2 * Copyright (C) 2005-2012 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, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <linux/namei.h>
24 #include <linux/types.h> /* a distribution requires */
25 #include <linux/parser.h>
28 /* ---------------------------------------------------------------------- */
32 Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
33 Opt_idel, Opt_imod, Opt_ireorder,
34 Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
35 Opt_rdblk_def, Opt_rdhash_def,
36 Opt_xino, Opt_zxino, Opt_noxino,
37 Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
38 Opt_trunc_xino_path, Opt_itrunc_xino,
39 Opt_trunc_xib, Opt_notrunc_xib,
41 Opt_plink, Opt_noplink, Opt_list_plink,
44 /* Opt_lock, Opt_unlock, */
45 Opt_cmd, Opt_cmd_args,
46 Opt_diropq_a, Opt_diropq_w,
47 Opt_warn_perm, Opt_nowarn_perm,
48 Opt_wbr_copyup, Opt_wbr_create,
49 Opt_refrof, Opt_norefrof,
50 Opt_verbose, Opt_noverbose,
51 Opt_sum, Opt_nosum, Opt_wsum,
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 {Opt_diropq_a, "diropq=always"},
106 {Opt_diropq_a, "diropq=a"},
107 {Opt_diropq_w, "diropq=whiteouted"},
108 {Opt_diropq_w, "diropq=w"},
110 {Opt_warn_perm, "warn_perm"},
111 {Opt_nowarn_perm, "nowarn_perm"},
113 /* keep them temporary */
114 {Opt_ignore_silent, "coo=%s"},
115 {Opt_ignore_silent, "nodlgt"},
116 {Opt_ignore_silent, "nodirperm1"},
117 {Opt_ignore_silent, "clean_plink"},
119 #ifdef CONFIG_AUFS_SHWH
122 {Opt_noshwh, "noshwh"},
124 {Opt_rendir, "rendir=%d"},
126 {Opt_refrof, "refrof"},
127 {Opt_norefrof, "norefrof"},
129 {Opt_verbose, "verbose"},
131 {Opt_noverbose, "noverbose"},
132 {Opt_noverbose, "quiet"},
133 {Opt_noverbose, "q"},
134 {Opt_noverbose, "silent"},
137 {Opt_nosum, "nosum"},
140 {Opt_rdcache, "rdcache=%d"},
141 {Opt_rdblk, "rdblk=%d"},
142 {Opt_rdblk_def, "rdblk=def"},
143 {Opt_rdhash, "rdhash=%d"},
144 {Opt_rdhash_def, "rdhash=def"},
146 {Opt_wbr_create, "create=%s"},
147 {Opt_wbr_create, "create_policy=%s"},
148 {Opt_wbr_copyup, "cpup=%s"},
149 {Opt_wbr_copyup, "copyup=%s"},
150 {Opt_wbr_copyup, "copyup_policy=%s"},
152 /* internal use for the scripts */
153 {Opt_ignore_silent, "si=%s"},
156 {Opt_ignore, "debug=%d"},
157 {Opt_ignore, "delete=whiteout"},
158 {Opt_ignore, "delete=all"},
159 {Opt_ignore, "imap=%s"},
161 /* temporary workaround, due to old mount(8)? */
162 {Opt_ignore_silent, "relatime"},
167 /* ---------------------------------------------------------------------- */
169 static const char *au_parser_pattern(int val, struct match_token *token)
171 while (token->pattern) {
172 if (token->token == val)
173 return token->pattern;
180 /* ---------------------------------------------------------------------- */
182 static match_table_t brperm = {
183 {AuBrPerm_RO, AUFS_BRPERM_RO},
184 {AuBrPerm_RR, AUFS_BRPERM_RR},
185 {AuBrPerm_RW, AUFS_BRPERM_RW},
189 static match_table_t brrattr = {
190 {AuBrRAttr_WH, AUFS_BRRATTR_WH},
194 static match_table_t brwattr = {
195 {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
199 #define AuBrStr_LONGEST AUFS_BRPERM_RW "+" AUFS_BRWATTR_NLWH
201 static int br_attr_val(char *str, match_table_t table, substring_t args[])
208 p = strchr(str, '+');
211 v = match_token(str, table, args);
217 pr_warning("ignored branch attribute %s\n", str);
227 static int noinline_for_stack br_perm_val(char *perm)
231 substring_t args[MAX_OPT_ARGS];
233 p = strchr(perm, '+');
236 val = match_token(perm, brperm, args);
240 pr_warning("ignored branch permission %s\n", perm);
250 val |= br_attr_val(p + 1, brrattr, args);
253 val |= br_attr_val(p + 1, brwattr, args);
261 /* Caller should free the return value */
262 char *au_optstr_br_perm(int brperm)
264 char *p, a[sizeof(AuBrStr_LONGEST)];
267 #define SetPerm(str) do { \
269 memcpy(a, str, sz); \
273 #define AppendAttr(flag, str) do { \
274 if (brperm & flag) { \
277 memcpy(p, str, sz); \
282 switch (brperm & AuBrPerm_Mask) {
284 SetPerm(AUFS_BRPERM_RO);
287 SetPerm(AUFS_BRPERM_RR);
290 SetPerm(AUFS_BRPERM_RW);
296 AppendAttr(AuBrRAttr_WH, AUFS_BRRATTR_WH);
297 AppendAttr(AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH);
299 AuDebugOn(strlen(a) >= sizeof(a));
300 return kstrdup(a, GFP_NOFS);
305 /* ---------------------------------------------------------------------- */
307 static match_table_t udbalevel = {
308 {AuOpt_UDBA_REVAL, "reval"},
309 {AuOpt_UDBA_NONE, "none"},
310 #ifdef CONFIG_AUFS_HNOTIFY
311 {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
312 #ifdef CONFIG_AUFS_HFSNOTIFY
313 {AuOpt_UDBA_HNOTIFY, "fsnotify"},
319 static int noinline_for_stack udba_val(char *str)
321 substring_t args[MAX_OPT_ARGS];
323 return match_token(str, udbalevel, args);
326 const char *au_optstr_udba(int udba)
328 return au_parser_pattern(udba, (void *)udbalevel);
331 /* ---------------------------------------------------------------------- */
333 static match_table_t au_wbr_create_policy = {
334 {AuWbrCreate_TDP, "tdp"},
335 {AuWbrCreate_TDP, "top-down-parent"},
336 {AuWbrCreate_RR, "rr"},
337 {AuWbrCreate_RR, "round-robin"},
338 {AuWbrCreate_MFS, "mfs"},
339 {AuWbrCreate_MFS, "most-free-space"},
340 {AuWbrCreate_MFSV, "mfs:%d"},
341 {AuWbrCreate_MFSV, "most-free-space:%d"},
343 {AuWbrCreate_MFSRR, "mfsrr:%d"},
344 {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
345 {AuWbrCreate_PMFS, "pmfs"},
346 {AuWbrCreate_PMFSV, "pmfs:%d"},
352 * cf. linux/lib/parser.c and cmdline.c
353 * gave up calling memparse() since it uses simple_strtoull() instead of
356 static int noinline_for_stack
357 au_match_ull(substring_t *s, unsigned long long *result)
364 len = s->to - s->from;
365 if (len + 1 <= sizeof(a)) {
366 memcpy(a, s->from, len);
368 err = kstrtoull(a, 0, result);
373 static int au_wbr_mfs_wmark(substring_t *arg, char *str,
374 struct au_opt_wbr_create *create)
377 unsigned long long ull;
380 if (!au_match_ull(arg, &ull))
381 create->mfsrr_watermark = ull;
383 pr_err("bad integer in %s\n", str);
390 static int au_wbr_mfs_sec(substring_t *arg, char *str,
391 struct au_opt_wbr_create *create)
396 if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
397 create->mfs_second = n;
399 pr_err("bad integer in %s\n", str);
406 static int noinline_for_stack
407 au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
410 substring_t args[MAX_OPT_ARGS];
412 err = match_token(str, au_wbr_create_policy, args);
413 create->wbr_create = err;
415 case AuWbrCreate_MFSRRV:
416 e = au_wbr_mfs_wmark(&args[0], str, create);
418 e = au_wbr_mfs_sec(&args[1], str, create);
422 case AuWbrCreate_MFSRR:
423 e = au_wbr_mfs_wmark(&args[0], str, create);
429 case AuWbrCreate_MFS:
430 case AuWbrCreate_PMFS:
431 create->mfs_second = AUFS_MFS_DEF_SEC;
433 case AuWbrCreate_MFSV:
434 case AuWbrCreate_PMFSV:
435 e = au_wbr_mfs_sec(&args[0], str, create);
444 const char *au_optstr_wbr_create(int wbr_create)
446 return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
449 static match_table_t au_wbr_copyup_policy = {
450 {AuWbrCopyup_TDP, "tdp"},
451 {AuWbrCopyup_TDP, "top-down-parent"},
452 {AuWbrCopyup_BUP, "bup"},
453 {AuWbrCopyup_BUP, "bottom-up-parent"},
454 {AuWbrCopyup_BU, "bu"},
455 {AuWbrCopyup_BU, "bottom-up"},
459 static int noinline_for_stack au_wbr_copyup_val(char *str)
461 substring_t args[MAX_OPT_ARGS];
463 return match_token(str, au_wbr_copyup_policy, args);
466 const char *au_optstr_wbr_copyup(int wbr_copyup)
468 return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
471 /* ---------------------------------------------------------------------- */
473 static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
475 static void dump_opts(struct au_opts *opts)
477 #ifdef CONFIG_AUFS_DEBUG
478 /* reduce stack space */
480 struct au_opt_add *add;
481 struct au_opt_del *del;
482 struct au_opt_mod *mod;
483 struct au_opt_xino *xino;
484 struct au_opt_xino_itrunc *xino_itrunc;
485 struct au_opt_wbr_create *create;
490 while (opt->type != Opt_tail) {
494 AuDbg("add {b%d, %s, 0x%x, %p}\n",
495 u.add->bindex, u.add->pathname, u.add->perm,
501 AuDbg("del {%s, %p}\n",
502 u.del->pathname, u.del->h_path.dentry);
507 AuDbg("mod {%s, 0x%x, %p}\n",
508 u.mod->path, u.mod->perm, u.mod->h_root);
512 AuDbg("append {b%d, %s, 0x%x, %p}\n",
513 u.add->bindex, u.add->pathname, u.add->perm,
518 AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
519 u.add->bindex, u.add->pathname, u.add->perm,
523 AuDbg("dirwh %d\n", opt->dirwh);
526 AuDbg("rdcache %d\n", opt->rdcache);
529 AuDbg("rdblk %u\n", opt->rdblk);
532 AuDbg("rdblk_def\n");
535 AuDbg("rdhash %u\n", opt->rdhash);
538 AuDbg("rdhash_def\n");
542 AuDbg("xino {%s %.*s}\n",
544 AuDLNPair(u.xino->file->f_dentry));
549 case Opt_notrunc_xino:
550 AuLabel(notrunc_xino);
552 case Opt_trunc_xino_path:
553 case Opt_itrunc_xino:
554 u.xino_itrunc = &opt->xino_itrunc;
555 AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
564 case Opt_notrunc_xib:
565 AuLabel(notrunc_xib);
583 AuDbg("udba %d, %s\n",
584 opt->udba, au_optstr_udba(opt->udba));
601 case Opt_nowarn_perm:
602 AuLabel(nowarn_perm);
626 u.create = &opt->wbr_create;
627 AuDbg("create %d, %s\n", u.create->wbr_create,
628 au_optstr_wbr_create(u.create->wbr_create));
629 switch (u.create->wbr_create) {
630 case AuWbrCreate_MFSV:
631 case AuWbrCreate_PMFSV:
632 AuDbg("%d sec\n", u.create->mfs_second);
634 case AuWbrCreate_MFSRR:
635 AuDbg("%llu watermark\n",
636 u.create->mfsrr_watermark);
638 case AuWbrCreate_MFSRRV:
639 AuDbg("%llu watermark, %d sec\n",
640 u.create->mfsrr_watermark,
641 u.create->mfs_second);
646 AuDbg("copyup %d, %s\n", opt->wbr_copyup,
647 au_optstr_wbr_copyup(opt->wbr_copyup));
657 void au_opts_free(struct au_opts *opts)
662 while (opt->type != Opt_tail) {
667 path_put(&opt->add.path);
671 path_put(&opt->del.h_path);
675 dput(opt->mod.h_root);
678 fput(opt->xino.file);
685 static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
686 aufs_bindex_t bindex)
689 struct au_opt_add *add = &opt->add;
692 add->bindex = bindex;
693 add->perm = AuBrPerm_RO;
694 add->pathname = opt_str;
695 p = strchr(opt_str, '=');
699 add->perm = br_perm_val(p);
702 err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
705 add->perm = AuBrPerm_RO;
706 if (au_test_fs_rr(add->path.dentry->d_sb))
707 add->perm = AuBrPerm_RR;
708 else if (!bindex && !(sb_flags & MS_RDONLY))
709 add->perm = AuBrPerm_RW;
714 pr_err("lookup failed %s (%d)\n", add->pathname, err);
721 static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
725 del->pathname = args[0].from;
726 AuDbg("del path %s\n", del->pathname);
728 err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
730 pr_err("lookup failed %s (%d)\n", del->pathname, err);
735 #if 0 /* reserved for future use */
736 static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
737 struct au_opt_del *del, substring_t args[])
744 aufs_read_lock(root, AuLock_FLUSH);
745 if (bindex < 0 || au_sbend(sb) < bindex) {
746 pr_err("out of bounds, %d\n", bindex);
751 del->h_path.dentry = dget(au_h_dptr(root, bindex));
752 del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
755 aufs_read_unlock(root, !AuLock_IR);
760 static int noinline_for_stack
761 au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
768 mod->path = args[0].from;
769 p = strchr(mod->path, '=');
771 pr_err("no permssion %s\n", args[0].from);
776 err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
778 pr_err("lookup failed %s (%d)\n", mod->path, err);
782 mod->perm = br_perm_val(p);
783 AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
784 mod->h_root = dget(path.dentry);
791 #if 0 /* reserved for future use */
792 static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
793 struct au_opt_mod *mod, substring_t args[])
800 aufs_read_lock(root, AuLock_FLUSH);
801 if (bindex < 0 || au_sbend(sb) < bindex) {
802 pr_err("out of bounds, %d\n", bindex);
807 mod->perm = br_perm_val(args[1].from);
808 AuDbg("mod path %s, perm 0x%x, %s\n",
809 mod->path, mod->perm, args[1].from);
810 mod->h_root = dget(au_h_dptr(root, bindex));
813 aufs_read_unlock(root, !AuLock_IR);
818 static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
824 file = au_xino_create(sb, args[0].from, /*silent*/0);
830 if (unlikely(file->f_dentry->d_sb == sb)) {
832 pr_err("%s must be outside\n", args[0].from);
838 xino->path = args[0].from;
844 static int noinline_for_stack
845 au_opts_parse_xino_itrunc_path(struct super_block *sb,
846 struct au_opt_xino_itrunc *xino_itrunc,
850 aufs_bindex_t bend, bindex;
854 err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
856 pr_err("lookup failed %s (%d)\n", args[0].from, err);
860 xino_itrunc->bindex = -1;
862 aufs_read_lock(root, AuLock_FLUSH);
864 for (bindex = 0; bindex <= bend; bindex++) {
865 if (au_h_dptr(root, bindex) == path.dentry) {
866 xino_itrunc->bindex = bindex;
870 aufs_read_unlock(root, !AuLock_IR);
873 if (unlikely(xino_itrunc->bindex < 0)) {
874 pr_err("no such branch %s\n", args[0].from);
882 /* called without aufs lock */
883 int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
886 aufs_bindex_t bindex;
887 unsigned char skipped;
889 struct au_opt *opt, *opt_tail;
891 /* reduce the stack space */
893 struct au_opt_xino_itrunc *xino_itrunc;
894 struct au_opt_wbr_create *create;
897 substring_t args[MAX_OPT_ARGS];
901 a = kmalloc(sizeof(*a), GFP_NOFS);
909 opt_tail = opt + opts->max_opt - 1;
910 opt->type = Opt_tail;
911 while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
914 token = match_token(opt_str, options, a->args);
918 while (!err && (opt_str = strsep(&a->args[0].from, ":"))
920 err = opt_add(opt, opt_str, opts->sb_flags,
922 if (unlikely(!err && ++opt > opt_tail)) {
926 opt->type = Opt_tail;
931 if (unlikely(match_int(&a->args[0], &n))) {
932 pr_err("bad integer in %s\n", opt_str);
936 err = opt_add(opt, a->args[1].from, opts->sb_flags,
942 err = opt_add(opt, a->args[0].from, opts->sb_flags,
948 err = opt_add(opt, a->args[0].from, opts->sb_flags,
954 err = au_opts_parse_del(&opt->del, a->args);
958 #if 0 /* reserved for future use */
960 del->pathname = "(indexed)";
961 if (unlikely(match_int(&args[0], &n))) {
962 pr_err("bad integer in %s\n", opt_str);
965 err = au_opts_parse_idel(sb, n, &opt->del, a->args);
971 err = au_opts_parse_mod(&opt->mod, a->args);
975 #ifdef IMOD /* reserved for future use */
977 u.mod->path = "(indexed)";
978 if (unlikely(match_int(&a->args[0], &n))) {
979 pr_err("bad integer in %s\n", opt_str);
982 err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
988 err = au_opts_parse_xino(sb, &opt->xino, a->args);
993 case Opt_trunc_xino_path:
994 err = au_opts_parse_xino_itrunc_path
995 (sb, &opt->xino_itrunc, a->args);
1000 case Opt_itrunc_xino:
1001 u.xino_itrunc = &opt->xino_itrunc;
1002 if (unlikely(match_int(&a->args[0], &n))) {
1003 pr_err("bad integer in %s\n", opt_str);
1006 u.xino_itrunc->bindex = n;
1007 aufs_read_lock(root, AuLock_FLUSH);
1008 if (n < 0 || au_sbend(sb) < n) {
1009 pr_err("out of bounds, %d\n", n);
1010 aufs_read_unlock(root, !AuLock_IR);
1013 aufs_read_unlock(root, !AuLock_IR);
1019 if (unlikely(match_int(&a->args[0], &opt->dirwh)))
1026 if (unlikely(match_int(&a->args[0], &n))) {
1027 pr_err("bad integer in %s\n", opt_str);
1030 if (unlikely(n > AUFS_RDCACHE_MAX)) {
1031 pr_err("rdcache must be smaller than %d\n",
1040 if (unlikely(match_int(&a->args[0], &n)
1042 || n > KMALLOC_MAX_SIZE)) {
1043 pr_err("bad integer in %s\n", opt_str);
1046 if (unlikely(n && n < NAME_MAX)) {
1047 pr_err("rdblk must be larger than %d\n",
1056 if (unlikely(match_int(&a->args[0], &n)
1058 || n * sizeof(struct hlist_head)
1059 > KMALLOC_MAX_SIZE)) {
1060 pr_err("bad integer in %s\n", opt_str);
1068 case Opt_trunc_xino:
1069 case Opt_notrunc_xino:
1072 case Opt_notrunc_xib:
1077 case Opt_list_plink:
1083 case Opt_nowarn_perm:
1092 case Opt_rdhash_def:
1098 opt->udba = udba_val(a->args[0].from);
1099 if (opt->udba >= 0) {
1103 pr_err("wrong value, %s\n", opt_str);
1106 case Opt_wbr_create:
1107 u.create = &opt->wbr_create;
1108 u.create->wbr_create
1109 = au_wbr_create_val(a->args[0].from, u.create);
1110 if (u.create->wbr_create >= 0) {
1114 pr_err("wrong value, %s\n", opt_str);
1116 case Opt_wbr_copyup:
1117 opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
1118 if (opt->wbr_copyup >= 0) {
1122 pr_err("wrong value, %s\n", opt_str);
1126 pr_warning("ignored %s\n", opt_str);
1128 case Opt_ignore_silent:
1133 pr_err("unknown option %s\n", opt_str);
1137 if (!err && !skipped) {
1138 if (unlikely(++opt > opt_tail)) {
1141 opt->type = Opt_tail;
1144 opt->type = Opt_tail;
1157 static int au_opt_wbr_create(struct super_block *sb,
1158 struct au_opt_wbr_create *create)
1161 struct au_sbinfo *sbinfo;
1163 SiMustWriteLock(sb);
1165 err = 1; /* handled */
1166 sbinfo = au_sbi(sb);
1167 if (sbinfo->si_wbr_create_ops->fin) {
1168 err = sbinfo->si_wbr_create_ops->fin(sb);
1173 sbinfo->si_wbr_create = create->wbr_create;
1174 sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
1175 switch (create->wbr_create) {
1176 case AuWbrCreate_MFSRRV:
1177 case AuWbrCreate_MFSRR:
1178 sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
1180 case AuWbrCreate_MFS:
1181 case AuWbrCreate_MFSV:
1182 case AuWbrCreate_PMFS:
1183 case AuWbrCreate_PMFSV:
1184 sbinfo->si_wbr_mfs.mfs_expire
1185 = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1189 if (sbinfo->si_wbr_create_ops->init)
1190 sbinfo->si_wbr_create_ops->init(sb); /* ignore */
1197 * plus: processed without an error
1200 static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
1201 struct au_opts *opts)
1204 struct au_sbinfo *sbinfo;
1206 SiMustWriteLock(sb);
1208 err = 1; /* handled */
1209 sbinfo = au_sbi(sb);
1210 switch (opt->type) {
1212 sbinfo->si_mntflags &= ~AuOptMask_UDBA;
1213 sbinfo->si_mntflags |= opt->udba;
1214 opts->given_udba |= opt->udba;
1218 au_opt_set(sbinfo->si_mntflags, PLINK);
1221 if (au_opt_test(sbinfo->si_mntflags, PLINK))
1222 au_plink_put(sb, /*verbose*/1);
1223 au_opt_clr(sbinfo->si_mntflags, PLINK);
1225 case Opt_list_plink:
1226 if (au_opt_test(sbinfo->si_mntflags, PLINK))
1231 au_opt_set(sbinfo->si_mntflags, DIO);
1232 au_fset_opts(opts->flags, REFRESH_DYAOP);
1235 au_opt_clr(sbinfo->si_mntflags, DIO);
1236 au_fset_opts(opts->flags, REFRESH_DYAOP);
1240 au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
1243 au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
1247 au_opt_set(sbinfo->si_mntflags, WARN_PERM);
1249 case Opt_nowarn_perm:
1250 au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
1254 au_opt_set(sbinfo->si_mntflags, REFROF);
1257 au_opt_clr(sbinfo->si_mntflags, REFROF);
1261 au_opt_set(sbinfo->si_mntflags, VERBOSE);
1264 au_opt_clr(sbinfo->si_mntflags, VERBOSE);
1268 au_opt_set(sbinfo->si_mntflags, SUM);
1271 au_opt_clr(sbinfo->si_mntflags, SUM);
1272 au_opt_set(sbinfo->si_mntflags, SUM_W);
1274 au_opt_clr(sbinfo->si_mntflags, SUM);
1275 au_opt_clr(sbinfo->si_mntflags, SUM_W);
1278 case Opt_wbr_create:
1279 err = au_opt_wbr_create(sb, &opt->wbr_create);
1281 case Opt_wbr_copyup:
1282 sbinfo->si_wbr_copyup = opt->wbr_copyup;
1283 sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
1287 sbinfo->si_dirwh = opt->dirwh;
1292 = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1295 sbinfo->si_rdblk = opt->rdblk;
1298 sbinfo->si_rdblk = AUFS_RDBLK_DEF;
1301 sbinfo->si_rdhash = opt->rdhash;
1303 case Opt_rdhash_def:
1304 sbinfo->si_rdhash = AUFS_RDHASH_DEF;
1308 au_opt_set(sbinfo->si_mntflags, SHWH);
1311 au_opt_clr(sbinfo->si_mntflags, SHWH);
1314 case Opt_trunc_xino:
1315 au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
1317 case Opt_notrunc_xino:
1318 au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
1321 case Opt_trunc_xino_path:
1322 case Opt_itrunc_xino:
1323 err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
1329 au_fset_opts(opts->flags, TRUNC_XIB);
1331 case Opt_notrunc_xib:
1332 au_fclr_opts(opts->flags, TRUNC_XIB);
1344 * returns tri-state.
1345 * plus: processed without an error
1349 static int au_opt_br(struct super_block *sb, struct au_opt *opt,
1350 struct au_opts *opts)
1352 int err, do_refresh;
1355 switch (opt->type) {
1357 opt->add.bindex = au_sbend(sb) + 1;
1358 if (opt->add.bindex < 0)
1359 opt->add.bindex = 0;
1362 opt->add.bindex = 0;
1365 err = au_br_add(sb, &opt->add,
1366 au_ftest_opts(opts->flags, REMOUNT));
1369 au_fset_opts(opts->flags, REFRESH);
1375 err = au_br_del(sb, &opt->del,
1376 au_ftest_opts(opts->flags, REMOUNT));
1379 au_fset_opts(opts->flags, TRUNC_XIB);
1380 au_fset_opts(opts->flags, REFRESH);
1386 err = au_br_mod(sb, &opt->mod,
1387 au_ftest_opts(opts->flags, REMOUNT),
1392 au_fset_opts(opts->flags, REFRESH);
1400 static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
1401 struct au_opt_xino **opt_xino,
1402 struct au_opts *opts)
1405 aufs_bindex_t bend, bindex;
1406 struct dentry *root, *parent, *h_root;
1409 switch (opt->type) {
1411 err = au_xino_set(sb, &opt->xino,
1412 !!au_ftest_opts(opts->flags, REMOUNT));
1416 *opt_xino = &opt->xino;
1417 au_xino_brid_set(sb, -1);
1419 /* safe d_parent access */
1420 parent = opt->xino.file->f_dentry->d_parent;
1422 bend = au_sbend(sb);
1423 for (bindex = 0; bindex <= bend; bindex++) {
1424 h_root = au_h_dptr(root, bindex);
1425 if (h_root == parent) {
1426 au_xino_brid_set(sb, au_sbr_id(sb, bindex));
1434 au_xino_brid_set(sb, -1);
1435 *opt_xino = (void *)-1;
1442 int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
1443 unsigned int pending)
1446 aufs_bindex_t bindex, bend;
1447 unsigned char do_plink, skip, do_free;
1448 struct au_branch *br;
1450 struct dentry *root;
1451 struct inode *dir, *h_dir;
1452 struct au_sbinfo *sbinfo;
1453 struct au_hinode *hdir;
1457 sbinfo = au_sbi(sb);
1458 AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
1460 if (!(sb_flags & MS_RDONLY)) {
1461 if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
1462 pr_warning("first branch should be rw\n");
1463 if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
1464 pr_warning("shwh should be used with ro\n");
1467 if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1468 && !au_opt_test(sbinfo->si_mntflags, XINO))
1469 pr_warning("udba=*notify requires xino\n");
1473 dir = root->d_inode;
1474 do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
1475 bend = au_sbend(sb);
1476 for (bindex = 0; !err && bindex <= bend; bindex++) {
1478 h_dir = au_h_iptr(dir, bindex);
1479 br = au_sbr(sb, bindex);
1484 wbr_wh_read_lock(wbr);
1486 if (!au_br_writable(br->br_perm)) {
1489 || (!wbr->wbr_whbase
1491 && !wbr->wbr_orph));
1492 } else if (!au_br_wh_linkable(br->br_perm)) {
1493 /* skip = (!br->br_whbase && !br->br_orph); */
1494 skip = (!wbr || !wbr->wbr_whbase);
1497 skip = !!wbr->wbr_plink;
1499 skip = !wbr->wbr_plink;
1502 /* skip = (br->br_whbase && br->br_ohph); */
1503 skip = (wbr && wbr->wbr_whbase);
1506 skip = !!wbr->wbr_plink;
1508 skip = !wbr->wbr_plink;
1512 wbr_wh_read_unlock(wbr);
1517 hdir = au_hi(dir, bindex);
1518 au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1520 wbr_wh_write_lock(wbr);
1521 err = au_wh_init(au_h_dptr(root, bindex), br, sb);
1523 wbr_wh_write_unlock(wbr);
1524 au_hn_imtx_unlock(hdir);
1526 if (!err && do_free) {
1535 int au_opts_mount(struct super_block *sb, struct au_opts *opts)
1539 aufs_bindex_t bindex, bend;
1541 struct au_opt_xino *opt_xino, xino;
1542 struct au_sbinfo *sbinfo;
1543 struct au_branch *br;
1545 SiMustWriteLock(sb);
1550 while (err >= 0 && opt->type != Opt_tail)
1551 err = au_opt_simple(sb, opt++, opts);
1554 else if (unlikely(err < 0))
1557 /* disable xino and udba temporary */
1558 sbinfo = au_sbi(sb);
1559 tmp = sbinfo->si_mntflags;
1560 au_opt_clr(sbinfo->si_mntflags, XINO);
1561 au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
1564 while (err >= 0 && opt->type != Opt_tail)
1565 err = au_opt_br(sb, opt++, opts);
1568 else if (unlikely(err < 0))
1571 bend = au_sbend(sb);
1572 if (unlikely(bend < 0)) {
1574 pr_err("no branches\n");
1578 if (au_opt_test(tmp, XINO))
1579 au_opt_set(sbinfo->si_mntflags, XINO);
1581 while (!err && opt->type != Opt_tail)
1582 err = au_opt_xino(sb, opt++, &opt_xino, opts);
1586 err = au_opts_verify(sb, sb->s_flags, tmp);
1591 if (au_opt_test(tmp, XINO) && !opt_xino) {
1592 xino.file = au_xino_def(sb);
1593 err = PTR_ERR(xino.file);
1594 if (IS_ERR(xino.file))
1597 err = au_xino_set(sb, &xino, /*remount*/0);
1604 tmp &= AuOptMask_UDBA;
1605 sbinfo->si_mntflags &= ~AuOptMask_UDBA;
1606 sbinfo->si_mntflags |= tmp;
1607 bend = au_sbend(sb);
1608 for (bindex = 0; bindex <= bend; bindex++) {
1609 br = au_sbr(sb, bindex);
1610 err = au_hnotify_reset_br(tmp, br, br->br_perm);
1612 AuIOErr("hnotify failed on br %d, %d, ignored\n",
1614 /* go on even if err */
1616 if (au_opt_test(tmp, UDBA_HNOTIFY)) {
1617 struct inode *dir = sb->s_root->d_inode;
1618 au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1625 int au_opts_remount(struct super_block *sb, struct au_opts *opts)
1629 struct au_opt_xino *opt_xino;
1631 struct au_sbinfo *sbinfo;
1633 SiMustWriteLock(sb);
1635 dir = sb->s_root->d_inode;
1636 sbinfo = au_sbi(sb);
1640 while (err >= 0 && opt->type != Opt_tail) {
1641 err = au_opt_simple(sb, opt, opts);
1643 err = au_opt_br(sb, opt, opts);
1645 err = au_opt_xino(sb, opt, &opt_xino, opts);
1651 /* go on even err */
1653 rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
1654 if (unlikely(rerr && !err))
1657 if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
1658 rerr = au_xib_trunc(sb);
1659 if (unlikely(rerr && !err))
1663 /* will be handled by the caller */
1664 if (!au_ftest_opts(opts->flags, REFRESH)
1665 && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
1666 au_fset_opts(opts->flags, REFRESH);
1668 AuDbg("status 0x%x\n", opts->flags);
1672 /* ---------------------------------------------------------------------- */
1674 unsigned int au_opt_udba(struct super_block *sb)
1676 return au_mntflags(sb) & AuOptMask_UDBA;