blob: c948033a4cb56a0ef3fe435ea3f4cff361d179fc [file] [log] [blame]
Patrick Williamsb48b7b42016-08-17 15:04:38 -05001/*
2 * Copyright (C) 2005-2015 Junjiro R. Okajima
3 *
4 * This program, aufs is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef __AUFS_TYPE_H__
19#define __AUFS_TYPE_H__
20
21#define AUFS_NAME "aufs"
22
23#ifdef __KERNEL__
24/*
25 * define it before including all other headers.
26 * sched.h may use pr_* macros before defining "current", so define the
27 * no-current version first, and re-define later.
28 */
29#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
30#include <linux/sched.h>
31#undef pr_fmt
32#define pr_fmt(fmt) \
33 AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
34 (int)sizeof(current->comm), current->comm, current->pid
35#else
36#include <stdint.h>
37#include <sys/types.h>
38#endif /* __KERNEL__ */
39
40#include <linux/limits.h>
41
42#define AUFS_VERSION "3.18-20150406"
43
44/* todo? move this to linux-2.6.19/include/magic.h */
45#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
46
47/* ---------------------------------------------------------------------- */
48
49#ifdef CONFIG_AUFS_BRANCH_MAX_127
50typedef int8_t aufs_bindex_t;
51#define AUFS_BRANCH_MAX 127
52#else
53typedef int16_t aufs_bindex_t;
54#ifdef CONFIG_AUFS_BRANCH_MAX_511
55#define AUFS_BRANCH_MAX 511
56#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
57#define AUFS_BRANCH_MAX 1023
58#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
59#define AUFS_BRANCH_MAX 32767
60#endif
61#endif
62
63#ifdef __KERNEL__
64#ifndef AUFS_BRANCH_MAX
65#error unknown CONFIG_AUFS_BRANCH_MAX value
66#endif
67#endif /* __KERNEL__ */
68
69/* ---------------------------------------------------------------------- */
70
71#define AUFS_FSTYPE AUFS_NAME
72
73#define AUFS_ROOT_INO 2
74#define AUFS_FIRST_INO 11
75
76#define AUFS_WH_PFX ".wh."
77#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
78#define AUFS_WH_TMP_LEN 4
79/* a limit for rmdir/rename a dir and copyup */
80#define AUFS_MAX_NAMELEN (NAME_MAX \
81 - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
82 - 1 /* dot */\
83 - AUFS_WH_TMP_LEN) /* hex */
84#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
85#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
86#define AUFS_XINO_DEF_SEC 30 /* seconds */
87#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
88#define AUFS_DIRWH_DEF 3
89#define AUFS_RDCACHE_DEF 10 /* seconds */
90#define AUFS_RDCACHE_MAX 3600 /* seconds */
91#define AUFS_RDBLK_DEF 512 /* bytes */
92#define AUFS_RDHASH_DEF 32
93#define AUFS_WKQ_NAME AUFS_NAME "d"
94#define AUFS_MFS_DEF_SEC 30 /* seconds */
95#define AUFS_MFS_MAX_SEC 3600 /* seconds */
96#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
97#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
98
99/* pseudo-link maintenace under /proc */
100#define AUFS_PLINK_MAINT_NAME "plink_maint"
101#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
102#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
103
104#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
105#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
106
107#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
108#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
109#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
110
111/* doubly whiteouted */
112#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
113#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
114#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
115
116/* branch permissions and attributes */
117#define AUFS_BRPERM_RW "rw"
118#define AUFS_BRPERM_RO "ro"
119#define AUFS_BRPERM_RR "rr"
120#define AUFS_BRATTR_COO_REG "coo_reg"
121#define AUFS_BRATTR_COO_ALL "coo_all"
122#define AUFS_BRATTR_FHSM "fhsm"
123#define AUFS_BRATTR_UNPIN "unpin"
124#define AUFS_BRATTR_ICEX "icex"
125#define AUFS_BRATTR_ICEX_SEC "icexsec"
126#define AUFS_BRATTR_ICEX_SYS "icexsys"
127#define AUFS_BRATTR_ICEX_TR "icextr"
128#define AUFS_BRATTR_ICEX_USR "icexusr"
129#define AUFS_BRATTR_ICEX_OTH "icexoth"
130#define AUFS_BRRATTR_WH "wh"
131#define AUFS_BRWATTR_NLWH "nolwh"
132#define AUFS_BRWATTR_MOO "moo"
133
134#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
135#define AuBrPerm_RO (1 << 1) /* readonly */
136#define AuBrPerm_RR (1 << 2) /* natively readonly */
137#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
138
139#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
140#define AuBrAttr_COO_ALL (1 << 4)
141#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
142
143#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
144#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
145 branch. meaningless since
146 linux-3.18-rc1 */
147
148/* ignore error in copying XATTR */
149#define AuBrAttr_ICEX_SEC (1 << 7)
150#define AuBrAttr_ICEX_SYS (1 << 8)
151#define AuBrAttr_ICEX_TR (1 << 9)
152#define AuBrAttr_ICEX_USR (1 << 10)
153#define AuBrAttr_ICEX_OTH (1 << 11)
154#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
155 | AuBrAttr_ICEX_SYS \
156 | AuBrAttr_ICEX_TR \
157 | AuBrAttr_ICEX_USR \
158 | AuBrAttr_ICEX_OTH)
159
160#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
161#define AuBrRAttr_Mask AuBrRAttr_WH
162
163#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
164#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
165#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
166
167#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
168
169/* #warning test userspace */
170#ifdef __KERNEL__
171#ifndef CONFIG_AUFS_FHSM
172#undef AuBrAttr_FHSM
173#define AuBrAttr_FHSM 0
174#endif
175#ifndef CONFIG_AUFS_XATTR
176#undef AuBrAttr_ICEX
177#define AuBrAttr_ICEX 0
178#undef AuBrAttr_ICEX_SEC
179#define AuBrAttr_ICEX_SEC 0
180#undef AuBrAttr_ICEX_SYS
181#define AuBrAttr_ICEX_SYS 0
182#undef AuBrAttr_ICEX_TR
183#define AuBrAttr_ICEX_TR 0
184#undef AuBrAttr_ICEX_USR
185#define AuBrAttr_ICEX_USR 0
186#undef AuBrAttr_ICEX_OTH
187#define AuBrAttr_ICEX_OTH 0
188#endif
189#endif
190
191/* the longest combination */
192/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
193#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
194 "+" AUFS_BRATTR_COO_REG \
195 "+" AUFS_BRATTR_FHSM \
196 "+" AUFS_BRATTR_UNPIN \
197 "+" AUFS_BRATTR_ICEX_SEC \
198 "+" AUFS_BRATTR_ICEX_SYS \
199 "+" AUFS_BRATTR_ICEX_USR \
200 "+" AUFS_BRATTR_ICEX_OTH \
201 "+" AUFS_BRWATTR_NLWH)
202
203typedef struct {
204 char a[AuBrPermStrSz];
205} au_br_perm_str_t;
206
207static inline int au_br_writable(int brperm)
208{
209 return brperm & AuBrPerm_RW;
210}
211
212static inline int au_br_whable(int brperm)
213{
214 return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
215}
216
217static inline int au_br_wh_linkable(int brperm)
218{
219 return !(brperm & AuBrWAttr_NoLinkWH);
220}
221
222static inline int au_br_cmoo(int brperm)
223{
224 return brperm & AuBrAttr_CMOO_Mask;
225}
226
227static inline int au_br_fhsm(int brperm)
228{
229 return brperm & AuBrAttr_FHSM;
230}
231
232/* ---------------------------------------------------------------------- */
233
234/* ioctl */
235enum {
236 /* readdir in userspace */
237 AuCtl_RDU,
238 AuCtl_RDU_INO,
239
240 AuCtl_WBR_FD, /* pathconf wrapper */
241 AuCtl_IBUSY, /* busy inode */
242 AuCtl_MVDOWN, /* move-down */
243 AuCtl_BR, /* info about branches */
244 AuCtl_FHSM_FD /* connection for fhsm */
245};
246
247/* borrowed from linux/include/linux/kernel.h */
248#ifndef ALIGN
249#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
250#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
251#endif
252
253/* borrowed from linux/include/linux/compiler-gcc3.h */
254#ifndef __aligned
255#define __aligned(x) __attribute__((aligned(x)))
256#endif
257
258#ifdef __KERNEL__
259#ifndef __packed
260#define __packed __attribute__((packed))
261#endif
262#endif
263
264struct au_rdu_cookie {
265 uint64_t h_pos;
266 int16_t bindex;
267 uint8_t flags;
268 uint8_t pad;
269 uint32_t generation;
270} __aligned(8);
271
272struct au_rdu_ent {
273 uint64_t ino;
274 int16_t bindex;
275 uint8_t type;
276 uint8_t nlen;
277 uint8_t wh;
278 char name[0];
279} __aligned(8);
280
281static inline int au_rdu_len(int nlen)
282{
283 /* include the terminating NULL */
284 return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
285 sizeof(uint64_t));
286}
287
288union au_rdu_ent_ul {
289 struct au_rdu_ent *e;
290 uint64_t ul;
291};
292
293enum {
294 AufsCtlRduV_SZ,
295 AufsCtlRduV_End
296};
297
298struct aufs_rdu {
299 /* input */
300 union {
301 uint64_t sz; /* AuCtl_RDU */
302 uint64_t nent; /* AuCtl_RDU_INO */
303 };
304 union au_rdu_ent_ul ent;
305 uint16_t verify[AufsCtlRduV_End];
306
307 /* input/output */
308 uint32_t blk;
309
310 /* output */
311 union au_rdu_ent_ul tail;
312 /* number of entries which were added in a single call */
313 uint64_t rent;
314 uint8_t full;
315 uint8_t shwh;
316
317 struct au_rdu_cookie cookie;
318} __aligned(8);
319
320/* ---------------------------------------------------------------------- */
321
322struct aufs_wbr_fd {
323 uint32_t oflags;
324 int16_t brid;
325} __aligned(8);
326
327/* ---------------------------------------------------------------------- */
328
329struct aufs_ibusy {
330 uint64_t ino, h_ino;
331 int16_t bindex;
332} __aligned(8);
333
334/* ---------------------------------------------------------------------- */
335
336/* error code for move-down */
337/* the actual message strings are implemented in aufs-util.git */
338enum {
339 EAU_MVDOWN_OPAQUE = 1,
340 EAU_MVDOWN_WHITEOUT,
341 EAU_MVDOWN_UPPER,
342 EAU_MVDOWN_BOTTOM,
343 EAU_MVDOWN_NOUPPER,
344 EAU_MVDOWN_NOLOWERBR,
345 EAU_Last
346};
347
348/* flags for move-down */
349#define AUFS_MVDOWN_DMSG 1
350#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
351#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
352#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
353#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
354#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
355#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
356#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
357#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
358#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
359#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
360#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
361#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
362
363/* index for move-down */
364enum {
365 AUFS_MVDOWN_UPPER,
366 AUFS_MVDOWN_LOWER,
367 AUFS_MVDOWN_NARRAY
368};
369
370/*
371 * additional info of move-down
372 * number of free blocks and inodes.
373 * subset of struct kstatfs, but smaller and always 64bit.
374 */
375struct aufs_stfs {
376 uint64_t f_blocks;
377 uint64_t f_bavail;
378 uint64_t f_files;
379 uint64_t f_ffree;
380};
381
382struct aufs_stbr {
383 int16_t brid; /* optional input */
384 int16_t bindex; /* output */
385 struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
386} __aligned(8);
387
388struct aufs_mvdown {
389 uint32_t flags; /* input/output */
390 struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
391 int8_t au_errno; /* output */
392} __aligned(8);
393
394/* ---------------------------------------------------------------------- */
395
396union aufs_brinfo {
397 /* PATH_MAX may differ between kernel-space and user-space */
398 char _spacer[4096];
399 struct {
400 int16_t id;
401 int perm;
402 char path[0];
403 };
404} __aligned(8);
405
406/* ---------------------------------------------------------------------- */
407
408#define AuCtlType 'A'
409#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
410#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
411#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
412 struct aufs_wbr_fd)
413#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
414#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
415 struct aufs_mvdown)
416#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
417#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
418
419#endif /* __AUFS_TYPE_H__ */