]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - fs/aufs/opts.c
Btrfs: fix data loss after truncate when using the no-holes feature
[mirror_ubuntu-zesty-kernel.git] / fs / aufs / opts.c
CommitLineData
e14748e8
SF
1/*
2 * Copyright (C) 2005-2016 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/*
19 * mount options/flags
20 */
21
22#include <linux/namei.h>
23#include <linux/types.h> /* a distribution requires */
24#include <linux/parser.h>
25#include "aufs.h"
26
27/* ---------------------------------------------------------------------- */
28
29enum {
30 Opt_br,
31 Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
32 Opt_idel, Opt_imod,
33 Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
34 Opt_rdblk_def, Opt_rdhash_def,
35 Opt_xino, Opt_noxino,
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,
39 Opt_shwh, Opt_noshwh,
40 Opt_plink, Opt_noplink, Opt_list_plink,
41 Opt_udba,
42 Opt_dio, Opt_nodio,
43 Opt_diropq_a, Opt_diropq_w,
44 Opt_warn_perm, Opt_nowarn_perm,
45 Opt_wbr_copyup, Opt_wbr_create,
46 Opt_fhsm_sec,
47 Opt_verbose, Opt_noverbose,
48 Opt_sum, Opt_nosum, Opt_wsum,
49 Opt_dirperm1, Opt_nodirperm1,
50 Opt_acl, Opt_noacl,
51 Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
52};
53
54static match_table_t options = {
55 {Opt_br, "br=%s"},
56 {Opt_br, "br:%s"},
57
58 {Opt_add, "add=%d:%s"},
59 {Opt_add, "add:%d:%s"},
60 {Opt_add, "ins=%d:%s"},
61 {Opt_add, "ins:%d:%s"},
62 {Opt_append, "append=%s"},
63 {Opt_append, "append:%s"},
64 {Opt_prepend, "prepend=%s"},
65 {Opt_prepend, "prepend:%s"},
66
67 {Opt_del, "del=%s"},
68 {Opt_del, "del:%s"},
69 /* {Opt_idel, "idel:%d"}, */
70 {Opt_mod, "mod=%s"},
71 {Opt_mod, "mod:%s"},
72 /* {Opt_imod, "imod:%d:%s"}, */
73
74 {Opt_dirwh, "dirwh=%d"},
75
76 {Opt_xino, "xino=%s"},
77 {Opt_noxino, "noxino"},
78 {Opt_trunc_xino, "trunc_xino"},
79 {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
80 {Opt_notrunc_xino, "notrunc_xino"},
81 {Opt_trunc_xino_path, "trunc_xino=%s"},
82 {Opt_itrunc_xino, "itrunc_xino=%d"},
83 /* {Opt_zxino, "zxino=%s"}, */
84 {Opt_trunc_xib, "trunc_xib"},
85 {Opt_notrunc_xib, "notrunc_xib"},
86
87#ifdef CONFIG_PROC_FS
88 {Opt_plink, "plink"},
89#else
90 {Opt_ignore_silent, "plink"},
91#endif
92
93 {Opt_noplink, "noplink"},
94
95#ifdef CONFIG_AUFS_DEBUG
96 {Opt_list_plink, "list_plink"},
97#endif
98
99 {Opt_udba, "udba=%s"},
100
101 {Opt_dio, "dio"},
102 {Opt_nodio, "nodio"},
103
104#ifdef CONFIG_AUFS_FHSM
105 {Opt_fhsm_sec, "fhsm_sec=%d"},
106#else
107 {Opt_ignore_silent, "fhsm_sec=%d"},
108#endif
109
110 {Opt_diropq_a, "diropq=always"},
111 {Opt_diropq_a, "diropq=a"},
112 {Opt_diropq_w, "diropq=whiteouted"},
113 {Opt_diropq_w, "diropq=w"},
114
115 {Opt_warn_perm, "warn_perm"},
116 {Opt_nowarn_perm, "nowarn_perm"},
117
118 /* keep them temporary */
119 {Opt_ignore_silent, "nodlgt"},
120 {Opt_ignore_silent, "clean_plink"},
121
122#ifdef CONFIG_AUFS_SHWH
123 {Opt_shwh, "shwh"},
124#endif
125 {Opt_noshwh, "noshwh"},
126
127 {Opt_dirperm1, "dirperm1"},
128 {Opt_nodirperm1, "nodirperm1"},
129
130 {Opt_verbose, "verbose"},
131 {Opt_verbose, "v"},
132 {Opt_noverbose, "noverbose"},
133 {Opt_noverbose, "quiet"},
134 {Opt_noverbose, "q"},
135 {Opt_noverbose, "silent"},
136
137 {Opt_sum, "sum"},
138 {Opt_nosum, "nosum"},
139 {Opt_wsum, "wsum"},
140
141 {Opt_rdcache, "rdcache=%d"},
142 {Opt_rdblk, "rdblk=%d"},
143 {Opt_rdblk_def, "rdblk=def"},
144 {Opt_rdhash, "rdhash=%d"},
145 {Opt_rdhash_def, "rdhash=def"},
146
147 {Opt_wbr_create, "create=%s"},
148 {Opt_wbr_create, "create_policy=%s"},
149 {Opt_wbr_copyup, "cpup=%s"},
150 {Opt_wbr_copyup, "copyup=%s"},
151 {Opt_wbr_copyup, "copyup_policy=%s"},
152
153 /* generic VFS flag */
154#ifdef CONFIG_FS_POSIX_ACL
155 {Opt_acl, "acl"},
156 {Opt_noacl, "noacl"},
157#else
158 {Opt_ignore_silent, "acl"},
159 {Opt_ignore_silent, "noacl"},
160#endif
161
162 /* internal use for the scripts */
163 {Opt_ignore_silent, "si=%s"},
164
165 {Opt_br, "dirs=%s"},
166 {Opt_ignore, "debug=%d"},
167 {Opt_ignore, "delete=whiteout"},
168 {Opt_ignore, "delete=all"},
169 {Opt_ignore, "imap=%s"},
170
171 /* temporary workaround, due to old mount(8)? */
172 {Opt_ignore_silent, "relatime"},
173
174 {Opt_err, NULL}
175};
176
177/* ---------------------------------------------------------------------- */
178
179static const char *au_parser_pattern(int val, match_table_t tbl)
180{
181 struct match_token *p;
182
183 p = tbl;
184 while (p->pattern) {
185 if (p->token == val)
186 return p->pattern;
187 p++;
188 }
189 BUG();
190 return "??";
191}
192
193static const char *au_optstr(int *val, match_table_t tbl)
194{
195 struct match_token *p;
196 int v;
197
198 v = *val;
199 if (!v)
200 goto out;
201 p = tbl;
202 while (p->pattern) {
203 if (p->token
204 && (v & p->token) == p->token) {
205 *val &= ~p->token;
206 return p->pattern;
207 }
208 p++;
209 }
210
211out:
212 return NULL;
213}
214
215/* ---------------------------------------------------------------------- */
216
217static match_table_t brperm = {
218 {AuBrPerm_RO, AUFS_BRPERM_RO},
219 {AuBrPerm_RR, AUFS_BRPERM_RR},
220 {AuBrPerm_RW, AUFS_BRPERM_RW},
221 {0, NULL}
222};
223
224static match_table_t brattr = {
225 /* general */
226 {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
227 {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
228 /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
229 {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
230#ifdef CONFIG_AUFS_FHSM
231 {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
232#endif
233#ifdef CONFIG_AUFS_XATTR
234 {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
235 {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
236 {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
237 {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
238 {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
239 {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
240#endif
241
242 /* ro/rr branch */
243 {AuBrRAttr_WH, AUFS_BRRATTR_WH},
244
245 /* rw branch */
246 {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
247 {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
248
249 {0, NULL}
250};
251
252static int br_attr_val(char *str, match_table_t table, substring_t args[])
253{
254 int attr, v;
255 char *p;
256
257 attr = 0;
258 do {
259 p = strchr(str, '+');
260 if (p)
261 *p = 0;
262 v = match_token(str, table, args);
263 if (v) {
264 if (v & AuBrAttr_CMOO_Mask)
265 attr &= ~AuBrAttr_CMOO_Mask;
266 attr |= v;
267 } else {
268 if (p)
269 *p = '+';
270 pr_warn("ignored branch attribute %s\n", str);
271 break;
272 }
273 if (p)
274 str = p + 1;
275 } while (p);
276
277 return attr;
278}
279
280static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
281{
282 int sz;
283 const char *p;
284 char *q;
285
286 q = str->a;
287 *q = 0;
288 p = au_optstr(&perm, brattr);
289 if (p) {
290 sz = strlen(p);
291 memcpy(q, p, sz + 1);
292 q += sz;
293 } else
294 goto out;
295
296 do {
297 p = au_optstr(&perm, brattr);
298 if (p) {
299 *q++ = '+';
300 sz = strlen(p);
301 memcpy(q, p, sz + 1);
302 q += sz;
303 }
304 } while (p);
305
306out:
307 return q - str->a;
308}
309
310static int noinline_for_stack br_perm_val(char *perm)
311{
312 int val, bad, sz;
313 char *p;
314 substring_t args[MAX_OPT_ARGS];
315 au_br_perm_str_t attr;
316
317 p = strchr(perm, '+');
318 if (p)
319 *p = 0;
320 val = match_token(perm, brperm, args);
321 if (!val) {
322 if (p)
323 *p = '+';
324 pr_warn("ignored branch permission %s\n", perm);
325 val = AuBrPerm_RO;
326 goto out;
327 }
328 if (!p)
329 goto out;
330
331 val |= br_attr_val(p + 1, brattr, args);
332
333 bad = 0;
334 switch (val & AuBrPerm_Mask) {
335 case AuBrPerm_RO:
336 case AuBrPerm_RR:
337 bad = val & AuBrWAttr_Mask;
338 val &= ~AuBrWAttr_Mask;
339 break;
340 case AuBrPerm_RW:
341 bad = val & AuBrRAttr_Mask;
342 val &= ~AuBrRAttr_Mask;
343 break;
344 }
345
346 /*
347 * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
348 * does not treat it as an error, just warning.
349 * this is a tiny guard for the user operation.
350 */
351 if (val & AuBrAttr_UNPIN) {
352 bad |= AuBrAttr_UNPIN;
353 val &= ~AuBrAttr_UNPIN;
354 }
355
356 if (unlikely(bad)) {
357 sz = au_do_optstr_br_attr(&attr, bad);
358 AuDebugOn(!sz);
359 pr_warn("ignored branch attribute %s\n", attr.a);
360 }
361
362out:
363 return val;
364}
365
366void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
367{
368 au_br_perm_str_t attr;
369 const char *p;
370 char *q;
371 int sz;
372
373 q = str->a;
374 p = au_optstr(&perm, brperm);
375 AuDebugOn(!p || !*p);
376 sz = strlen(p);
377 memcpy(q, p, sz + 1);
378 q += sz;
379
380 sz = au_do_optstr_br_attr(&attr, perm);
381 if (sz) {
382 *q++ = '+';
383 memcpy(q, attr.a, sz + 1);
384 }
385
386 AuDebugOn(strlen(str->a) >= sizeof(str->a));
387}
388
389/* ---------------------------------------------------------------------- */
390
391static match_table_t udbalevel = {
392 {AuOpt_UDBA_REVAL, "reval"},
393 {AuOpt_UDBA_NONE, "none"},
394#ifdef CONFIG_AUFS_HNOTIFY
395 {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
396#ifdef CONFIG_AUFS_HFSNOTIFY
397 {AuOpt_UDBA_HNOTIFY, "fsnotify"},
398#endif
399#endif
400 {-1, NULL}
401};
402
403static int noinline_for_stack udba_val(char *str)
404{
405 substring_t args[MAX_OPT_ARGS];
406
407 return match_token(str, udbalevel, args);
408}
409
410const char *au_optstr_udba(int udba)
411{
412 return au_parser_pattern(udba, udbalevel);
413}
414
415/* ---------------------------------------------------------------------- */
416
417static match_table_t au_wbr_create_policy = {
418 {AuWbrCreate_TDP, "tdp"},
419 {AuWbrCreate_TDP, "top-down-parent"},
420 {AuWbrCreate_RR, "rr"},
421 {AuWbrCreate_RR, "round-robin"},
422 {AuWbrCreate_MFS, "mfs"},
423 {AuWbrCreate_MFS, "most-free-space"},
424 {AuWbrCreate_MFSV, "mfs:%d"},
425 {AuWbrCreate_MFSV, "most-free-space:%d"},
426
427 /* top-down regardless the parent, and then mfs */
428 {AuWbrCreate_TDMFS, "tdmfs:%d"},
429 {AuWbrCreate_TDMFSV, "tdmfs:%d:%d"},
430
431 {AuWbrCreate_MFSRR, "mfsrr:%d"},
432 {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
433 {AuWbrCreate_PMFS, "pmfs"},
434 {AuWbrCreate_PMFSV, "pmfs:%d"},
435 {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
436 {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
437
438 {-1, NULL}
439};
440
441static int au_wbr_mfs_wmark(substring_t *arg, char *str,
442 struct au_opt_wbr_create *create)
443{
444 int err;
445 unsigned long long ull;
446
447 err = 0;
448 if (!match_u64(arg, &ull))
449 create->mfsrr_watermark = ull;
450 else {
451 pr_err("bad integer in %s\n", str);
452 err = -EINVAL;
453 }
454
455 return err;
456}
457
458static int au_wbr_mfs_sec(substring_t *arg, char *str,
459 struct au_opt_wbr_create *create)
460{
461 int n, err;
462
463 err = 0;
464 if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
465 create->mfs_second = n;
466 else {
467 pr_err("bad integer in %s\n", str);
468 err = -EINVAL;
469 }
470
471 return err;
472}
473
474static int noinline_for_stack
475au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
476{
477 int err, e;
478 substring_t args[MAX_OPT_ARGS];
479
480 err = match_token(str, au_wbr_create_policy, args);
481 create->wbr_create = err;
482 switch (err) {
483 case AuWbrCreate_MFSRRV:
484 case AuWbrCreate_TDMFSV:
485 case AuWbrCreate_PMFSRRV:
486 e = au_wbr_mfs_wmark(&args[0], str, create);
487 if (!e)
488 e = au_wbr_mfs_sec(&args[1], str, create);
489 if (unlikely(e))
490 err = e;
491 break;
492 case AuWbrCreate_MFSRR:
493 case AuWbrCreate_TDMFS:
494 case AuWbrCreate_PMFSRR:
495 e = au_wbr_mfs_wmark(&args[0], str, create);
496 if (unlikely(e)) {
497 err = e;
498 break;
499 }
500 /*FALLTHROUGH*/
501 case AuWbrCreate_MFS:
502 case AuWbrCreate_PMFS:
503 create->mfs_second = AUFS_MFS_DEF_SEC;
504 break;
505 case AuWbrCreate_MFSV:
506 case AuWbrCreate_PMFSV:
507 e = au_wbr_mfs_sec(&args[0], str, create);
508 if (unlikely(e))
509 err = e;
510 break;
511 }
512
513 return err;
514}
515
516const char *au_optstr_wbr_create(int wbr_create)
517{
518 return au_parser_pattern(wbr_create, au_wbr_create_policy);
519}
520
521static match_table_t au_wbr_copyup_policy = {
522 {AuWbrCopyup_TDP, "tdp"},
523 {AuWbrCopyup_TDP, "top-down-parent"},
524 {AuWbrCopyup_BUP, "bup"},
525 {AuWbrCopyup_BUP, "bottom-up-parent"},
526 {AuWbrCopyup_BU, "bu"},
527 {AuWbrCopyup_BU, "bottom-up"},
528 {-1, NULL}
529};
530
531static int noinline_for_stack au_wbr_copyup_val(char *str)
532{
533 substring_t args[MAX_OPT_ARGS];
534
535 return match_token(str, au_wbr_copyup_policy, args);
536}
537
538const char *au_optstr_wbr_copyup(int wbr_copyup)
539{
540 return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
541}
542
543/* ---------------------------------------------------------------------- */
544
545static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
546
547static void dump_opts(struct au_opts *opts)
548{
549#ifdef CONFIG_AUFS_DEBUG
550 /* reduce stack space */
551 union {
552 struct au_opt_add *add;
553 struct au_opt_del *del;
554 struct au_opt_mod *mod;
555 struct au_opt_xino *xino;
556 struct au_opt_xino_itrunc *xino_itrunc;
557 struct au_opt_wbr_create *create;
558 } u;
559 struct au_opt *opt;
560
561 opt = opts->opt;
562 while (opt->type != Opt_tail) {
563 switch (opt->type) {
564 case Opt_add:
565 u.add = &opt->add;
566 AuDbg("add {b%d, %s, 0x%x, %p}\n",
567 u.add->bindex, u.add->pathname, u.add->perm,
568 u.add->path.dentry);
569 break;
570 case Opt_del:
571 case Opt_idel:
572 u.del = &opt->del;
573 AuDbg("del {%s, %p}\n",
574 u.del->pathname, u.del->h_path.dentry);
575 break;
576 case Opt_mod:
577 case Opt_imod:
578 u.mod = &opt->mod;
579 AuDbg("mod {%s, 0x%x, %p}\n",
580 u.mod->path, u.mod->perm, u.mod->h_root);
581 break;
582 case Opt_append:
583 u.add = &opt->add;
584 AuDbg("append {b%d, %s, 0x%x, %p}\n",
585 u.add->bindex, u.add->pathname, u.add->perm,
586 u.add->path.dentry);
587 break;
588 case Opt_prepend:
589 u.add = &opt->add;
590 AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
591 u.add->bindex, u.add->pathname, u.add->perm,
592 u.add->path.dentry);
593 break;
594 case Opt_dirwh:
595 AuDbg("dirwh %d\n", opt->dirwh);
596 break;
597 case Opt_rdcache:
598 AuDbg("rdcache %d\n", opt->rdcache);
599 break;
600 case Opt_rdblk:
601 AuDbg("rdblk %u\n", opt->rdblk);
602 break;
603 case Opt_rdblk_def:
604 AuDbg("rdblk_def\n");
605 break;
606 case Opt_rdhash:
607 AuDbg("rdhash %u\n", opt->rdhash);
608 break;
609 case Opt_rdhash_def:
610 AuDbg("rdhash_def\n");
611 break;
612 case Opt_xino:
613 u.xino = &opt->xino;
614 AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
615 break;
616 case Opt_trunc_xino:
617 AuLabel(trunc_xino);
618 break;
619 case Opt_notrunc_xino:
620 AuLabel(notrunc_xino);
621 break;
622 case Opt_trunc_xino_path:
623 case Opt_itrunc_xino:
624 u.xino_itrunc = &opt->xino_itrunc;
625 AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
626 break;
627 case Opt_noxino:
628 AuLabel(noxino);
629 break;
630 case Opt_trunc_xib:
631 AuLabel(trunc_xib);
632 break;
633 case Opt_notrunc_xib:
634 AuLabel(notrunc_xib);
635 break;
636 case Opt_shwh:
637 AuLabel(shwh);
638 break;
639 case Opt_noshwh:
640 AuLabel(noshwh);
641 break;
642 case Opt_dirperm1:
643 AuLabel(dirperm1);
644 break;
645 case Opt_nodirperm1:
646 AuLabel(nodirperm1);
647 break;
648 case Opt_plink:
649 AuLabel(plink);
650 break;
651 case Opt_noplink:
652 AuLabel(noplink);
653 break;
654 case Opt_list_plink:
655 AuLabel(list_plink);
656 break;
657 case Opt_udba:
658 AuDbg("udba %d, %s\n",
659 opt->udba, au_optstr_udba(opt->udba));
660 break;
661 case Opt_dio:
662 AuLabel(dio);
663 break;
664 case Opt_nodio:
665 AuLabel(nodio);
666 break;
667 case Opt_diropq_a:
668 AuLabel(diropq_a);
669 break;
670 case Opt_diropq_w:
671 AuLabel(diropq_w);
672 break;
673 case Opt_warn_perm:
674 AuLabel(warn_perm);
675 break;
676 case Opt_nowarn_perm:
677 AuLabel(nowarn_perm);
678 break;
679 case Opt_verbose:
680 AuLabel(verbose);
681 break;
682 case Opt_noverbose:
683 AuLabel(noverbose);
684 break;
685 case Opt_sum:
686 AuLabel(sum);
687 break;
688 case Opt_nosum:
689 AuLabel(nosum);
690 break;
691 case Opt_wsum:
692 AuLabel(wsum);
693 break;
694 case Opt_wbr_create:
695 u.create = &opt->wbr_create;
696 AuDbg("create %d, %s\n", u.create->wbr_create,
697 au_optstr_wbr_create(u.create->wbr_create));
698 switch (u.create->wbr_create) {
699 case AuWbrCreate_MFSV:
700 case AuWbrCreate_PMFSV:
701 AuDbg("%d sec\n", u.create->mfs_second);
702 break;
703 case AuWbrCreate_MFSRR:
704 case AuWbrCreate_TDMFS:
705 AuDbg("%llu watermark\n",
706 u.create->mfsrr_watermark);
707 break;
708 case AuWbrCreate_MFSRRV:
709 case AuWbrCreate_TDMFSV:
710 case AuWbrCreate_PMFSRRV:
711 AuDbg("%llu watermark, %d sec\n",
712 u.create->mfsrr_watermark,
713 u.create->mfs_second);
714 break;
715 }
716 break;
717 case Opt_wbr_copyup:
718 AuDbg("copyup %d, %s\n", opt->wbr_copyup,
719 au_optstr_wbr_copyup(opt->wbr_copyup));
720 break;
721 case Opt_fhsm_sec:
722 AuDbg("fhsm_sec %u\n", opt->fhsm_second);
723 break;
724 case Opt_acl:
725 AuLabel(acl);
726 break;
727 case Opt_noacl:
728 AuLabel(noacl);
729 break;
730 default:
731 BUG();
732 }
733 opt++;
734 }
735#endif
736}
737
738void au_opts_free(struct au_opts *opts)
739{
740 struct au_opt *opt;
741
742 opt = opts->opt;
743 while (opt->type != Opt_tail) {
744 switch (opt->type) {
745 case Opt_add:
746 case Opt_append:
747 case Opt_prepend:
748 path_put(&opt->add.path);
749 break;
750 case Opt_del:
751 case Opt_idel:
752 path_put(&opt->del.h_path);
753 break;
754 case Opt_mod:
755 case Opt_imod:
756 dput(opt->mod.h_root);
757 break;
758 case Opt_xino:
759 fput(opt->xino.file);
760 break;
761 }
762 opt++;
763 }
764}
765
766static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
767 aufs_bindex_t bindex)
768{
769 int err;
770 struct au_opt_add *add = &opt->add;
771 char *p;
772
773 add->bindex = bindex;
774 add->perm = AuBrPerm_RO;
775 add->pathname = opt_str;
776 p = strchr(opt_str, '=');
777 if (p) {
778 *p++ = 0;
779 if (*p)
780 add->perm = br_perm_val(p);
781 }
782
783 err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
784 if (!err) {
785 if (!p) {
786 add->perm = AuBrPerm_RO;
787 if (au_test_fs_rr(add->path.dentry->d_sb))
788 add->perm = AuBrPerm_RR;
789 else if (!bindex && !(sb_flags & MS_RDONLY))
790 add->perm = AuBrPerm_RW;
791 }
792 opt->type = Opt_add;
793 goto out;
794 }
795 pr_err("lookup failed %s (%d)\n", add->pathname, err);
796 err = -EINVAL;
797
798out:
799 return err;
800}
801
802static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
803{
804 int err;
805
806 del->pathname = args[0].from;
807 AuDbg("del path %s\n", del->pathname);
808
809 err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
810 if (unlikely(err))
811 pr_err("lookup failed %s (%d)\n", del->pathname, err);
812
813 return err;
814}
815
816#if 0 /* reserved for future use */
817static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
818 struct au_opt_del *del, substring_t args[])
819{
820 int err;
821 struct dentry *root;
822
823 err = -EINVAL;
824 root = sb->s_root;
825 aufs_read_lock(root, AuLock_FLUSH);
826 if (bindex < 0 || au_sbbot(sb) < bindex) {
827 pr_err("out of bounds, %d\n", bindex);
828 goto out;
829 }
830
831 err = 0;
832 del->h_path.dentry = dget(au_h_dptr(root, bindex));
833 del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
834
835out:
836 aufs_read_unlock(root, !AuLock_IR);
837 return err;
838}
839#endif
840
841static int noinline_for_stack
842au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
843{
844 int err;
845 struct path path;
846 char *p;
847
848 err = -EINVAL;
849 mod->path = args[0].from;
850 p = strchr(mod->path, '=');
851 if (unlikely(!p)) {
852 pr_err("no permssion %s\n", args[0].from);
853 goto out;
854 }
855
856 *p++ = 0;
857 err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
858 if (unlikely(err)) {
859 pr_err("lookup failed %s (%d)\n", mod->path, err);
860 goto out;
861 }
862
863 mod->perm = br_perm_val(p);
864 AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
865 mod->h_root = dget(path.dentry);
866 path_put(&path);
867
868out:
869 return err;
870}
871
872#if 0 /* reserved for future use */
873static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
874 struct au_opt_mod *mod, substring_t args[])
875{
876 int err;
877 struct dentry *root;
878
879 err = -EINVAL;
880 root = sb->s_root;
881 aufs_read_lock(root, AuLock_FLUSH);
882 if (bindex < 0 || au_sbbot(sb) < bindex) {
883 pr_err("out of bounds, %d\n", bindex);
884 goto out;
885 }
886
887 err = 0;
888 mod->perm = br_perm_val(args[1].from);
889 AuDbg("mod path %s, perm 0x%x, %s\n",
890 mod->path, mod->perm, args[1].from);
891 mod->h_root = dget(au_h_dptr(root, bindex));
892
893out:
894 aufs_read_unlock(root, !AuLock_IR);
895 return err;
896}
897#endif
898
899static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
900 substring_t args[])
901{
902 int err;
903 struct file *file;
904
905 file = au_xino_create(sb, args[0].from, /*silent*/0);
906 err = PTR_ERR(file);
907 if (IS_ERR(file))
908 goto out;
909
910 err = -EINVAL;
911 if (unlikely(file->f_path.dentry->d_sb == sb)) {
912 fput(file);
913 pr_err("%s must be outside\n", args[0].from);
914 goto out;
915 }
916
917 err = 0;
918 xino->file = file;
919 xino->path = args[0].from;
920
921out:
922 return err;
923}
924
925static int noinline_for_stack
926au_opts_parse_xino_itrunc_path(struct super_block *sb,
927 struct au_opt_xino_itrunc *xino_itrunc,
928 substring_t args[])
929{
930 int err;
931 aufs_bindex_t bbot, bindex;
932 struct path path;
933 struct dentry *root;
934
935 err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
936 if (unlikely(err)) {
937 pr_err("lookup failed %s (%d)\n", args[0].from, err);
938 goto out;
939 }
940
941 xino_itrunc->bindex = -1;
942 root = sb->s_root;
943 aufs_read_lock(root, AuLock_FLUSH);
944 bbot = au_sbbot(sb);
945 for (bindex = 0; bindex <= bbot; bindex++) {
946 if (au_h_dptr(root, bindex) == path.dentry) {
947 xino_itrunc->bindex = bindex;
948 break;
949 }
950 }
951 aufs_read_unlock(root, !AuLock_IR);
952 path_put(&path);
953
954 if (unlikely(xino_itrunc->bindex < 0)) {
955 pr_err("no such branch %s\n", args[0].from);
956 err = -EINVAL;
957 }
958
959out:
960 return err;
961}
962
963/* called without aufs lock */
964int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
965{
966 int err, n, token;
967 aufs_bindex_t bindex;
968 unsigned char skipped;
969 struct dentry *root;
970 struct au_opt *opt, *opt_tail;
971 char *opt_str;
972 /* reduce the stack space */
973 union {
974 struct au_opt_xino_itrunc *xino_itrunc;
975 struct au_opt_wbr_create *create;
976 } u;
977 struct {
978 substring_t args[MAX_OPT_ARGS];
979 } *a;
980
981 err = -ENOMEM;
982 a = kmalloc(sizeof(*a), GFP_NOFS);
983 if (unlikely(!a))
984 goto out;
985
986 root = sb->s_root;
987 err = 0;
988 bindex = 0;
989 opt = opts->opt;
990 opt_tail = opt + opts->max_opt - 1;
991 opt->type = Opt_tail;
992 while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
993 err = -EINVAL;
994 skipped = 0;
995 token = match_token(opt_str, options, a->args);
996 switch (token) {
997 case Opt_br:
998 err = 0;
999 while (!err && (opt_str = strsep(&a->args[0].from, ":"))
1000 && *opt_str) {
1001 err = opt_add(opt, opt_str, opts->sb_flags,
1002 bindex++);
1003 if (unlikely(!err && ++opt > opt_tail)) {
1004 err = -E2BIG;
1005 break;
1006 }
1007 opt->type = Opt_tail;
1008 skipped = 1;
1009 }
1010 break;
1011 case Opt_add:
1012 if (unlikely(match_int(&a->args[0], &n))) {
1013 pr_err("bad integer in %s\n", opt_str);
1014 break;
1015 }
1016 bindex = n;
1017 err = opt_add(opt, a->args[1].from, opts->sb_flags,
1018 bindex);
1019 if (!err)
1020 opt->type = token;
1021 break;
1022 case Opt_append:
1023 err = opt_add(opt, a->args[0].from, opts->sb_flags,
1024 /*dummy bindex*/1);
1025 if (!err)
1026 opt->type = token;
1027 break;
1028 case Opt_prepend:
1029 err = opt_add(opt, a->args[0].from, opts->sb_flags,
1030 /*bindex*/0);
1031 if (!err)
1032 opt->type = token;
1033 break;
1034 case Opt_del:
1035 err = au_opts_parse_del(&opt->del, a->args);
1036 if (!err)
1037 opt->type = token;
1038 break;
1039#if 0 /* reserved for future use */
1040 case Opt_idel:
1041 del->pathname = "(indexed)";
1042 if (unlikely(match_int(&args[0], &n))) {
1043 pr_err("bad integer in %s\n", opt_str);
1044 break;
1045 }
1046 err = au_opts_parse_idel(sb, n, &opt->del, a->args);
1047 if (!err)
1048 opt->type = token;
1049 break;
1050#endif
1051 case Opt_mod:
1052 err = au_opts_parse_mod(&opt->mod, a->args);
1053 if (!err)
1054 opt->type = token;
1055 break;
1056#ifdef IMOD /* reserved for future use */
1057 case Opt_imod:
1058 u.mod->path = "(indexed)";
1059 if (unlikely(match_int(&a->args[0], &n))) {
1060 pr_err("bad integer in %s\n", opt_str);
1061 break;
1062 }
1063 err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
1064 if (!err)
1065 opt->type = token;
1066 break;
1067#endif
1068 case Opt_xino:
1069 err = au_opts_parse_xino(sb, &opt->xino, a->args);
1070 if (!err)
1071 opt->type = token;
1072 break;
1073
1074 case Opt_trunc_xino_path:
1075 err = au_opts_parse_xino_itrunc_path
1076 (sb, &opt->xino_itrunc, a->args);
1077 if (!err)
1078 opt->type = token;
1079 break;
1080
1081 case Opt_itrunc_xino:
1082 u.xino_itrunc = &opt->xino_itrunc;
1083 if (unlikely(match_int(&a->args[0], &n))) {
1084 pr_err("bad integer in %s\n", opt_str);
1085 break;
1086 }
1087 u.xino_itrunc->bindex = n;
1088 aufs_read_lock(root, AuLock_FLUSH);
1089 if (n < 0 || au_sbbot(sb) < n) {
1090 pr_err("out of bounds, %d\n", n);
1091 aufs_read_unlock(root, !AuLock_IR);
1092 break;
1093 }
1094 aufs_read_unlock(root, !AuLock_IR);
1095 err = 0;
1096 opt->type = token;
1097 break;
1098
1099 case Opt_dirwh:
1100 if (unlikely(match_int(&a->args[0], &opt->dirwh)))
1101 break;
1102 err = 0;
1103 opt->type = token;
1104 break;
1105
1106 case Opt_rdcache:
1107 if (unlikely(match_int(&a->args[0], &n))) {
1108 pr_err("bad integer in %s\n", opt_str);
1109 break;
1110 }
1111 if (unlikely(n > AUFS_RDCACHE_MAX)) {
1112 pr_err("rdcache must be smaller than %d\n",
1113 AUFS_RDCACHE_MAX);
1114 break;
1115 }
1116 opt->rdcache = n;
1117 err = 0;
1118 opt->type = token;
1119 break;
1120 case Opt_rdblk:
1121 if (unlikely(match_int(&a->args[0], &n)
1122 || n < 0
1123 || n > KMALLOC_MAX_SIZE)) {
1124 pr_err("bad integer in %s\n", opt_str);
1125 break;
1126 }
1127 if (unlikely(n && n < NAME_MAX)) {
1128 pr_err("rdblk must be larger than %d\n",
1129 NAME_MAX);
1130 break;
1131 }
1132 opt->rdblk = n;
1133 err = 0;
1134 opt->type = token;
1135 break;
1136 case Opt_rdhash:
1137 if (unlikely(match_int(&a->args[0], &n)
1138 || n < 0
1139 || n * sizeof(struct hlist_head)
1140 > KMALLOC_MAX_SIZE)) {
1141 pr_err("bad integer in %s\n", opt_str);
1142 break;
1143 }
1144 opt->rdhash = n;
1145 err = 0;
1146 opt->type = token;
1147 break;
1148
1149 case Opt_trunc_xino:
1150 case Opt_notrunc_xino:
1151 case Opt_noxino:
1152 case Opt_trunc_xib:
1153 case Opt_notrunc_xib:
1154 case Opt_shwh:
1155 case Opt_noshwh:
1156 case Opt_dirperm1:
1157 case Opt_nodirperm1:
1158 case Opt_plink:
1159 case Opt_noplink:
1160 case Opt_list_plink:
1161 case Opt_dio:
1162 case Opt_nodio:
1163 case Opt_diropq_a:
1164 case Opt_diropq_w:
1165 case Opt_warn_perm:
1166 case Opt_nowarn_perm:
1167 case Opt_verbose:
1168 case Opt_noverbose:
1169 case Opt_sum:
1170 case Opt_nosum:
1171 case Opt_wsum:
1172 case Opt_rdblk_def:
1173 case Opt_rdhash_def:
1174 case Opt_acl:
1175 case Opt_noacl:
1176 err = 0;
1177 opt->type = token;
1178 break;
1179
1180 case Opt_udba:
1181 opt->udba = udba_val(a->args[0].from);
1182 if (opt->udba >= 0) {
1183 err = 0;
1184 opt->type = token;
1185 } else
1186 pr_err("wrong value, %s\n", opt_str);
1187 break;
1188
1189 case Opt_wbr_create:
1190 u.create = &opt->wbr_create;
1191 u.create->wbr_create
1192 = au_wbr_create_val(a->args[0].from, u.create);
1193 if (u.create->wbr_create >= 0) {
1194 err = 0;
1195 opt->type = token;
1196 } else
1197 pr_err("wrong value, %s\n", opt_str);
1198 break;
1199 case Opt_wbr_copyup:
1200 opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
1201 if (opt->wbr_copyup >= 0) {
1202 err = 0;
1203 opt->type = token;
1204 } else
1205 pr_err("wrong value, %s\n", opt_str);
1206 break;
1207
1208 case Opt_fhsm_sec:
1209 if (unlikely(match_int(&a->args[0], &n)
1210 || n < 0)) {
1211 pr_err("bad integer in %s\n", opt_str);
1212 break;
1213 }
1214 if (sysaufs_brs) {
1215 opt->fhsm_second = n;
1216 opt->type = token;
1217 } else
1218 pr_warn("ignored %s\n", opt_str);
1219 err = 0;
1220 break;
1221
1222 case Opt_ignore:
1223 pr_warn("ignored %s\n", opt_str);
1224 /*FALLTHROUGH*/
1225 case Opt_ignore_silent:
1226 skipped = 1;
1227 err = 0;
1228 break;
1229 case Opt_err:
1230 pr_err("unknown option %s\n", opt_str);
1231 break;
1232 }
1233
1234 if (!err && !skipped) {
1235 if (unlikely(++opt > opt_tail)) {
1236 err = -E2BIG;
1237 opt--;
1238 opt->type = Opt_tail;
1239 break;
1240 }
1241 opt->type = Opt_tail;
1242 }
1243 }
1244
1245 au_delayed_kfree(a);
1246 dump_opts(opts);
1247 if (unlikely(err))
1248 au_opts_free(opts);
1249
1250out:
1251 return err;
1252}
1253
1254static int au_opt_wbr_create(struct super_block *sb,
1255 struct au_opt_wbr_create *create)
1256{
1257 int err;
1258 struct au_sbinfo *sbinfo;
1259
1260 SiMustWriteLock(sb);
1261
1262 err = 1; /* handled */
1263 sbinfo = au_sbi(sb);
1264 if (sbinfo->si_wbr_create_ops->fin) {
1265 err = sbinfo->si_wbr_create_ops->fin(sb);
1266 if (!err)
1267 err = 1;
1268 }
1269
1270 sbinfo->si_wbr_create = create->wbr_create;
1271 sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
1272 switch (create->wbr_create) {
1273 case AuWbrCreate_MFSRRV:
1274 case AuWbrCreate_MFSRR:
1275 case AuWbrCreate_TDMFS:
1276 case AuWbrCreate_TDMFSV:
1277 case AuWbrCreate_PMFSRR:
1278 case AuWbrCreate_PMFSRRV:
1279 sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
1280 /*FALLTHROUGH*/
1281 case AuWbrCreate_MFS:
1282 case AuWbrCreate_MFSV:
1283 case AuWbrCreate_PMFS:
1284 case AuWbrCreate_PMFSV:
1285 sbinfo->si_wbr_mfs.mfs_expire
1286 = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1287 break;
1288 }
1289
1290 if (sbinfo->si_wbr_create_ops->init)
1291 sbinfo->si_wbr_create_ops->init(sb); /* ignore */
1292
1293 return err;
1294}
1295
1296/*
1297 * returns,
1298 * plus: processed without an error
1299 * zero: unprocessed
1300 */
1301static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
1302 struct au_opts *opts)
1303{
1304 int err;
1305 struct au_sbinfo *sbinfo;
1306
1307 SiMustWriteLock(sb);
1308
1309 err = 1; /* handled */
1310 sbinfo = au_sbi(sb);
1311 switch (opt->type) {
1312 case Opt_udba:
1313 sbinfo->si_mntflags &= ~AuOptMask_UDBA;
1314 sbinfo->si_mntflags |= opt->udba;
1315 opts->given_udba |= opt->udba;
1316 break;
1317
1318 case Opt_plink:
1319 au_opt_set(sbinfo->si_mntflags, PLINK);
1320 break;
1321 case Opt_noplink:
1322 if (au_opt_test(sbinfo->si_mntflags, PLINK))
1323 au_plink_put(sb, /*verbose*/1);
1324 au_opt_clr(sbinfo->si_mntflags, PLINK);
1325 break;
1326 case Opt_list_plink:
1327 if (au_opt_test(sbinfo->si_mntflags, PLINK))
1328 au_plink_list(sb);
1329 break;
1330
1331 case Opt_dio:
1332 au_opt_set(sbinfo->si_mntflags, DIO);
1333 au_fset_opts(opts->flags, REFRESH_DYAOP);
1334 break;
1335 case Opt_nodio:
1336 au_opt_clr(sbinfo->si_mntflags, DIO);
1337 au_fset_opts(opts->flags, REFRESH_DYAOP);
1338 break;
1339
1340 case Opt_fhsm_sec:
1341 au_fhsm_set(sbinfo, opt->fhsm_second);
1342 break;
1343
1344 case Opt_diropq_a:
1345 au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
1346 break;
1347 case Opt_diropq_w:
1348 au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
1349 break;
1350
1351 case Opt_warn_perm:
1352 au_opt_set(sbinfo->si_mntflags, WARN_PERM);
1353 break;
1354 case Opt_nowarn_perm:
1355 au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
1356 break;
1357
1358 case Opt_verbose:
1359 au_opt_set(sbinfo->si_mntflags, VERBOSE);
1360 break;
1361 case Opt_noverbose:
1362 au_opt_clr(sbinfo->si_mntflags, VERBOSE);
1363 break;
1364
1365 case Opt_sum:
1366 au_opt_set(sbinfo->si_mntflags, SUM);
1367 break;
1368 case Opt_wsum:
1369 au_opt_clr(sbinfo->si_mntflags, SUM);
1370 au_opt_set(sbinfo->si_mntflags, SUM_W);
1371 case Opt_nosum:
1372 au_opt_clr(sbinfo->si_mntflags, SUM);
1373 au_opt_clr(sbinfo->si_mntflags, SUM_W);
1374 break;
1375
1376 case Opt_wbr_create:
1377 err = au_opt_wbr_create(sb, &opt->wbr_create);
1378 break;
1379 case Opt_wbr_copyup:
1380 sbinfo->si_wbr_copyup = opt->wbr_copyup;
1381 sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
1382 break;
1383
1384 case Opt_dirwh:
1385 sbinfo->si_dirwh = opt->dirwh;
1386 break;
1387
1388 case Opt_rdcache:
1389 sbinfo->si_rdcache
1390 = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1391 break;
1392 case Opt_rdblk:
1393 sbinfo->si_rdblk = opt->rdblk;
1394 break;
1395 case Opt_rdblk_def:
1396 sbinfo->si_rdblk = AUFS_RDBLK_DEF;
1397 break;
1398 case Opt_rdhash:
1399 sbinfo->si_rdhash = opt->rdhash;
1400 break;
1401 case Opt_rdhash_def:
1402 sbinfo->si_rdhash = AUFS_RDHASH_DEF;
1403 break;
1404
1405 case Opt_shwh:
1406 au_opt_set(sbinfo->si_mntflags, SHWH);
1407 break;
1408 case Opt_noshwh:
1409 au_opt_clr(sbinfo->si_mntflags, SHWH);
1410 break;
1411
1412 case Opt_dirperm1:
1413 au_opt_set(sbinfo->si_mntflags, DIRPERM1);
1414 break;
1415 case Opt_nodirperm1:
1416 au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
1417 break;
1418
1419 case Opt_trunc_xino:
1420 au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
1421 break;
1422 case Opt_notrunc_xino:
1423 au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
1424 break;
1425
1426 case Opt_trunc_xino_path:
1427 case Opt_itrunc_xino:
1428 err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
1429 if (!err)
1430 err = 1;
1431 break;
1432
1433 case Opt_trunc_xib:
1434 au_fset_opts(opts->flags, TRUNC_XIB);
1435 break;
1436 case Opt_notrunc_xib:
1437 au_fclr_opts(opts->flags, TRUNC_XIB);
1438 break;
1439
1440 case Opt_acl:
1441 sb->s_flags |= MS_POSIXACL;
1442 break;
1443 case Opt_noacl:
1444 sb->s_flags &= ~MS_POSIXACL;
1445 break;
1446
1447 default:
1448 err = 0;
1449 break;
1450 }
1451
1452 return err;
1453}
1454
1455/*
1456 * returns tri-state.
1457 * plus: processed without an error
1458 * zero: unprocessed
1459 * minus: error
1460 */
1461static int au_opt_br(struct super_block *sb, struct au_opt *opt,
1462 struct au_opts *opts)
1463{
1464 int err, do_refresh;
1465
1466 err = 0;
1467 switch (opt->type) {
1468 case Opt_append:
1469 opt->add.bindex = au_sbbot(sb) + 1;
1470 if (opt->add.bindex < 0)
1471 opt->add.bindex = 0;
1472 goto add;
1473 case Opt_prepend:
1474 opt->add.bindex = 0;
1475 add: /* indented label */
1476 case Opt_add:
1477 err = au_br_add(sb, &opt->add,
1478 au_ftest_opts(opts->flags, REMOUNT));
1479 if (!err) {
1480 err = 1;
1481 au_fset_opts(opts->flags, REFRESH);
1482 }
1483 break;
1484
1485 case Opt_del:
1486 case Opt_idel:
1487 err = au_br_del(sb, &opt->del,
1488 au_ftest_opts(opts->flags, REMOUNT));
1489 if (!err) {
1490 err = 1;
1491 au_fset_opts(opts->flags, TRUNC_XIB);
1492 au_fset_opts(opts->flags, REFRESH);
1493 }
1494 break;
1495
1496 case Opt_mod:
1497 case Opt_imod:
1498 err = au_br_mod(sb, &opt->mod,
1499 au_ftest_opts(opts->flags, REMOUNT),
1500 &do_refresh);
1501 if (!err) {
1502 err = 1;
1503 if (do_refresh)
1504 au_fset_opts(opts->flags, REFRESH);
1505 }
1506 break;
1507 }
1508
1509 return err;
1510}
1511
1512static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
1513 struct au_opt_xino **opt_xino,
1514 struct au_opts *opts)
1515{
1516 int err;
1517 aufs_bindex_t bbot, bindex;
1518 struct dentry *root, *parent, *h_root;
1519
1520 err = 0;
1521 switch (opt->type) {
1522 case Opt_xino:
1523 err = au_xino_set(sb, &opt->xino,
1524 !!au_ftest_opts(opts->flags, REMOUNT));
1525 if (unlikely(err))
1526 break;
1527
1528 *opt_xino = &opt->xino;
1529 au_xino_brid_set(sb, -1);
1530
1531 /* safe d_parent access */
1532 parent = opt->xino.file->f_path.dentry->d_parent;
1533 root = sb->s_root;
1534 bbot = au_sbbot(sb);
1535 for (bindex = 0; bindex <= bbot; bindex++) {
1536 h_root = au_h_dptr(root, bindex);
1537 if (h_root == parent) {
1538 au_xino_brid_set(sb, au_sbr_id(sb, bindex));
1539 break;
1540 }
1541 }
1542 break;
1543
1544 case Opt_noxino:
1545 au_xino_clr(sb);
1546 au_xino_brid_set(sb, -1);
1547 *opt_xino = (void *)-1;
1548 break;
1549 }
1550
1551 return err;
1552}
1553
1554int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
1555 unsigned int pending)
1556{
1557 int err, fhsm;
1558 aufs_bindex_t bindex, bbot;
1559 unsigned char do_plink, skip, do_free, can_no_dreval;
1560 struct au_branch *br;
1561 struct au_wbr *wbr;
1562 struct dentry *root, *dentry;
1563 struct inode *dir, *h_dir;
1564 struct au_sbinfo *sbinfo;
1565 struct au_hinode *hdir;
1566
1567 SiMustAnyLock(sb);
1568
1569 sbinfo = au_sbi(sb);
1570 AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
1571
1572 if (!(sb_flags & MS_RDONLY)) {
1573 if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
1574 pr_warn("first branch should be rw\n");
1575 if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
1576 pr_warn_once("shwh should be used with ro\n");
1577 }
1578
1579 if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1580 && !au_opt_test(sbinfo->si_mntflags, XINO))
1581 pr_warn_once("udba=*notify requires xino\n");
1582
1583 if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
1584 pr_warn_once("dirperm1 breaks the protection"
1585 " by the permission bits on the lower branch\n");
1586
1587 err = 0;
1588 fhsm = 0;
1589 root = sb->s_root;
1590 dir = d_inode(root);
1591 do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
1592 can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
1593 UDBA_NONE);
1594 bbot = au_sbbot(sb);
1595 for (bindex = 0; !err && bindex <= bbot; bindex++) {
1596 skip = 0;
1597 h_dir = au_h_iptr(dir, bindex);
1598 br = au_sbr(sb, bindex);
1599
1600 if ((br->br_perm & AuBrAttr_ICEX)
1601 && !h_dir->i_op->listxattr)
1602 br->br_perm &= ~AuBrAttr_ICEX;
1603#if 0
1604 if ((br->br_perm & AuBrAttr_ICEX_SEC)
1605 && (au_br_sb(br)->s_flags & MS_NOSEC))
1606 br->br_perm &= ~AuBrAttr_ICEX_SEC;
1607#endif
1608
1609 do_free = 0;
1610 wbr = br->br_wbr;
1611 if (wbr)
1612 wbr_wh_read_lock(wbr);
1613
1614 if (!au_br_writable(br->br_perm)) {
1615 do_free = !!wbr;
1616 skip = (!wbr
1617 || (!wbr->wbr_whbase
1618 && !wbr->wbr_plink
1619 && !wbr->wbr_orph));
1620 } else if (!au_br_wh_linkable(br->br_perm)) {
1621 /* skip = (!br->br_whbase && !br->br_orph); */
1622 skip = (!wbr || !wbr->wbr_whbase);
1623 if (skip && wbr) {
1624 if (do_plink)
1625 skip = !!wbr->wbr_plink;
1626 else
1627 skip = !wbr->wbr_plink;
1628 }
1629 } else {
1630 /* skip = (br->br_whbase && br->br_ohph); */
1631 skip = (wbr && wbr->wbr_whbase);
1632 if (skip) {
1633 if (do_plink)
1634 skip = !!wbr->wbr_plink;
1635 else
1636 skip = !wbr->wbr_plink;
1637 }
1638 }
1639 if (wbr)
1640 wbr_wh_read_unlock(wbr);
1641
1642 if (can_no_dreval) {
1643 dentry = br->br_path.dentry;
1644 spin_lock(&dentry->d_lock);
1645 if (dentry->d_flags &
1646 (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
1647 can_no_dreval = 0;
1648 spin_unlock(&dentry->d_lock);
1649 }
1650
1651 if (au_br_fhsm(br->br_perm)) {
1652 fhsm++;
1653 AuDebugOn(!br->br_fhsm);
1654 }
1655
1656 if (skip)
1657 continue;
1658
1659 hdir = au_hi(dir, bindex);
1660 au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1661 if (wbr)
1662 wbr_wh_write_lock(wbr);
1663 err = au_wh_init(br, sb);
1664 if (wbr)
1665 wbr_wh_write_unlock(wbr);
1666 au_hn_inode_unlock(hdir);
1667
1668 if (!err && do_free) {
1669 if (wbr)
1670 au_delayed_kfree(wbr);
1671 br->br_wbr = NULL;
1672 }
1673 }
1674
1675 if (can_no_dreval)
1676 au_fset_si(sbinfo, NO_DREVAL);
1677 else
1678 au_fclr_si(sbinfo, NO_DREVAL);
1679
1680 if (fhsm >= 2) {
1681 au_fset_si(sbinfo, FHSM);
1682 for (bindex = bbot; bindex >= 0; bindex--) {
1683 br = au_sbr(sb, bindex);
1684 if (au_br_fhsm(br->br_perm)) {
1685 au_fhsm_set_bottom(sb, bindex);
1686 break;
1687 }
1688 }
1689 } else {
1690 au_fclr_si(sbinfo, FHSM);
1691 au_fhsm_set_bottom(sb, -1);
1692 }
1693
1694 return err;
1695}
1696
1697int au_opts_mount(struct super_block *sb, struct au_opts *opts)
1698{
1699 int err;
1700 unsigned int tmp;
1701 aufs_bindex_t bindex, bbot;
1702 struct au_opt *opt;
1703 struct au_opt_xino *opt_xino, xino;
1704 struct au_sbinfo *sbinfo;
1705 struct au_branch *br;
1706 struct inode *dir;
1707
1708 SiMustWriteLock(sb);
1709
1710 err = 0;
1711 opt_xino = NULL;
1712 opt = opts->opt;
1713 while (err >= 0 && opt->type != Opt_tail)
1714 err = au_opt_simple(sb, opt++, opts);
1715 if (err > 0)
1716 err = 0;
1717 else if (unlikely(err < 0))
1718 goto out;
1719
1720 /* disable xino and udba temporary */
1721 sbinfo = au_sbi(sb);
1722 tmp = sbinfo->si_mntflags;
1723 au_opt_clr(sbinfo->si_mntflags, XINO);
1724 au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
1725
1726 opt = opts->opt;
1727 while (err >= 0 && opt->type != Opt_tail)
1728 err = au_opt_br(sb, opt++, opts);
1729 if (err > 0)
1730 err = 0;
1731 else if (unlikely(err < 0))
1732 goto out;
1733
1734 bbot = au_sbbot(sb);
1735 if (unlikely(bbot < 0)) {
1736 err = -EINVAL;
1737 pr_err("no branches\n");
1738 goto out;
1739 }
1740
1741 if (au_opt_test(tmp, XINO))
1742 au_opt_set(sbinfo->si_mntflags, XINO);
1743 opt = opts->opt;
1744 while (!err && opt->type != Opt_tail)
1745 err = au_opt_xino(sb, opt++, &opt_xino, opts);
1746 if (unlikely(err))
1747 goto out;
1748
1749 err = au_opts_verify(sb, sb->s_flags, tmp);
1750 if (unlikely(err))
1751 goto out;
1752
1753 /* restore xino */
1754 if (au_opt_test(tmp, XINO) && !opt_xino) {
1755 xino.file = au_xino_def(sb);
1756 err = PTR_ERR(xino.file);
1757 if (IS_ERR(xino.file))
1758 goto out;
1759
1760 err = au_xino_set(sb, &xino, /*remount*/0);
1761 fput(xino.file);
1762 if (unlikely(err))
1763 goto out;
1764 }
1765
1766 /* restore udba */
1767 tmp &= AuOptMask_UDBA;
1768 sbinfo->si_mntflags &= ~AuOptMask_UDBA;
1769 sbinfo->si_mntflags |= tmp;
1770 bbot = au_sbbot(sb);
1771 for (bindex = 0; bindex <= bbot; bindex++) {
1772 br = au_sbr(sb, bindex);
1773 err = au_hnotify_reset_br(tmp, br, br->br_perm);
1774 if (unlikely(err))
1775 AuIOErr("hnotify failed on br %d, %d, ignored\n",
1776 bindex, err);
1777 /* go on even if err */
1778 }
1779 if (au_opt_test(tmp, UDBA_HNOTIFY)) {
1780 dir = d_inode(sb->s_root);
1781 au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1782 }
1783
1784out:
1785 return err;
1786}
1787
1788int au_opts_remount(struct super_block *sb, struct au_opts *opts)
1789{
1790 int err, rerr;
1791 unsigned char no_dreval;
1792 struct inode *dir;
1793 struct au_opt_xino *opt_xino;
1794 struct au_opt *opt;
1795 struct au_sbinfo *sbinfo;
1796
1797 SiMustWriteLock(sb);
1798
1799 err = 0;
1800 dir = d_inode(sb->s_root);
1801 sbinfo = au_sbi(sb);
1802 opt_xino = NULL;
1803 opt = opts->opt;
1804 while (err >= 0 && opt->type != Opt_tail) {
1805 err = au_opt_simple(sb, opt, opts);
1806 if (!err)
1807 err = au_opt_br(sb, opt, opts);
1808 if (!err)
1809 err = au_opt_xino(sb, opt, &opt_xino, opts);
1810 opt++;
1811 }
1812 if (err > 0)
1813 err = 0;
1814 AuTraceErr(err);
1815 /* go on even err */
1816
1817 no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
1818 rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
1819 if (unlikely(rerr && !err))
1820 err = rerr;
1821
1822 if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
1823 au_fset_opts(opts->flags, REFRESH_IDOP);
1824
1825 if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
1826 rerr = au_xib_trunc(sb);
1827 if (unlikely(rerr && !err))
1828 err = rerr;
1829 }
1830
1831 /* will be handled by the caller */
1832 if (!au_ftest_opts(opts->flags, REFRESH)
1833 && (opts->given_udba
1834 || au_opt_test(sbinfo->si_mntflags, XINO)
1835 || au_ftest_opts(opts->flags, REFRESH_IDOP)
1836 ))
1837 au_fset_opts(opts->flags, REFRESH);
1838
1839 AuDbg("status 0x%x\n", opts->flags);
1840 return err;
1841}
1842
1843/* ---------------------------------------------------------------------- */
1844
1845unsigned int au_opt_udba(struct super_block *sb)
1846{
1847 return au_mntflags(sb) & AuOptMask_UDBA;
1848}