2 * Copyright (C) 2005-2017 Junjiro R. Okajima
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.
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.
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/>.
22 #include <linux/namei.h>
23 #include <linux/types.h> /* a distribution requires */
24 #include <linux/parser.h>
27 /* ---------------------------------------------------------------------- */
31 Opt_add
, Opt_del
, Opt_mod
, Opt_append
, Opt_prepend
,
33 Opt_dirwh
, Opt_rdcache
, Opt_rdblk
, Opt_rdhash
,
34 Opt_rdblk_def
, Opt_rdhash_def
,
36 Opt_trunc_xino
, Opt_trunc_xino_v
, Opt_notrunc_xino
,
37 Opt_trunc_xino_path
, Opt_itrunc_xino
,
38 Opt_trunc_xib
, Opt_notrunc_xib
,
40 Opt_plink
, Opt_noplink
, Opt_list_plink
,
43 Opt_diropq_a
, Opt_diropq_w
,
44 Opt_warn_perm
, Opt_nowarn_perm
,
45 Opt_wbr_copyup
, Opt_wbr_create
,
47 Opt_verbose
, Opt_noverbose
,
48 Opt_sum
, Opt_nosum
, Opt_wsum
,
49 Opt_dirperm1
, Opt_nodirperm1
,
50 Opt_dirren
, Opt_nodirren
,
52 Opt_tail
, Opt_ignore
, Opt_ignore_silent
, Opt_err
55 static match_table_t options
= {
59 {Opt_add
, "add=%d:%s"},
60 {Opt_add
, "add:%d:%s"},
61 {Opt_add
, "ins=%d:%s"},
62 {Opt_add
, "ins:%d:%s"},
63 {Opt_append
, "append=%s"},
64 {Opt_append
, "append:%s"},
65 {Opt_prepend
, "prepend=%s"},
66 {Opt_prepend
, "prepend:%s"},
70 /* {Opt_idel, "idel:%d"}, */
73 /* {Opt_imod, "imod:%d:%s"}, */
75 {Opt_dirwh
, "dirwh=%d"},
77 {Opt_xino
, "xino=%s"},
78 {Opt_noxino
, "noxino"},
79 {Opt_trunc_xino
, "trunc_xino"},
80 {Opt_trunc_xino_v
, "trunc_xino_v=%d:%d"},
81 {Opt_notrunc_xino
, "notrunc_xino"},
82 {Opt_trunc_xino_path
, "trunc_xino=%s"},
83 {Opt_itrunc_xino
, "itrunc_xino=%d"},
84 /* {Opt_zxino, "zxino=%s"}, */
85 {Opt_trunc_xib
, "trunc_xib"},
86 {Opt_notrunc_xib
, "notrunc_xib"},
91 {Opt_ignore_silent
, "plink"},
94 {Opt_noplink
, "noplink"},
96 #ifdef CONFIG_AUFS_DEBUG
97 {Opt_list_plink
, "list_plink"},
100 {Opt_udba
, "udba=%s"},
103 {Opt_nodio
, "nodio"},
105 #ifdef CONFIG_AUFS_DIRREN
106 {Opt_dirren
, "dirren"},
107 {Opt_nodirren
, "nodirren"},
109 {Opt_ignore
, "dirren"},
110 {Opt_ignore_silent
, "nodirren"},
113 #ifdef CONFIG_AUFS_FHSM
114 {Opt_fhsm_sec
, "fhsm_sec=%d"},
116 {Opt_ignore
, "fhsm_sec=%d"},
119 {Opt_diropq_a
, "diropq=always"},
120 {Opt_diropq_a
, "diropq=a"},
121 {Opt_diropq_w
, "diropq=whiteouted"},
122 {Opt_diropq_w
, "diropq=w"},
124 {Opt_warn_perm
, "warn_perm"},
125 {Opt_nowarn_perm
, "nowarn_perm"},
127 /* keep them temporary */
128 {Opt_ignore_silent
, "nodlgt"},
129 {Opt_ignore
, "clean_plink"},
131 #ifdef CONFIG_AUFS_SHWH
134 {Opt_noshwh
, "noshwh"},
136 {Opt_dirperm1
, "dirperm1"},
137 {Opt_nodirperm1
, "nodirperm1"},
139 {Opt_verbose
, "verbose"},
141 {Opt_noverbose
, "noverbose"},
142 {Opt_noverbose
, "quiet"},
143 {Opt_noverbose
, "q"},
144 {Opt_noverbose
, "silent"},
147 {Opt_nosum
, "nosum"},
150 {Opt_rdcache
, "rdcache=%d"},
151 {Opt_rdblk
, "rdblk=%d"},
152 {Opt_rdblk_def
, "rdblk=def"},
153 {Opt_rdhash
, "rdhash=%d"},
154 {Opt_rdhash_def
, "rdhash=def"},
156 {Opt_wbr_create
, "create=%s"},
157 {Opt_wbr_create
, "create_policy=%s"},
158 {Opt_wbr_copyup
, "cpup=%s"},
159 {Opt_wbr_copyup
, "copyup=%s"},
160 {Opt_wbr_copyup
, "copyup_policy=%s"},
162 /* generic VFS flag */
163 #ifdef CONFIG_FS_POSIX_ACL
165 {Opt_noacl
, "noacl"},
168 {Opt_ignore_silent
, "noacl"},
171 /* internal use for the scripts */
172 {Opt_ignore_silent
, "si=%s"},
175 {Opt_ignore
, "debug=%d"},
176 {Opt_ignore
, "delete=whiteout"},
177 {Opt_ignore
, "delete=all"},
178 {Opt_ignore
, "imap=%s"},
180 /* temporary workaround, due to old mount(8)? */
181 {Opt_ignore_silent
, "relatime"},
186 /* ---------------------------------------------------------------------- */
188 static const char *au_parser_pattern(int val
, match_table_t tbl
)
190 struct match_token
*p
;
202 static const char *au_optstr(int *val
, match_table_t tbl
)
204 struct match_token
*p
;
213 && (v
& p
->token
) == p
->token
) {
224 /* ---------------------------------------------------------------------- */
226 static match_table_t brperm
= {
227 {AuBrPerm_RO
, AUFS_BRPERM_RO
},
228 {AuBrPerm_RR
, AUFS_BRPERM_RR
},
229 {AuBrPerm_RW
, AUFS_BRPERM_RW
},
233 static match_table_t brattr
= {
235 {AuBrAttr_COO_REG
, AUFS_BRATTR_COO_REG
},
236 {AuBrAttr_COO_ALL
, AUFS_BRATTR_COO_ALL
},
237 /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
238 {AuBrAttr_UNPIN
, AUFS_BRATTR_UNPIN
},
239 #ifdef CONFIG_AUFS_FHSM
240 {AuBrAttr_FHSM
, AUFS_BRATTR_FHSM
},
242 #ifdef CONFIG_AUFS_XATTR
243 {AuBrAttr_ICEX
, AUFS_BRATTR_ICEX
},
244 {AuBrAttr_ICEX_SEC
, AUFS_BRATTR_ICEX_SEC
},
245 {AuBrAttr_ICEX_SYS
, AUFS_BRATTR_ICEX_SYS
},
246 {AuBrAttr_ICEX_TR
, AUFS_BRATTR_ICEX_TR
},
247 {AuBrAttr_ICEX_USR
, AUFS_BRATTR_ICEX_USR
},
248 {AuBrAttr_ICEX_OTH
, AUFS_BRATTR_ICEX_OTH
},
252 {AuBrRAttr_WH
, AUFS_BRRATTR_WH
},
255 {AuBrWAttr_MOO
, AUFS_BRWATTR_MOO
},
256 {AuBrWAttr_NoLinkWH
, AUFS_BRWATTR_NLWH
},
261 static int br_attr_val(char *str
, match_table_t table
, substring_t args
[])
268 p
= strchr(str
, '+');
271 v
= match_token(str
, table
, args
);
273 if (v
& AuBrAttr_CMOO_Mask
)
274 attr
&= ~AuBrAttr_CMOO_Mask
;
279 pr_warn("ignored branch attribute %s\n", str
);
289 static int au_do_optstr_br_attr(au_br_perm_str_t
*str
, int perm
)
297 p
= au_optstr(&perm
, brattr
);
300 memcpy(q
, p
, sz
+ 1);
306 p
= au_optstr(&perm
, brattr
);
310 memcpy(q
, p
, sz
+ 1);
319 static int noinline_for_stack
br_perm_val(char *perm
)
323 substring_t args
[MAX_OPT_ARGS
];
324 au_br_perm_str_t attr
;
326 p
= strchr(perm
, '+');
329 val
= match_token(perm
, brperm
, args
);
333 pr_warn("ignored branch permission %s\n", perm
);
340 val
|= br_attr_val(p
+ 1, brattr
, args
);
343 switch (val
& AuBrPerm_Mask
) {
346 bad
= val
& AuBrWAttr_Mask
;
347 val
&= ~AuBrWAttr_Mask
;
350 bad
= val
& AuBrRAttr_Mask
;
351 val
&= ~AuBrRAttr_Mask
;
356 * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
357 * does not treat it as an error, just warning.
358 * this is a tiny guard for the user operation.
360 if (val
& AuBrAttr_UNPIN
) {
361 bad
|= AuBrAttr_UNPIN
;
362 val
&= ~AuBrAttr_UNPIN
;
366 sz
= au_do_optstr_br_attr(&attr
, bad
);
368 pr_warn("ignored branch attribute %s\n", attr
.a
);
375 void au_optstr_br_perm(au_br_perm_str_t
*str
, int perm
)
377 au_br_perm_str_t attr
;
383 p
= au_optstr(&perm
, brperm
);
384 AuDebugOn(!p
|| !*p
);
386 memcpy(q
, p
, sz
+ 1);
389 sz
= au_do_optstr_br_attr(&attr
, perm
);
392 memcpy(q
, attr
.a
, sz
+ 1);
395 AuDebugOn(strlen(str
->a
) >= sizeof(str
->a
));
398 /* ---------------------------------------------------------------------- */
400 static match_table_t udbalevel
= {
401 {AuOpt_UDBA_REVAL
, "reval"},
402 {AuOpt_UDBA_NONE
, "none"},
403 #ifdef CONFIG_AUFS_HNOTIFY
404 {AuOpt_UDBA_HNOTIFY
, "notify"}, /* abstraction */
405 #ifdef CONFIG_AUFS_HFSNOTIFY
406 {AuOpt_UDBA_HNOTIFY
, "fsnotify"},
412 static int noinline_for_stack
udba_val(char *str
)
414 substring_t args
[MAX_OPT_ARGS
];
416 return match_token(str
, udbalevel
, args
);
419 const char *au_optstr_udba(int udba
)
421 return au_parser_pattern(udba
, udbalevel
);
424 /* ---------------------------------------------------------------------- */
426 static match_table_t au_wbr_create_policy
= {
427 {AuWbrCreate_TDP
, "tdp"},
428 {AuWbrCreate_TDP
, "top-down-parent"},
429 {AuWbrCreate_RR
, "rr"},
430 {AuWbrCreate_RR
, "round-robin"},
431 {AuWbrCreate_MFS
, "mfs"},
432 {AuWbrCreate_MFS
, "most-free-space"},
433 {AuWbrCreate_MFSV
, "mfs:%d"},
434 {AuWbrCreate_MFSV
, "most-free-space:%d"},
436 /* top-down regardless the parent, and then mfs */
437 {AuWbrCreate_TDMFS
, "tdmfs:%d"},
438 {AuWbrCreate_TDMFSV
, "tdmfs:%d:%d"},
440 {AuWbrCreate_MFSRR
, "mfsrr:%d"},
441 {AuWbrCreate_MFSRRV
, "mfsrr:%d:%d"},
442 {AuWbrCreate_PMFS
, "pmfs"},
443 {AuWbrCreate_PMFSV
, "pmfs:%d"},
444 {AuWbrCreate_PMFSRR
, "pmfsrr:%d"},
445 {AuWbrCreate_PMFSRRV
, "pmfsrr:%d:%d"},
450 static int au_wbr_mfs_wmark(substring_t
*arg
, char *str
,
451 struct au_opt_wbr_create
*create
)
454 unsigned long long ull
;
457 if (!match_u64(arg
, &ull
))
458 create
->mfsrr_watermark
= ull
;
460 pr_err("bad integer in %s\n", str
);
467 static int au_wbr_mfs_sec(substring_t
*arg
, char *str
,
468 struct au_opt_wbr_create
*create
)
473 if (!match_int(arg
, &n
) && 0 <= n
&& n
<= AUFS_MFS_MAX_SEC
)
474 create
->mfs_second
= n
;
476 pr_err("bad integer in %s\n", str
);
483 static int noinline_for_stack
484 au_wbr_create_val(char *str
, struct au_opt_wbr_create
*create
)
487 substring_t args
[MAX_OPT_ARGS
];
489 err
= match_token(str
, au_wbr_create_policy
, args
);
490 create
->wbr_create
= err
;
492 case AuWbrCreate_MFSRRV
:
493 case AuWbrCreate_TDMFSV
:
494 case AuWbrCreate_PMFSRRV
:
495 e
= au_wbr_mfs_wmark(&args
[0], str
, create
);
497 e
= au_wbr_mfs_sec(&args
[1], str
, create
);
501 case AuWbrCreate_MFSRR
:
502 case AuWbrCreate_TDMFS
:
503 case AuWbrCreate_PMFSRR
:
504 e
= au_wbr_mfs_wmark(&args
[0], str
, create
);
510 case AuWbrCreate_MFS
:
511 case AuWbrCreate_PMFS
:
512 create
->mfs_second
= AUFS_MFS_DEF_SEC
;
514 case AuWbrCreate_MFSV
:
515 case AuWbrCreate_PMFSV
:
516 e
= au_wbr_mfs_sec(&args
[0], str
, create
);
525 const char *au_optstr_wbr_create(int wbr_create
)
527 return au_parser_pattern(wbr_create
, au_wbr_create_policy
);
530 static match_table_t au_wbr_copyup_policy
= {
531 {AuWbrCopyup_TDP
, "tdp"},
532 {AuWbrCopyup_TDP
, "top-down-parent"},
533 {AuWbrCopyup_BUP
, "bup"},
534 {AuWbrCopyup_BUP
, "bottom-up-parent"},
535 {AuWbrCopyup_BU
, "bu"},
536 {AuWbrCopyup_BU
, "bottom-up"},
540 static int noinline_for_stack
au_wbr_copyup_val(char *str
)
542 substring_t args
[MAX_OPT_ARGS
];
544 return match_token(str
, au_wbr_copyup_policy
, args
);
547 const char *au_optstr_wbr_copyup(int wbr_copyup
)
549 return au_parser_pattern(wbr_copyup
, au_wbr_copyup_policy
);
552 /* ---------------------------------------------------------------------- */
554 static const int lkup_dirflags
= LOOKUP_FOLLOW
| LOOKUP_DIRECTORY
;
556 static void dump_opts(struct au_opts
*opts
)
558 #ifdef CONFIG_AUFS_DEBUG
559 /* reduce stack space */
561 struct au_opt_add
*add
;
562 struct au_opt_del
*del
;
563 struct au_opt_mod
*mod
;
564 struct au_opt_xino
*xino
;
565 struct au_opt_xino_itrunc
*xino_itrunc
;
566 struct au_opt_wbr_create
*create
;
571 while (opt
->type
!= Opt_tail
) {
575 AuDbg("add {b%d, %s, 0x%x, %p}\n",
576 u
.add
->bindex
, u
.add
->pathname
, u
.add
->perm
,
582 AuDbg("del {%s, %p}\n",
583 u
.del
->pathname
, u
.del
->h_path
.dentry
);
588 AuDbg("mod {%s, 0x%x, %p}\n",
589 u
.mod
->path
, u
.mod
->perm
, u
.mod
->h_root
);
593 AuDbg("append {b%d, %s, 0x%x, %p}\n",
594 u
.add
->bindex
, u
.add
->pathname
, u
.add
->perm
,
599 AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
600 u
.add
->bindex
, u
.add
->pathname
, u
.add
->perm
,
604 AuDbg("dirwh %d\n", opt
->dirwh
);
607 AuDbg("rdcache %d\n", opt
->rdcache
);
610 AuDbg("rdblk %u\n", opt
->rdblk
);
613 AuDbg("rdblk_def\n");
616 AuDbg("rdhash %u\n", opt
->rdhash
);
619 AuDbg("rdhash_def\n");
623 AuDbg("xino {%s %pD}\n", u
.xino
->path
, u
.xino
->file
);
628 case Opt_notrunc_xino
:
629 AuLabel(notrunc_xino
);
631 case Opt_trunc_xino_path
:
632 case Opt_itrunc_xino
:
633 u
.xino_itrunc
= &opt
->xino_itrunc
;
634 AuDbg("trunc_xino %d\n", u
.xino_itrunc
->bindex
);
642 case Opt_notrunc_xib
:
643 AuLabel(notrunc_xib
);
667 AuDbg("udba %d, %s\n",
668 opt
->udba
, au_optstr_udba(opt
->udba
));
685 case Opt_nowarn_perm
:
686 AuLabel(nowarn_perm
);
704 u
.create
= &opt
->wbr_create
;
705 AuDbg("create %d, %s\n", u
.create
->wbr_create
,
706 au_optstr_wbr_create(u
.create
->wbr_create
));
707 switch (u
.create
->wbr_create
) {
708 case AuWbrCreate_MFSV
:
709 case AuWbrCreate_PMFSV
:
710 AuDbg("%d sec\n", u
.create
->mfs_second
);
712 case AuWbrCreate_MFSRR
:
713 case AuWbrCreate_TDMFS
:
714 AuDbg("%llu watermark\n",
715 u
.create
->mfsrr_watermark
);
717 case AuWbrCreate_MFSRRV
:
718 case AuWbrCreate_TDMFSV
:
719 case AuWbrCreate_PMFSRRV
:
720 AuDbg("%llu watermark, %d sec\n",
721 u
.create
->mfsrr_watermark
,
722 u
.create
->mfs_second
);
727 AuDbg("copyup %d, %s\n", opt
->wbr_copyup
,
728 au_optstr_wbr_copyup(opt
->wbr_copyup
));
731 AuDbg("fhsm_sec %u\n", opt
->fhsm_second
);
753 void au_opts_free(struct au_opts
*opts
)
758 while (opt
->type
!= Opt_tail
) {
763 path_put(&opt
->add
.path
);
767 path_put(&opt
->del
.h_path
);
771 dput(opt
->mod
.h_root
);
774 fput(opt
->xino
.file
);
781 static int opt_add(struct au_opt
*opt
, char *opt_str
, unsigned long sb_flags
,
782 aufs_bindex_t bindex
)
785 struct au_opt_add
*add
= &opt
->add
;
788 add
->bindex
= bindex
;
789 add
->perm
= AuBrPerm_RO
;
790 add
->pathname
= opt_str
;
791 p
= strchr(opt_str
, '=');
795 add
->perm
= br_perm_val(p
);
798 err
= vfsub_kern_path(add
->pathname
, lkup_dirflags
, &add
->path
);
801 add
->perm
= AuBrPerm_RO
;
802 if (au_test_fs_rr(add
->path
.dentry
->d_sb
))
803 add
->perm
= AuBrPerm_RR
;
804 else if (!bindex
&& !(sb_flags
& SB_RDONLY
))
805 add
->perm
= AuBrPerm_RW
;
810 pr_err("lookup failed %s (%d)\n", add
->pathname
, err
);
817 static int au_opts_parse_del(struct au_opt_del
*del
, substring_t args
[])
821 del
->pathname
= args
[0].from
;
822 AuDbg("del path %s\n", del
->pathname
);
824 err
= vfsub_kern_path(del
->pathname
, lkup_dirflags
, &del
->h_path
);
826 pr_err("lookup failed %s (%d)\n", del
->pathname
, err
);
831 #if 0 /* reserved for future use */
832 static int au_opts_parse_idel(struct super_block
*sb
, aufs_bindex_t bindex
,
833 struct au_opt_del
*del
, substring_t args
[])
840 aufs_read_lock(root
, AuLock_FLUSH
);
841 if (bindex
< 0 || au_sbbot(sb
) < bindex
) {
842 pr_err("out of bounds, %d\n", bindex
);
847 del
->h_path
.dentry
= dget(au_h_dptr(root
, bindex
));
848 del
->h_path
.mnt
= mntget(au_sbr_mnt(sb
, bindex
));
851 aufs_read_unlock(root
, !AuLock_IR
);
856 static int noinline_for_stack
857 au_opts_parse_mod(struct au_opt_mod
*mod
, substring_t args
[])
864 mod
->path
= args
[0].from
;
865 p
= strchr(mod
->path
, '=');
867 pr_err("no permssion %s\n", args
[0].from
);
872 err
= vfsub_kern_path(mod
->path
, lkup_dirflags
, &path
);
874 pr_err("lookup failed %s (%d)\n", mod
->path
, err
);
878 mod
->perm
= br_perm_val(p
);
879 AuDbg("mod path %s, perm 0x%x, %s\n", mod
->path
, mod
->perm
, p
);
880 mod
->h_root
= dget(path
.dentry
);
887 #if 0 /* reserved for future use */
888 static int au_opts_parse_imod(struct super_block
*sb
, aufs_bindex_t bindex
,
889 struct au_opt_mod
*mod
, substring_t args
[])
896 aufs_read_lock(root
, AuLock_FLUSH
);
897 if (bindex
< 0 || au_sbbot(sb
) < bindex
) {
898 pr_err("out of bounds, %d\n", bindex
);
903 mod
->perm
= br_perm_val(args
[1].from
);
904 AuDbg("mod path %s, perm 0x%x, %s\n",
905 mod
->path
, mod
->perm
, args
[1].from
);
906 mod
->h_root
= dget(au_h_dptr(root
, bindex
));
909 aufs_read_unlock(root
, !AuLock_IR
);
914 static int au_opts_parse_xino(struct super_block
*sb
, struct au_opt_xino
*xino
,
920 file
= au_xino_create(sb
, args
[0].from
, /*silent*/0);
926 if (unlikely(file
->f_path
.dentry
->d_sb
== sb
)) {
928 pr_err("%s must be outside\n", args
[0].from
);
934 xino
->path
= args
[0].from
;
940 static int noinline_for_stack
941 au_opts_parse_xino_itrunc_path(struct super_block
*sb
,
942 struct au_opt_xino_itrunc
*xino_itrunc
,
946 aufs_bindex_t bbot
, bindex
;
950 err
= vfsub_kern_path(args
[0].from
, lkup_dirflags
, &path
);
952 pr_err("lookup failed %s (%d)\n", args
[0].from
, err
);
956 xino_itrunc
->bindex
= -1;
958 aufs_read_lock(root
, AuLock_FLUSH
);
960 for (bindex
= 0; bindex
<= bbot
; bindex
++) {
961 if (au_h_dptr(root
, bindex
) == path
.dentry
) {
962 xino_itrunc
->bindex
= bindex
;
966 aufs_read_unlock(root
, !AuLock_IR
);
969 if (unlikely(xino_itrunc
->bindex
< 0)) {
970 pr_err("no such branch %s\n", args
[0].from
);
978 /* called without aufs lock */
979 int au_opts_parse(struct super_block
*sb
, char *str
, struct au_opts
*opts
)
982 aufs_bindex_t bindex
;
983 unsigned char skipped
;
985 struct au_opt
*opt
, *opt_tail
;
987 /* reduce the stack space */
989 struct au_opt_xino_itrunc
*xino_itrunc
;
990 struct au_opt_wbr_create
*create
;
993 substring_t args
[MAX_OPT_ARGS
];
997 a
= kmalloc(sizeof(*a
), GFP_NOFS
);
1005 opt_tail
= opt
+ opts
->max_opt
- 1;
1006 opt
->type
= Opt_tail
;
1007 while (!err
&& (opt_str
= strsep(&str
, ",")) && *opt_str
) {
1010 token
= match_token(opt_str
, options
, a
->args
);
1014 while (!err
&& (opt_str
= strsep(&a
->args
[0].from
, ":"))
1016 err
= opt_add(opt
, opt_str
, opts
->sb_flags
,
1018 if (unlikely(!err
&& ++opt
> opt_tail
)) {
1022 opt
->type
= Opt_tail
;
1027 if (unlikely(match_int(&a
->args
[0], &n
))) {
1028 pr_err("bad integer in %s\n", opt_str
);
1032 err
= opt_add(opt
, a
->args
[1].from
, opts
->sb_flags
,
1038 err
= opt_add(opt
, a
->args
[0].from
, opts
->sb_flags
,
1044 err
= opt_add(opt
, a
->args
[0].from
, opts
->sb_flags
,
1050 err
= au_opts_parse_del(&opt
->del
, a
->args
);
1054 #if 0 /* reserved for future use */
1056 del
->pathname
= "(indexed)";
1057 if (unlikely(match_int(&args
[0], &n
))) {
1058 pr_err("bad integer in %s\n", opt_str
);
1061 err
= au_opts_parse_idel(sb
, n
, &opt
->del
, a
->args
);
1067 err
= au_opts_parse_mod(&opt
->mod
, a
->args
);
1071 #ifdef IMOD /* reserved for future use */
1073 u
.mod
->path
= "(indexed)";
1074 if (unlikely(match_int(&a
->args
[0], &n
))) {
1075 pr_err("bad integer in %s\n", opt_str
);
1078 err
= au_opts_parse_imod(sb
, n
, &opt
->mod
, a
->args
);
1084 err
= au_opts_parse_xino(sb
, &opt
->xino
, a
->args
);
1089 case Opt_trunc_xino_path
:
1090 err
= au_opts_parse_xino_itrunc_path
1091 (sb
, &opt
->xino_itrunc
, a
->args
);
1096 case Opt_itrunc_xino
:
1097 u
.xino_itrunc
= &opt
->xino_itrunc
;
1098 if (unlikely(match_int(&a
->args
[0], &n
))) {
1099 pr_err("bad integer in %s\n", opt_str
);
1102 u
.xino_itrunc
->bindex
= n
;
1103 aufs_read_lock(root
, AuLock_FLUSH
);
1104 if (n
< 0 || au_sbbot(sb
) < n
) {
1105 pr_err("out of bounds, %d\n", n
);
1106 aufs_read_unlock(root
, !AuLock_IR
);
1109 aufs_read_unlock(root
, !AuLock_IR
);
1115 if (unlikely(match_int(&a
->args
[0], &opt
->dirwh
)))
1122 if (unlikely(match_int(&a
->args
[0], &n
))) {
1123 pr_err("bad integer in %s\n", opt_str
);
1126 if (unlikely(n
> AUFS_RDCACHE_MAX
)) {
1127 pr_err("rdcache must be smaller than %d\n",
1136 if (unlikely(match_int(&a
->args
[0], &n
)
1138 || n
> KMALLOC_MAX_SIZE
)) {
1139 pr_err("bad integer in %s\n", opt_str
);
1142 if (unlikely(n
&& n
< NAME_MAX
)) {
1143 pr_err("rdblk must be larger than %d\n",
1152 if (unlikely(match_int(&a
->args
[0], &n
)
1154 || n
* sizeof(struct hlist_head
)
1155 > KMALLOC_MAX_SIZE
)) {
1156 pr_err("bad integer in %s\n", opt_str
);
1164 case Opt_trunc_xino
:
1165 case Opt_notrunc_xino
:
1168 case Opt_notrunc_xib
:
1172 case Opt_nodirperm1
:
1175 case Opt_list_plink
:
1181 case Opt_nowarn_perm
:
1188 case Opt_rdhash_def
:
1198 opt
->udba
= udba_val(a
->args
[0].from
);
1199 if (opt
->udba
>= 0) {
1203 pr_err("wrong value, %s\n", opt_str
);
1206 case Opt_wbr_create
:
1207 u
.create
= &opt
->wbr_create
;
1208 u
.create
->wbr_create
1209 = au_wbr_create_val(a
->args
[0].from
, u
.create
);
1210 if (u
.create
->wbr_create
>= 0) {
1214 pr_err("wrong value, %s\n", opt_str
);
1216 case Opt_wbr_copyup
:
1217 opt
->wbr_copyup
= au_wbr_copyup_val(a
->args
[0].from
);
1218 if (opt
->wbr_copyup
>= 0) {
1222 pr_err("wrong value, %s\n", opt_str
);
1226 if (unlikely(match_int(&a
->args
[0], &n
)
1228 pr_err("bad integer in %s\n", opt_str
);
1232 opt
->fhsm_second
= n
;
1235 pr_warn("ignored %s\n", opt_str
);
1240 pr_warn("ignored %s\n", opt_str
);
1242 case Opt_ignore_silent
:
1247 pr_err("unknown option %s\n", opt_str
);
1251 if (!err
&& !skipped
) {
1252 if (unlikely(++opt
> opt_tail
)) {
1255 opt
->type
= Opt_tail
;
1258 opt
->type
= Opt_tail
;
1271 static int au_opt_wbr_create(struct super_block
*sb
,
1272 struct au_opt_wbr_create
*create
)
1275 struct au_sbinfo
*sbinfo
;
1277 SiMustWriteLock(sb
);
1279 err
= 1; /* handled */
1280 sbinfo
= au_sbi(sb
);
1281 if (sbinfo
->si_wbr_create_ops
->fin
) {
1282 err
= sbinfo
->si_wbr_create_ops
->fin(sb
);
1287 sbinfo
->si_wbr_create
= create
->wbr_create
;
1288 sbinfo
->si_wbr_create_ops
= au_wbr_create_ops
+ create
->wbr_create
;
1289 switch (create
->wbr_create
) {
1290 case AuWbrCreate_MFSRRV
:
1291 case AuWbrCreate_MFSRR
:
1292 case AuWbrCreate_TDMFS
:
1293 case AuWbrCreate_TDMFSV
:
1294 case AuWbrCreate_PMFSRR
:
1295 case AuWbrCreate_PMFSRRV
:
1296 sbinfo
->si_wbr_mfs
.mfsrr_watermark
= create
->mfsrr_watermark
;
1298 case AuWbrCreate_MFS
:
1299 case AuWbrCreate_MFSV
:
1300 case AuWbrCreate_PMFS
:
1301 case AuWbrCreate_PMFSV
:
1302 sbinfo
->si_wbr_mfs
.mfs_expire
1303 = msecs_to_jiffies(create
->mfs_second
* MSEC_PER_SEC
);
1307 if (sbinfo
->si_wbr_create_ops
->init
)
1308 sbinfo
->si_wbr_create_ops
->init(sb
); /* ignore */
1315 * plus: processed without an error
1318 static int au_opt_simple(struct super_block
*sb
, struct au_opt
*opt
,
1319 struct au_opts
*opts
)
1322 struct au_sbinfo
*sbinfo
;
1324 SiMustWriteLock(sb
);
1326 err
= 1; /* handled */
1327 sbinfo
= au_sbi(sb
);
1328 switch (opt
->type
) {
1330 sbinfo
->si_mntflags
&= ~AuOptMask_UDBA
;
1331 sbinfo
->si_mntflags
|= opt
->udba
;
1332 opts
->given_udba
|= opt
->udba
;
1336 au_opt_set(sbinfo
->si_mntflags
, PLINK
);
1339 if (au_opt_test(sbinfo
->si_mntflags
, PLINK
))
1340 au_plink_put(sb
, /*verbose*/1);
1341 au_opt_clr(sbinfo
->si_mntflags
, PLINK
);
1343 case Opt_list_plink
:
1344 if (au_opt_test(sbinfo
->si_mntflags
, PLINK
))
1349 au_opt_set(sbinfo
->si_mntflags
, DIO
);
1350 au_fset_opts(opts
->flags
, REFRESH_DYAOP
);
1353 au_opt_clr(sbinfo
->si_mntflags
, DIO
);
1354 au_fset_opts(opts
->flags
, REFRESH_DYAOP
);
1358 au_fhsm_set(sbinfo
, opt
->fhsm_second
);
1362 au_opt_set(sbinfo
->si_mntflags
, ALWAYS_DIROPQ
);
1365 au_opt_clr(sbinfo
->si_mntflags
, ALWAYS_DIROPQ
);
1369 au_opt_set(sbinfo
->si_mntflags
, WARN_PERM
);
1371 case Opt_nowarn_perm
:
1372 au_opt_clr(sbinfo
->si_mntflags
, WARN_PERM
);
1376 au_opt_set(sbinfo
->si_mntflags
, VERBOSE
);
1379 au_opt_clr(sbinfo
->si_mntflags
, VERBOSE
);
1383 au_opt_set(sbinfo
->si_mntflags
, SUM
);
1386 au_opt_clr(sbinfo
->si_mntflags
, SUM
);
1387 au_opt_set(sbinfo
->si_mntflags
, SUM_W
);
1389 au_opt_clr(sbinfo
->si_mntflags
, SUM
);
1390 au_opt_clr(sbinfo
->si_mntflags
, SUM_W
);
1393 case Opt_wbr_create
:
1394 err
= au_opt_wbr_create(sb
, &opt
->wbr_create
);
1396 case Opt_wbr_copyup
:
1397 sbinfo
->si_wbr_copyup
= opt
->wbr_copyup
;
1398 sbinfo
->si_wbr_copyup_ops
= au_wbr_copyup_ops
+ opt
->wbr_copyup
;
1402 sbinfo
->si_dirwh
= opt
->dirwh
;
1407 = msecs_to_jiffies(opt
->rdcache
* MSEC_PER_SEC
);
1410 sbinfo
->si_rdblk
= opt
->rdblk
;
1413 sbinfo
->si_rdblk
= AUFS_RDBLK_DEF
;
1416 sbinfo
->si_rdhash
= opt
->rdhash
;
1418 case Opt_rdhash_def
:
1419 sbinfo
->si_rdhash
= AUFS_RDHASH_DEF
;
1423 au_opt_set(sbinfo
->si_mntflags
, SHWH
);
1426 au_opt_clr(sbinfo
->si_mntflags
, SHWH
);
1430 au_opt_set(sbinfo
->si_mntflags
, DIRPERM1
);
1432 case Opt_nodirperm1
:
1433 au_opt_clr(sbinfo
->si_mntflags
, DIRPERM1
);
1436 case Opt_trunc_xino
:
1437 au_opt_set(sbinfo
->si_mntflags
, TRUNC_XINO
);
1439 case Opt_notrunc_xino
:
1440 au_opt_clr(sbinfo
->si_mntflags
, TRUNC_XINO
);
1443 case Opt_trunc_xino_path
:
1444 case Opt_itrunc_xino
:
1445 err
= au_xino_trunc(sb
, opt
->xino_itrunc
.bindex
);
1451 au_fset_opts(opts
->flags
, TRUNC_XIB
);
1453 case Opt_notrunc_xib
:
1454 au_fclr_opts(opts
->flags
, TRUNC_XIB
);
1459 if (!au_opt_test(sbinfo
->si_mntflags
, DIRREN
)) {
1460 err
= au_dr_opt_set(sb
);
1465 au_opt_set(sbinfo
->si_mntflags
, DIRREN
);
1469 if (au_opt_test(sbinfo
->si_mntflags
, DIRREN
)) {
1470 err
= au_dr_opt_clr(sb
, au_ftest_opts(opts
->flags
,
1476 au_opt_clr(sbinfo
->si_mntflags
, DIRREN
);
1480 sb
->s_flags
|= SB_POSIXACL
;
1483 sb
->s_flags
&= ~SB_POSIXACL
;
1495 * returns tri-state.
1496 * plus: processed without an error
1500 static int au_opt_br(struct super_block
*sb
, struct au_opt
*opt
,
1501 struct au_opts
*opts
)
1503 int err
, do_refresh
;
1506 switch (opt
->type
) {
1508 opt
->add
.bindex
= au_sbbot(sb
) + 1;
1509 if (opt
->add
.bindex
< 0)
1510 opt
->add
.bindex
= 0;
1513 opt
->add
.bindex
= 0;
1514 add
: /* indented label */
1516 err
= au_br_add(sb
, &opt
->add
,
1517 au_ftest_opts(opts
->flags
, REMOUNT
));
1520 au_fset_opts(opts
->flags
, REFRESH
);
1526 err
= au_br_del(sb
, &opt
->del
,
1527 au_ftest_opts(opts
->flags
, REMOUNT
));
1530 au_fset_opts(opts
->flags
, TRUNC_XIB
);
1531 au_fset_opts(opts
->flags
, REFRESH
);
1537 err
= au_br_mod(sb
, &opt
->mod
,
1538 au_ftest_opts(opts
->flags
, REMOUNT
),
1543 au_fset_opts(opts
->flags
, REFRESH
);
1550 static int au_opt_xino(struct super_block
*sb
, struct au_opt
*opt
,
1551 struct au_opt_xino
**opt_xino
,
1552 struct au_opts
*opts
)
1555 aufs_bindex_t bbot
, bindex
;
1556 struct dentry
*root
, *parent
, *h_root
;
1559 switch (opt
->type
) {
1561 err
= au_xino_set(sb
, &opt
->xino
,
1562 !!au_ftest_opts(opts
->flags
, REMOUNT
));
1566 *opt_xino
= &opt
->xino
;
1567 au_xino_brid_set(sb
, -1);
1569 /* safe d_parent access */
1570 parent
= opt
->xino
.file
->f_path
.dentry
->d_parent
;
1572 bbot
= au_sbbot(sb
);
1573 for (bindex
= 0; bindex
<= bbot
; bindex
++) {
1574 h_root
= au_h_dptr(root
, bindex
);
1575 if (h_root
== parent
) {
1576 au_xino_brid_set(sb
, au_sbr_id(sb
, bindex
));
1584 au_xino_brid_set(sb
, -1);
1585 *opt_xino
= (void *)-1;
1592 int au_opts_verify(struct super_block
*sb
, unsigned long sb_flags
,
1593 unsigned int pending
)
1596 aufs_bindex_t bindex
, bbot
;
1597 unsigned char do_plink
, skip
, do_free
, can_no_dreval
;
1598 struct au_branch
*br
;
1600 struct dentry
*root
, *dentry
;
1601 struct inode
*dir
, *h_dir
;
1602 struct au_sbinfo
*sbinfo
;
1603 struct au_hinode
*hdir
;
1607 sbinfo
= au_sbi(sb
);
1608 AuDebugOn(!(sbinfo
->si_mntflags
& AuOptMask_UDBA
));
1610 if (!(sb_flags
& SB_RDONLY
)) {
1611 if (unlikely(!au_br_writable(au_sbr_perm(sb
, 0))))
1612 pr_warn("first branch should be rw\n");
1613 if (unlikely(au_opt_test(sbinfo
->si_mntflags
, SHWH
)))
1614 pr_warn_once("shwh should be used with ro\n");
1617 if (au_opt_test((sbinfo
->si_mntflags
| pending
), UDBA_HNOTIFY
)
1618 && !au_opt_test(sbinfo
->si_mntflags
, XINO
))
1619 pr_warn_once("udba=*notify requires xino\n");
1621 if (au_opt_test(sbinfo
->si_mntflags
, DIRPERM1
))
1622 pr_warn_once("dirperm1 breaks the protection"
1623 " by the permission bits on the lower branch\n");
1628 dir
= d_inode(root
);
1629 do_plink
= !!au_opt_test(sbinfo
->si_mntflags
, PLINK
);
1630 can_no_dreval
= !!au_opt_test((sbinfo
->si_mntflags
| pending
),
1632 bbot
= au_sbbot(sb
);
1633 for (bindex
= 0; !err
&& bindex
<= bbot
; bindex
++) {
1635 h_dir
= au_h_iptr(dir
, bindex
);
1636 br
= au_sbr(sb
, bindex
);
1638 if ((br
->br_perm
& AuBrAttr_ICEX
)
1639 && !h_dir
->i_op
->listxattr
)
1640 br
->br_perm
&= ~AuBrAttr_ICEX
;
1642 if ((br
->br_perm
& AuBrAttr_ICEX_SEC
)
1643 && (au_br_sb(br
)->s_flags
& SB_NOSEC
))
1644 br
->br_perm
&= ~AuBrAttr_ICEX_SEC
;
1650 wbr_wh_read_lock(wbr
);
1652 if (!au_br_writable(br
->br_perm
)) {
1655 || (!wbr
->wbr_whbase
1657 && !wbr
->wbr_orph
));
1658 } else if (!au_br_wh_linkable(br
->br_perm
)) {
1659 /* skip = (!br->br_whbase && !br->br_orph); */
1660 skip
= (!wbr
|| !wbr
->wbr_whbase
);
1663 skip
= !!wbr
->wbr_plink
;
1665 skip
= !wbr
->wbr_plink
;
1668 /* skip = (br->br_whbase && br->br_ohph); */
1669 skip
= (wbr
&& wbr
->wbr_whbase
);
1672 skip
= !!wbr
->wbr_plink
;
1674 skip
= !wbr
->wbr_plink
;
1678 wbr_wh_read_unlock(wbr
);
1680 if (can_no_dreval
) {
1681 dentry
= br
->br_path
.dentry
;
1682 spin_lock(&dentry
->d_lock
);
1683 if (dentry
->d_flags
&
1684 (DCACHE_OP_REVALIDATE
| DCACHE_OP_WEAK_REVALIDATE
))
1686 spin_unlock(&dentry
->d_lock
);
1689 if (au_br_fhsm(br
->br_perm
)) {
1691 AuDebugOn(!br
->br_fhsm
);
1697 hdir
= au_hi(dir
, bindex
);
1698 au_hn_inode_lock_nested(hdir
, AuLsc_I_PARENT
);
1700 wbr_wh_write_lock(wbr
);
1701 err
= au_wh_init(br
, sb
);
1703 wbr_wh_write_unlock(wbr
);
1704 au_hn_inode_unlock(hdir
);
1706 if (!err
&& do_free
) {
1713 au_fset_si(sbinfo
, NO_DREVAL
);
1715 au_fclr_si(sbinfo
, NO_DREVAL
);
1718 au_fset_si(sbinfo
, FHSM
);
1719 for (bindex
= bbot
; bindex
>= 0; bindex
--) {
1720 br
= au_sbr(sb
, bindex
);
1721 if (au_br_fhsm(br
->br_perm
)) {
1722 au_fhsm_set_bottom(sb
, bindex
);
1727 au_fclr_si(sbinfo
, FHSM
);
1728 au_fhsm_set_bottom(sb
, -1);
1734 int au_opts_mount(struct super_block
*sb
, struct au_opts
*opts
)
1738 aufs_bindex_t bindex
, bbot
;
1740 struct au_opt_xino
*opt_xino
, xino
;
1741 struct au_sbinfo
*sbinfo
;
1742 struct au_branch
*br
;
1745 SiMustWriteLock(sb
);
1750 while (err
>= 0 && opt
->type
!= Opt_tail
)
1751 err
= au_opt_simple(sb
, opt
++, opts
);
1754 else if (unlikely(err
< 0))
1757 /* disable xino and udba temporary */
1758 sbinfo
= au_sbi(sb
);
1759 tmp
= sbinfo
->si_mntflags
;
1760 au_opt_clr(sbinfo
->si_mntflags
, XINO
);
1761 au_opt_set_udba(sbinfo
->si_mntflags
, UDBA_REVAL
);
1764 while (err
>= 0 && opt
->type
!= Opt_tail
)
1765 err
= au_opt_br(sb
, opt
++, opts
);
1768 else if (unlikely(err
< 0))
1771 bbot
= au_sbbot(sb
);
1772 if (unlikely(bbot
< 0)) {
1774 pr_err("no branches\n");
1778 if (au_opt_test(tmp
, XINO
))
1779 au_opt_set(sbinfo
->si_mntflags
, XINO
);
1781 while (!err
&& opt
->type
!= Opt_tail
)
1782 err
= au_opt_xino(sb
, opt
++, &opt_xino
, opts
);
1786 err
= au_opts_verify(sb
, sb
->s_flags
, tmp
);
1791 if (au_opt_test(tmp
, XINO
) && !opt_xino
) {
1792 xino
.file
= au_xino_def(sb
);
1793 err
= PTR_ERR(xino
.file
);
1794 if (IS_ERR(xino
.file
))
1797 err
= au_xino_set(sb
, &xino
, /*remount*/0);
1804 tmp
&= AuOptMask_UDBA
;
1805 sbinfo
->si_mntflags
&= ~AuOptMask_UDBA
;
1806 sbinfo
->si_mntflags
|= tmp
;
1807 bbot
= au_sbbot(sb
);
1808 for (bindex
= 0; bindex
<= bbot
; bindex
++) {
1809 br
= au_sbr(sb
, bindex
);
1810 err
= au_hnotify_reset_br(tmp
, br
, br
->br_perm
);
1812 AuIOErr("hnotify failed on br %d, %d, ignored\n",
1814 /* go on even if err */
1816 if (au_opt_test(tmp
, UDBA_HNOTIFY
)) {
1817 dir
= d_inode(sb
->s_root
);
1818 au_hn_reset(dir
, au_hi_flags(dir
, /*isdir*/1) & ~AuHi_XINO
);
1825 int au_opts_remount(struct super_block
*sb
, struct au_opts
*opts
)
1828 unsigned char no_dreval
;
1830 struct au_opt_xino
*opt_xino
;
1832 struct au_sbinfo
*sbinfo
;
1834 SiMustWriteLock(sb
);
1836 err
= au_dr_opt_flush(sb
);
1839 au_fset_opts(opts
->flags
, DR_FLUSHED
);
1841 dir
= d_inode(sb
->s_root
);
1842 sbinfo
= au_sbi(sb
);
1845 while (err
>= 0 && opt
->type
!= Opt_tail
) {
1846 err
= au_opt_simple(sb
, opt
, opts
);
1848 err
= au_opt_br(sb
, opt
, opts
);
1850 err
= au_opt_xino(sb
, opt
, &opt_xino
, opts
);
1856 /* go on even err */
1858 no_dreval
= !!au_ftest_si(sbinfo
, NO_DREVAL
);
1859 rerr
= au_opts_verify(sb
, opts
->sb_flags
, /*pending*/0);
1860 if (unlikely(rerr
&& !err
))
1863 if (no_dreval
!= !!au_ftest_si(sbinfo
, NO_DREVAL
))
1864 au_fset_opts(opts
->flags
, REFRESH_IDOP
);
1866 if (au_ftest_opts(opts
->flags
, TRUNC_XIB
)) {
1867 rerr
= au_xib_trunc(sb
);
1868 if (unlikely(rerr
&& !err
))
1872 /* will be handled by the caller */
1873 if (!au_ftest_opts(opts
->flags
, REFRESH
)
1874 && (opts
->given_udba
1875 || au_opt_test(sbinfo
->si_mntflags
, XINO
)
1876 || au_ftest_opts(opts
->flags
, REFRESH_IDOP
)
1878 au_fset_opts(opts
->flags
, REFRESH
);
1880 AuDbg("status 0x%x\n", opts
->flags
);
1886 /* ---------------------------------------------------------------------- */
1888 unsigned int au_opt_udba(struct super_block
*sb
)
1890 return au_mntflags(sb
) & AuOptMask_UDBA
;