]>
Commit | Line | Data |
---|---|---|
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 and super_block operations | |
20 | */ | |
21 | ||
22 | #include <linux/mm.h> | |
23 | #include <linux/seq_file.h> | |
24 | #include <linux/statfs.h> | |
25 | #include <linux/vmalloc.h> | |
26 | #include "aufs.h" | |
27 | ||
28 | /* | |
29 | * super_operations | |
30 | */ | |
31 | static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused) | |
32 | { | |
33 | struct au_icntnr *c; | |
34 | ||
35 | c = au_cache_alloc_icntnr(); | |
36 | if (c) { | |
37 | au_icntnr_init(c); | |
38 | c->vfs_inode.i_version = 1; /* sigen(sb); */ | |
39 | c->iinfo.ii_hinode = NULL; | |
40 | return &c->vfs_inode; | |
41 | } | |
42 | return NULL; | |
43 | } | |
44 | ||
45 | static void aufs_destroy_inode_cb(struct rcu_head *head) | |
46 | { | |
47 | struct inode *inode = container_of(head, struct inode, i_rcu); | |
48 | ||
49 | au_cache_dfree_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); | |
50 | } | |
51 | ||
52 | static void aufs_destroy_inode(struct inode *inode) | |
53 | { | |
54 | if (!au_is_bad_inode(inode)) | |
55 | au_iinfo_fin(inode); | |
56 | call_rcu(&inode->i_rcu, aufs_destroy_inode_cb); | |
57 | } | |
58 | ||
59 | struct inode *au_iget_locked(struct super_block *sb, ino_t ino) | |
60 | { | |
61 | struct inode *inode; | |
62 | int err; | |
63 | ||
64 | inode = iget_locked(sb, ino); | |
65 | if (unlikely(!inode)) { | |
66 | inode = ERR_PTR(-ENOMEM); | |
67 | goto out; | |
68 | } | |
69 | if (!(inode->i_state & I_NEW)) | |
70 | goto out; | |
71 | ||
72 | err = au_xigen_new(inode); | |
73 | if (!err) | |
74 | err = au_iinfo_init(inode); | |
75 | if (!err) | |
76 | inode->i_version++; | |
77 | else { | |
78 | iget_failed(inode); | |
79 | inode = ERR_PTR(err); | |
80 | } | |
81 | ||
82 | out: | |
83 | /* never return NULL */ | |
84 | AuDebugOn(!inode); | |
85 | AuTraceErrPtr(inode); | |
86 | return inode; | |
87 | } | |
88 | ||
89 | /* lock free root dinfo */ | |
90 | static int au_show_brs(struct seq_file *seq, struct super_block *sb) | |
91 | { | |
92 | int err; | |
93 | aufs_bindex_t bindex, bbot; | |
94 | struct path path; | |
95 | struct au_hdentry *hdp; | |
96 | struct au_branch *br; | |
97 | au_br_perm_str_t perm; | |
98 | ||
99 | err = 0; | |
100 | bbot = au_sbbot(sb); | |
101 | bindex = 0; | |
102 | hdp = au_hdentry(au_di(sb->s_root), bindex); | |
103 | for (; !err && bindex <= bbot; bindex++, hdp++) { | |
104 | br = au_sbr(sb, bindex); | |
105 | path.mnt = au_br_mnt(br); | |
106 | path.dentry = hdp->hd_dentry; | |
107 | err = au_seq_path(seq, &path); | |
108 | if (!err) { | |
109 | au_optstr_br_perm(&perm, br->br_perm); | |
110 | seq_printf(seq, "=%s", perm.a); | |
111 | if (bindex != bbot) | |
112 | seq_putc(seq, ':'); | |
113 | } | |
114 | } | |
115 | if (unlikely(err || seq_has_overflowed(seq))) | |
116 | err = -E2BIG; | |
117 | ||
118 | return err; | |
119 | } | |
120 | ||
121 | static void au_gen_fmt(char *fmt, int len __maybe_unused, const char *pat, | |
122 | const char *append) | |
123 | { | |
124 | char *p; | |
125 | ||
126 | p = fmt; | |
127 | while (*pat != ':') | |
128 | *p++ = *pat++; | |
129 | *p++ = *pat++; | |
130 | strcpy(p, append); | |
131 | AuDebugOn(strlen(fmt) >= len); | |
132 | } | |
133 | ||
134 | static void au_show_wbr_create(struct seq_file *m, int v, | |
135 | struct au_sbinfo *sbinfo) | |
136 | { | |
137 | const char *pat; | |
138 | char fmt[32]; | |
139 | struct au_wbr_mfs *mfs; | |
140 | ||
141 | AuRwMustAnyLock(&sbinfo->si_rwsem); | |
142 | ||
143 | seq_puts(m, ",create="); | |
144 | pat = au_optstr_wbr_create(v); | |
145 | mfs = &sbinfo->si_wbr_mfs; | |
146 | switch (v) { | |
147 | case AuWbrCreate_TDP: | |
148 | case AuWbrCreate_RR: | |
149 | case AuWbrCreate_MFS: | |
150 | case AuWbrCreate_PMFS: | |
151 | seq_puts(m, pat); | |
152 | break; | |
153 | case AuWbrCreate_MFSRR: | |
154 | case AuWbrCreate_TDMFS: | |
155 | case AuWbrCreate_PMFSRR: | |
156 | au_gen_fmt(fmt, sizeof(fmt), pat, "%llu"); | |
157 | seq_printf(m, fmt, mfs->mfsrr_watermark); | |
158 | break; | |
159 | case AuWbrCreate_MFSV: | |
160 | case AuWbrCreate_PMFSV: | |
161 | au_gen_fmt(fmt, sizeof(fmt), pat, "%lu"); | |
162 | seq_printf(m, fmt, | |
163 | jiffies_to_msecs(mfs->mfs_expire) | |
164 | / MSEC_PER_SEC); | |
165 | break; | |
166 | case AuWbrCreate_MFSRRV: | |
167 | case AuWbrCreate_TDMFSV: | |
168 | case AuWbrCreate_PMFSRRV: | |
169 | au_gen_fmt(fmt, sizeof(fmt), pat, "%llu:%lu"); | |
170 | seq_printf(m, fmt, mfs->mfsrr_watermark, | |
171 | jiffies_to_msecs(mfs->mfs_expire) / MSEC_PER_SEC); | |
172 | break; | |
173 | default: | |
174 | BUG(); | |
175 | } | |
176 | } | |
177 | ||
178 | static int au_show_xino(struct seq_file *seq, struct super_block *sb) | |
179 | { | |
180 | #ifdef CONFIG_SYSFS | |
181 | return 0; | |
182 | #else | |
183 | int err; | |
184 | const int len = sizeof(AUFS_XINO_FNAME) - 1; | |
185 | aufs_bindex_t bindex, brid; | |
186 | struct qstr *name; | |
187 | struct file *f; | |
188 | struct dentry *d, *h_root; | |
189 | ||
190 | AuRwMustAnyLock(&sbinfo->si_rwsem); | |
191 | ||
192 | err = 0; | |
193 | f = au_sbi(sb)->si_xib; | |
194 | if (!f) | |
195 | goto out; | |
196 | ||
197 | /* stop printing the default xino path on the first writable branch */ | |
198 | h_root = NULL; | |
199 | brid = au_xino_brid(sb); | |
200 | if (brid >= 0) { | |
201 | bindex = au_br_index(sb, brid); | |
202 | h_root = au_hdentry(au_di(sb->s_root), bindex)->hd_dentry; | |
203 | } | |
204 | d = f->f_path.dentry; | |
205 | name = &d->d_name; | |
206 | /* safe ->d_parent because the file is unlinked */ | |
207 | if (d->d_parent == h_root | |
208 | && name->len == len | |
209 | && !memcmp(name->name, AUFS_XINO_FNAME, len)) | |
210 | goto out; | |
211 | ||
212 | seq_puts(seq, ",xino="); | |
213 | err = au_xino_path(seq, f); | |
214 | ||
215 | out: | |
216 | return err; | |
217 | #endif | |
218 | } | |
219 | ||
220 | /* seq_file will re-call me in case of too long string */ | |
221 | static int aufs_show_options(struct seq_file *m, struct dentry *dentry) | |
222 | { | |
223 | int err; | |
224 | unsigned int mnt_flags, v; | |
225 | struct super_block *sb; | |
226 | struct au_sbinfo *sbinfo; | |
227 | ||
228 | #define AuBool(name, str) do { \ | |
229 | v = au_opt_test(mnt_flags, name); \ | |
230 | if (v != au_opt_test(AuOpt_Def, name)) \ | |
231 | seq_printf(m, ",%s" #str, v ? "" : "no"); \ | |
232 | } while (0) | |
233 | ||
234 | #define AuStr(name, str) do { \ | |
235 | v = mnt_flags & AuOptMask_##name; \ | |
236 | if (v != (AuOpt_Def & AuOptMask_##name)) \ | |
237 | seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ | |
238 | } while (0) | |
239 | ||
240 | #define AuUInt(name, str, val) do { \ | |
241 | if (val != AUFS_##name##_DEF) \ | |
242 | seq_printf(m, "," #str "=%u", val); \ | |
243 | } while (0) | |
244 | ||
245 | sb = dentry->d_sb; | |
246 | if (sb->s_flags & MS_POSIXACL) | |
247 | seq_puts(m, ",acl"); | |
248 | ||
249 | /* lock free root dinfo */ | |
250 | si_noflush_read_lock(sb); | |
251 | sbinfo = au_sbi(sb); | |
252 | seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo)); | |
253 | ||
254 | mnt_flags = au_mntflags(sb); | |
255 | if (au_opt_test(mnt_flags, XINO)) { | |
256 | err = au_show_xino(m, sb); | |
257 | if (unlikely(err)) | |
258 | goto out; | |
259 | } else | |
260 | seq_puts(m, ",noxino"); | |
261 | ||
262 | AuBool(TRUNC_XINO, trunc_xino); | |
263 | AuStr(UDBA, udba); | |
264 | AuBool(SHWH, shwh); | |
265 | AuBool(PLINK, plink); | |
266 | AuBool(DIO, dio); | |
267 | AuBool(DIRPERM1, dirperm1); | |
268 | ||
269 | v = sbinfo->si_wbr_create; | |
270 | if (v != AuWbrCreate_Def) | |
271 | au_show_wbr_create(m, v, sbinfo); | |
272 | ||
273 | v = sbinfo->si_wbr_copyup; | |
274 | if (v != AuWbrCopyup_Def) | |
275 | seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); | |
276 | ||
277 | v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); | |
278 | if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) | |
279 | seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); | |
280 | ||
281 | AuUInt(DIRWH, dirwh, sbinfo->si_dirwh); | |
282 | ||
283 | v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC; | |
284 | AuUInt(RDCACHE, rdcache, v); | |
285 | ||
286 | AuUInt(RDBLK, rdblk, sbinfo->si_rdblk); | |
287 | AuUInt(RDHASH, rdhash, sbinfo->si_rdhash); | |
288 | ||
289 | au_fhsm_show(m, sbinfo); | |
290 | ||
291 | AuBool(SUM, sum); | |
292 | /* AuBool(SUM_W, wsum); */ | |
293 | AuBool(WARN_PERM, warn_perm); | |
294 | AuBool(VERBOSE, verbose); | |
295 | ||
296 | out: | |
297 | /* be sure to print "br:" last */ | |
298 | if (!sysaufs_brs) { | |
299 | seq_puts(m, ",br:"); | |
300 | au_show_brs(m, sb); | |
301 | } | |
302 | si_read_unlock(sb); | |
303 | return 0; | |
304 | ||
305 | #undef AuBool | |
306 | #undef AuStr | |
307 | #undef AuUInt | |
308 | } | |
309 | ||
310 | /* ---------------------------------------------------------------------- */ | |
311 | ||
312 | /* sum mode which returns the summation for statfs(2) */ | |
313 | ||
314 | static u64 au_add_till_max(u64 a, u64 b) | |
315 | { | |
316 | u64 old; | |
317 | ||
318 | old = a; | |
319 | a += b; | |
320 | if (old <= a) | |
321 | return a; | |
322 | return ULLONG_MAX; | |
323 | } | |
324 | ||
325 | static u64 au_mul_till_max(u64 a, long mul) | |
326 | { | |
327 | u64 old; | |
328 | ||
329 | old = a; | |
330 | a *= mul; | |
331 | if (old <= a) | |
332 | return a; | |
333 | return ULLONG_MAX; | |
334 | } | |
335 | ||
336 | static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf) | |
337 | { | |
338 | int err; | |
339 | long bsize, factor; | |
340 | u64 blocks, bfree, bavail, files, ffree; | |
341 | aufs_bindex_t bbot, bindex, i; | |
342 | unsigned char shared; | |
343 | struct path h_path; | |
344 | struct super_block *h_sb; | |
345 | ||
346 | err = 0; | |
347 | bsize = LONG_MAX; | |
348 | files = 0; | |
349 | ffree = 0; | |
350 | blocks = 0; | |
351 | bfree = 0; | |
352 | bavail = 0; | |
353 | bbot = au_sbbot(sb); | |
354 | for (bindex = 0; bindex <= bbot; bindex++) { | |
355 | h_path.mnt = au_sbr_mnt(sb, bindex); | |
356 | h_sb = h_path.mnt->mnt_sb; | |
357 | shared = 0; | |
358 | for (i = 0; !shared && i < bindex; i++) | |
359 | shared = (au_sbr_sb(sb, i) == h_sb); | |
360 | if (shared) | |
361 | continue; | |
362 | ||
363 | /* sb->s_root for NFS is unreliable */ | |
364 | h_path.dentry = h_path.mnt->mnt_root; | |
365 | err = vfs_statfs(&h_path, buf); | |
366 | if (unlikely(err)) | |
367 | goto out; | |
368 | ||
369 | if (bsize > buf->f_bsize) { | |
370 | /* | |
371 | * we will reduce bsize, so we have to expand blocks | |
372 | * etc. to match them again | |
373 | */ | |
374 | factor = (bsize / buf->f_bsize); | |
375 | blocks = au_mul_till_max(blocks, factor); | |
376 | bfree = au_mul_till_max(bfree, factor); | |
377 | bavail = au_mul_till_max(bavail, factor); | |
378 | bsize = buf->f_bsize; | |
379 | } | |
380 | ||
381 | factor = (buf->f_bsize / bsize); | |
382 | blocks = au_add_till_max(blocks, | |
383 | au_mul_till_max(buf->f_blocks, factor)); | |
384 | bfree = au_add_till_max(bfree, | |
385 | au_mul_till_max(buf->f_bfree, factor)); | |
386 | bavail = au_add_till_max(bavail, | |
387 | au_mul_till_max(buf->f_bavail, factor)); | |
388 | files = au_add_till_max(files, buf->f_files); | |
389 | ffree = au_add_till_max(ffree, buf->f_ffree); | |
390 | } | |
391 | ||
392 | buf->f_bsize = bsize; | |
393 | buf->f_blocks = blocks; | |
394 | buf->f_bfree = bfree; | |
395 | buf->f_bavail = bavail; | |
396 | buf->f_files = files; | |
397 | buf->f_ffree = ffree; | |
398 | buf->f_frsize = 0; | |
399 | ||
400 | out: | |
401 | return err; | |
402 | } | |
403 | ||
404 | static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) | |
405 | { | |
406 | int err; | |
407 | struct path h_path; | |
408 | struct super_block *sb; | |
409 | ||
410 | /* lock free root dinfo */ | |
411 | sb = dentry->d_sb; | |
412 | si_noflush_read_lock(sb); | |
413 | if (!au_opt_test(au_mntflags(sb), SUM)) { | |
414 | /* sb->s_root for NFS is unreliable */ | |
415 | h_path.mnt = au_sbr_mnt(sb, 0); | |
416 | h_path.dentry = h_path.mnt->mnt_root; | |
417 | err = vfs_statfs(&h_path, buf); | |
418 | } else | |
419 | err = au_statfs_sum(sb, buf); | |
420 | si_read_unlock(sb); | |
421 | ||
422 | if (!err) { | |
423 | buf->f_type = AUFS_SUPER_MAGIC; | |
424 | buf->f_namelen = AUFS_MAX_NAMELEN; | |
425 | memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); | |
426 | } | |
427 | /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ | |
428 | ||
429 | return err; | |
430 | } | |
431 | ||
432 | /* ---------------------------------------------------------------------- */ | |
433 | ||
434 | static int aufs_sync_fs(struct super_block *sb, int wait) | |
435 | { | |
436 | int err, e; | |
437 | aufs_bindex_t bbot, bindex; | |
438 | struct au_branch *br; | |
439 | struct super_block *h_sb; | |
440 | ||
441 | err = 0; | |
442 | si_noflush_read_lock(sb); | |
443 | bbot = au_sbbot(sb); | |
444 | for (bindex = 0; bindex <= bbot; bindex++) { | |
445 | br = au_sbr(sb, bindex); | |
446 | if (!au_br_writable(br->br_perm)) | |
447 | continue; | |
448 | ||
449 | h_sb = au_sbr_sb(sb, bindex); | |
450 | e = vfsub_sync_filesystem(h_sb, wait); | |
451 | if (unlikely(e && !err)) | |
452 | err = e; | |
453 | /* go on even if an error happens */ | |
454 | } | |
455 | si_read_unlock(sb); | |
456 | ||
457 | return err; | |
458 | } | |
459 | ||
460 | /* ---------------------------------------------------------------------- */ | |
461 | ||
462 | /* final actions when unmounting a file system */ | |
463 | static void aufs_put_super(struct super_block *sb) | |
464 | { | |
465 | struct au_sbinfo *sbinfo; | |
466 | ||
467 | sbinfo = au_sbi(sb); | |
468 | if (!sbinfo) | |
469 | return; | |
470 | ||
471 | dbgaufs_si_fin(sbinfo); | |
472 | kobject_put(&sbinfo->si_kobj); | |
473 | } | |
474 | ||
475 | /* ---------------------------------------------------------------------- */ | |
476 | ||
477 | void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, | |
478 | struct super_block *sb, void *arg) | |
479 | { | |
480 | void *array; | |
481 | unsigned long long n, sz; | |
482 | ||
483 | array = NULL; | |
484 | n = 0; | |
485 | if (!*hint) | |
486 | goto out; | |
487 | ||
488 | if (*hint > ULLONG_MAX / sizeof(array)) { | |
489 | array = ERR_PTR(-EMFILE); | |
490 | pr_err("hint %llu\n", *hint); | |
491 | goto out; | |
492 | } | |
493 | ||
494 | sz = sizeof(array) * *hint; | |
495 | array = kzalloc(sz, GFP_NOFS); | |
496 | if (unlikely(!array)) | |
497 | array = vzalloc(sz); | |
498 | if (unlikely(!array)) { | |
499 | array = ERR_PTR(-ENOMEM); | |
500 | goto out; | |
501 | } | |
502 | ||
503 | n = cb(sb, array, *hint, arg); | |
504 | AuDebugOn(n > *hint); | |
505 | ||
506 | out: | |
507 | *hint = n; | |
508 | return array; | |
509 | } | |
510 | ||
511 | static unsigned long long au_iarray_cb(struct super_block *sb, void *a, | |
512 | unsigned long long max __maybe_unused, | |
513 | void *arg) | |
514 | { | |
515 | unsigned long long n; | |
516 | struct inode **p, *inode; | |
517 | struct list_head *head; | |
518 | ||
519 | n = 0; | |
520 | p = a; | |
521 | head = arg; | |
522 | spin_lock(&sb->s_inode_list_lock); | |
523 | list_for_each_entry(inode, head, i_sb_list) { | |
524 | if (!au_is_bad_inode(inode) | |
525 | && au_ii(inode)->ii_btop >= 0) { | |
526 | spin_lock(&inode->i_lock); | |
527 | if (atomic_read(&inode->i_count)) { | |
528 | au_igrab(inode); | |
529 | *p++ = inode; | |
530 | n++; | |
531 | AuDebugOn(n > max); | |
532 | } | |
533 | spin_unlock(&inode->i_lock); | |
534 | } | |
535 | } | |
536 | spin_unlock(&sb->s_inode_list_lock); | |
537 | ||
538 | return n; | |
539 | } | |
540 | ||
541 | struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max) | |
542 | { | |
543 | *max = au_ninodes(sb); | |
544 | return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes); | |
545 | } | |
546 | ||
547 | void au_iarray_free(struct inode **a, unsigned long long max) | |
548 | { | |
549 | unsigned long long ull; | |
550 | ||
551 | for (ull = 0; ull < max; ull++) | |
552 | iput(a[ull]); | |
553 | kvfree(a); | |
554 | } | |
555 | ||
556 | /* ---------------------------------------------------------------------- */ | |
557 | ||
558 | /* | |
559 | * refresh dentry and inode at remount time. | |
560 | */ | |
561 | /* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */ | |
562 | static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags, | |
563 | struct dentry *parent) | |
564 | { | |
565 | int err; | |
566 | ||
567 | di_write_lock_child(dentry); | |
568 | di_read_lock_parent(parent, AuLock_IR); | |
569 | err = au_refresh_dentry(dentry, parent); | |
570 | if (!err && dir_flags) | |
571 | au_hn_reset(d_inode(dentry), dir_flags); | |
572 | di_read_unlock(parent, AuLock_IR); | |
573 | di_write_unlock(dentry); | |
574 | ||
575 | return err; | |
576 | } | |
577 | ||
578 | static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen, | |
579 | struct au_sbinfo *sbinfo, | |
580 | const unsigned int dir_flags, unsigned int do_idop) | |
581 | { | |
582 | int err; | |
583 | struct dentry *parent; | |
584 | ||
585 | err = 0; | |
586 | parent = dget_parent(dentry); | |
587 | if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) { | |
588 | if (d_really_is_positive(dentry)) { | |
589 | if (!d_is_dir(dentry)) | |
590 | err = au_do_refresh(dentry, /*dir_flags*/0, | |
591 | parent); | |
592 | else { | |
593 | err = au_do_refresh(dentry, dir_flags, parent); | |
594 | if (unlikely(err)) | |
595 | au_fset_si(sbinfo, FAILED_REFRESH_DIR); | |
596 | } | |
597 | } else | |
598 | err = au_do_refresh(dentry, /*dir_flags*/0, parent); | |
599 | AuDbgDentry(dentry); | |
600 | } | |
601 | dput(parent); | |
602 | ||
603 | if (!err) { | |
604 | if (do_idop) | |
605 | au_refresh_dop(dentry, /*force_reval*/0); | |
606 | } else | |
607 | au_refresh_dop(dentry, /*force_reval*/1); | |
608 | ||
609 | AuTraceErr(err); | |
610 | return err; | |
611 | } | |
612 | ||
613 | static int au_refresh_d(struct super_block *sb, unsigned int do_idop) | |
614 | { | |
615 | int err, i, j, ndentry, e; | |
616 | unsigned int sigen; | |
617 | struct au_dcsub_pages dpages; | |
618 | struct au_dpage *dpage; | |
619 | struct dentry **dentries, *d; | |
620 | struct au_sbinfo *sbinfo; | |
621 | struct dentry *root = sb->s_root; | |
622 | const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1); | |
623 | ||
624 | if (do_idop) | |
625 | au_refresh_dop(root, /*force_reval*/0); | |
626 | ||
627 | err = au_dpages_init(&dpages, GFP_NOFS); | |
628 | if (unlikely(err)) | |
629 | goto out; | |
630 | err = au_dcsub_pages(&dpages, root, NULL, NULL); | |
631 | if (unlikely(err)) | |
632 | goto out_dpages; | |
633 | ||
634 | sigen = au_sigen(sb); | |
635 | sbinfo = au_sbi(sb); | |
636 | for (i = 0; i < dpages.ndpage; i++) { | |
637 | dpage = dpages.dpages + i; | |
638 | dentries = dpage->dentries; | |
639 | ndentry = dpage->ndentry; | |
640 | for (j = 0; j < ndentry; j++) { | |
641 | d = dentries[j]; | |
642 | e = au_do_refresh_d(d, sigen, sbinfo, dir_flags, | |
643 | do_idop); | |
644 | if (unlikely(e && !err)) | |
645 | err = e; | |
646 | /* go on even err */ | |
647 | } | |
648 | } | |
649 | ||
650 | out_dpages: | |
651 | au_dpages_free(&dpages); | |
652 | out: | |
653 | return err; | |
654 | } | |
655 | ||
656 | static int au_refresh_i(struct super_block *sb, unsigned int do_idop) | |
657 | { | |
658 | int err, e; | |
659 | unsigned int sigen; | |
660 | unsigned long long max, ull; | |
661 | struct inode *inode, **array; | |
662 | ||
663 | array = au_iarray_alloc(sb, &max); | |
664 | err = PTR_ERR(array); | |
665 | if (IS_ERR(array)) | |
666 | goto out; | |
667 | ||
668 | err = 0; | |
669 | sigen = au_sigen(sb); | |
670 | for (ull = 0; ull < max; ull++) { | |
671 | inode = array[ull]; | |
672 | if (unlikely(!inode)) | |
673 | break; | |
674 | ||
675 | e = 0; | |
676 | ii_write_lock_child(inode); | |
677 | if (au_iigen(inode, NULL) != sigen) { | |
678 | e = au_refresh_hinode_self(inode); | |
679 | if (unlikely(e)) { | |
680 | au_refresh_iop(inode, /*force_getattr*/1); | |
681 | pr_err("error %d, i%lu\n", e, inode->i_ino); | |
682 | if (!err) | |
683 | err = e; | |
684 | /* go on even if err */ | |
685 | } | |
686 | } | |
687 | if (!e && do_idop) | |
688 | au_refresh_iop(inode, /*force_getattr*/0); | |
689 | ii_write_unlock(inode); | |
690 | } | |
691 | ||
692 | au_iarray_free(array, max); | |
693 | ||
694 | out: | |
695 | return err; | |
696 | } | |
697 | ||
698 | static void au_remount_refresh(struct super_block *sb, unsigned int do_idop) | |
699 | { | |
700 | int err, e; | |
701 | unsigned int udba; | |
702 | aufs_bindex_t bindex, bbot; | |
703 | struct dentry *root; | |
704 | struct inode *inode; | |
705 | struct au_branch *br; | |
706 | struct au_sbinfo *sbi; | |
707 | ||
708 | au_sigen_inc(sb); | |
709 | sbi = au_sbi(sb); | |
710 | au_fclr_si(sbi, FAILED_REFRESH_DIR); | |
711 | ||
712 | root = sb->s_root; | |
713 | DiMustNoWaiters(root); | |
714 | inode = d_inode(root); | |
715 | IiMustNoWaiters(inode); | |
716 | ||
717 | udba = au_opt_udba(sb); | |
718 | bbot = au_sbbot(sb); | |
719 | for (bindex = 0; bindex <= bbot; bindex++) { | |
720 | br = au_sbr(sb, bindex); | |
721 | err = au_hnotify_reset_br(udba, br, br->br_perm); | |
722 | if (unlikely(err)) | |
723 | AuIOErr("hnotify failed on br %d, %d, ignored\n", | |
724 | bindex, err); | |
725 | /* go on even if err */ | |
726 | } | |
727 | au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1)); | |
728 | ||
729 | if (do_idop) { | |
730 | if (au_ftest_si(sbi, NO_DREVAL)) { | |
731 | AuDebugOn(sb->s_d_op == &aufs_dop_noreval); | |
732 | sb->s_d_op = &aufs_dop_noreval; | |
733 | AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr); | |
734 | sbi->si_iop_array = aufs_iop_nogetattr; | |
735 | } else { | |
736 | AuDebugOn(sb->s_d_op == &aufs_dop); | |
737 | sb->s_d_op = &aufs_dop; | |
738 | AuDebugOn(sbi->si_iop_array == aufs_iop); | |
739 | sbi->si_iop_array = aufs_iop; | |
740 | } | |
741 | pr_info("reset to %pf and %pf\n", | |
742 | sb->s_d_op, sbi->si_iop_array); | |
743 | } | |
744 | ||
745 | di_write_unlock(root); | |
746 | err = au_refresh_d(sb, do_idop); | |
747 | e = au_refresh_i(sb, do_idop); | |
748 | if (unlikely(e && !err)) | |
749 | err = e; | |
750 | /* aufs_write_lock() calls ..._child() */ | |
751 | di_write_lock_child(root); | |
752 | ||
753 | au_cpup_attr_all(inode, /*force*/1); | |
754 | ||
755 | if (unlikely(err)) | |
756 | AuIOErr("refresh failed, ignored, %d\n", err); | |
757 | } | |
758 | ||
759 | /* stop extra interpretation of errno in mount(8), and strange error messages */ | |
760 | static int cvt_err(int err) | |
761 | { | |
762 | AuTraceErr(err); | |
763 | ||
764 | switch (err) { | |
765 | case -ENOENT: | |
766 | case -ENOTDIR: | |
767 | case -EEXIST: | |
768 | case -EIO: | |
769 | err = -EINVAL; | |
770 | } | |
771 | return err; | |
772 | } | |
773 | ||
774 | static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) | |
775 | { | |
776 | int err, do_dx; | |
777 | unsigned int mntflags; | |
778 | struct au_opts opts = { | |
779 | .opt = NULL | |
780 | }; | |
781 | struct dentry *root; | |
782 | struct inode *inode; | |
783 | struct au_sbinfo *sbinfo; | |
784 | ||
785 | err = 0; | |
786 | root = sb->s_root; | |
787 | if (!data || !*data) { | |
788 | err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); | |
789 | if (!err) { | |
790 | di_write_lock_child(root); | |
791 | err = au_opts_verify(sb, *flags, /*pending*/0); | |
792 | aufs_write_unlock(root); | |
793 | } | |
794 | goto out; | |
795 | } | |
796 | ||
797 | err = -ENOMEM; | |
798 | opts.opt = (void *)__get_free_page(GFP_NOFS); | |
799 | if (unlikely(!opts.opt)) | |
800 | goto out; | |
801 | opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); | |
802 | opts.flags = AuOpts_REMOUNT; | |
803 | opts.sb_flags = *flags; | |
804 | ||
805 | /* parse it before aufs lock */ | |
806 | err = au_opts_parse(sb, data, &opts); | |
807 | if (unlikely(err)) | |
808 | goto out_opts; | |
809 | ||
810 | sbinfo = au_sbi(sb); | |
811 | inode = d_inode(root); | |
812 | inode_lock(inode); | |
813 | err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); | |
814 | if (unlikely(err)) | |
815 | goto out_mtx; | |
816 | di_write_lock_child(root); | |
817 | ||
818 | /* au_opts_remount() may return an error */ | |
819 | err = au_opts_remount(sb, &opts); | |
820 | au_opts_free(&opts); | |
821 | ||
822 | if (au_ftest_opts(opts.flags, REFRESH)) | |
823 | au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP)); | |
824 | ||
825 | if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) { | |
826 | mntflags = au_mntflags(sb); | |
827 | do_dx = !!au_opt_test(mntflags, DIO); | |
828 | au_dy_arefresh(do_dx); | |
829 | } | |
830 | ||
831 | au_fhsm_wrote_all(sb, /*force*/1); /* ?? */ | |
832 | aufs_write_unlock(root); | |
833 | ||
834 | out_mtx: | |
835 | inode_unlock(inode); | |
836 | out_opts: | |
837 | au_delayed_free_page((unsigned long)opts.opt); | |
838 | out: | |
839 | err = cvt_err(err); | |
840 | AuTraceErr(err); | |
841 | return err; | |
842 | } | |
843 | ||
844 | static const struct super_operations aufs_sop = { | |
845 | .alloc_inode = aufs_alloc_inode, | |
846 | .destroy_inode = aufs_destroy_inode, | |
847 | /* always deleting, no clearing */ | |
848 | .drop_inode = generic_delete_inode, | |
849 | .show_options = aufs_show_options, | |
850 | .statfs = aufs_statfs, | |
851 | .put_super = aufs_put_super, | |
852 | .sync_fs = aufs_sync_fs, | |
853 | .remount_fs = aufs_remount_fs | |
854 | }; | |
855 | ||
856 | /* ---------------------------------------------------------------------- */ | |
857 | ||
858 | static int alloc_root(struct super_block *sb) | |
859 | { | |
860 | int err; | |
861 | struct inode *inode; | |
862 | struct dentry *root; | |
863 | ||
864 | err = -ENOMEM; | |
865 | inode = au_iget_locked(sb, AUFS_ROOT_INO); | |
866 | err = PTR_ERR(inode); | |
867 | if (IS_ERR(inode)) | |
868 | goto out; | |
869 | ||
870 | inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */ | |
871 | inode->i_fop = &aufs_dir_fop; | |
872 | inode->i_mode = S_IFDIR; | |
873 | set_nlink(inode, 2); | |
874 | unlock_new_inode(inode); | |
875 | ||
876 | root = d_make_root(inode); | |
877 | if (unlikely(!root)) | |
878 | goto out; | |
879 | err = PTR_ERR(root); | |
880 | if (IS_ERR(root)) | |
881 | goto out; | |
882 | ||
883 | err = au_di_init(root); | |
884 | if (!err) { | |
885 | sb->s_root = root; | |
886 | return 0; /* success */ | |
887 | } | |
888 | dput(root); | |
889 | ||
890 | out: | |
891 | return err; | |
892 | } | |
893 | ||
894 | static int aufs_fill_super(struct super_block *sb, void *raw_data, | |
895 | int silent __maybe_unused) | |
896 | { | |
897 | int err; | |
898 | struct au_opts opts = { | |
899 | .opt = NULL | |
900 | }; | |
901 | struct au_sbinfo *sbinfo; | |
902 | struct dentry *root; | |
903 | struct inode *inode; | |
904 | char *arg = raw_data; | |
905 | ||
906 | if (unlikely(!arg || !*arg)) { | |
907 | err = -EINVAL; | |
908 | pr_err("no arg\n"); | |
909 | goto out; | |
910 | } | |
911 | ||
912 | err = -ENOMEM; | |
913 | opts.opt = (void *)__get_free_page(GFP_NOFS); | |
914 | if (unlikely(!opts.opt)) | |
915 | goto out; | |
916 | opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); | |
917 | opts.sb_flags = sb->s_flags; | |
918 | ||
919 | err = au_si_alloc(sb); | |
920 | if (unlikely(err)) | |
921 | goto out_opts; | |
922 | sbinfo = au_sbi(sb); | |
923 | ||
924 | /* all timestamps always follow the ones on the branch */ | |
925 | sb->s_flags |= MS_NOATIME | MS_NODIRATIME; | |
926 | sb->s_op = &aufs_sop; | |
927 | sb->s_d_op = &aufs_dop; | |
928 | sb->s_magic = AUFS_SUPER_MAGIC; | |
929 | sb->s_maxbytes = 0; | |
930 | sb->s_stack_depth = 1; | |
931 | au_export_init(sb); | |
932 | au_xattr_init(sb); | |
933 | ||
934 | err = alloc_root(sb); | |
935 | if (unlikely(err)) { | |
936 | si_write_unlock(sb); | |
937 | goto out_info; | |
938 | } | |
939 | root = sb->s_root; | |
940 | inode = d_inode(root); | |
941 | ||
942 | /* | |
943 | * actually we can parse options regardless aufs lock here. | |
944 | * but at remount time, parsing must be done before aufs lock. | |
945 | * so we follow the same rule. | |
946 | */ | |
947 | ii_write_lock_parent(inode); | |
948 | aufs_write_unlock(root); | |
949 | err = au_opts_parse(sb, arg, &opts); | |
950 | if (unlikely(err)) | |
951 | goto out_root; | |
952 | ||
953 | /* lock vfs_inode first, then aufs. */ | |
954 | inode_lock(inode); | |
955 | aufs_write_lock(root); | |
956 | err = au_opts_mount(sb, &opts); | |
957 | au_opts_free(&opts); | |
958 | if (!err && au_ftest_si(sbinfo, NO_DREVAL)) { | |
959 | sb->s_d_op = &aufs_dop_noreval; | |
960 | pr_info("%pf\n", sb->s_d_op); | |
961 | au_refresh_dop(root, /*force_reval*/0); | |
962 | sbinfo->si_iop_array = aufs_iop_nogetattr; | |
963 | au_refresh_iop(inode, /*force_getattr*/0); | |
964 | } | |
965 | aufs_write_unlock(root); | |
966 | inode_unlock(inode); | |
967 | if (!err) | |
968 | goto out_opts; /* success */ | |
969 | ||
970 | out_root: | |
971 | dput(root); | |
972 | sb->s_root = NULL; | |
973 | out_info: | |
974 | dbgaufs_si_fin(sbinfo); | |
975 | kobject_put(&sbinfo->si_kobj); | |
976 | sb->s_fs_info = NULL; | |
977 | out_opts: | |
978 | au_delayed_free_page((unsigned long)opts.opt); | |
979 | out: | |
980 | AuTraceErr(err); | |
981 | err = cvt_err(err); | |
982 | AuTraceErr(err); | |
983 | return err; | |
984 | } | |
985 | ||
986 | /* ---------------------------------------------------------------------- */ | |
987 | ||
988 | static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags, | |
989 | const char *dev_name __maybe_unused, | |
990 | void *raw_data) | |
991 | { | |
992 | struct dentry *root; | |
993 | struct super_block *sb; | |
994 | ||
995 | /* all timestamps always follow the ones on the branch */ | |
996 | /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ | |
997 | root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super); | |
998 | if (IS_ERR(root)) | |
999 | goto out; | |
1000 | ||
1001 | sb = root->d_sb; | |
1002 | si_write_lock(sb, !AuLock_FLUSH); | |
1003 | sysaufs_brs_add(sb, 0); | |
1004 | si_write_unlock(sb); | |
1005 | au_sbilist_add(sb); | |
1006 | ||
1007 | out: | |
1008 | return root; | |
1009 | } | |
1010 | ||
1011 | static void aufs_kill_sb(struct super_block *sb) | |
1012 | { | |
1013 | struct au_sbinfo *sbinfo; | |
1014 | ||
1015 | sbinfo = au_sbi(sb); | |
1016 | if (sbinfo) { | |
1017 | au_sbilist_del(sb); | |
1018 | aufs_write_lock(sb->s_root); | |
1019 | au_fhsm_fin(sb); | |
1020 | if (sbinfo->si_wbr_create_ops->fin) | |
1021 | sbinfo->si_wbr_create_ops->fin(sb); | |
1022 | if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) { | |
1023 | au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE); | |
1024 | au_remount_refresh(sb, /*do_idop*/0); | |
1025 | } | |
1026 | if (au_opt_test(sbinfo->si_mntflags, PLINK)) | |
1027 | au_plink_put(sb, /*verbose*/1); | |
1028 | au_xino_clr(sb); | |
1029 | sbinfo->si_sb = NULL; | |
1030 | aufs_write_unlock(sb->s_root); | |
1031 | au_nwt_flush(&sbinfo->si_nowait); | |
1032 | } | |
1033 | kill_anon_super(sb); | |
1034 | } | |
1035 | ||
1036 | struct file_system_type aufs_fs_type = { | |
1037 | .name = AUFS_FSTYPE, | |
1038 | /* a race between rename and others */ | |
1039 | .fs_flags = FS_RENAME_DOES_D_MOVE, | |
1040 | .mount = aufs_mount, | |
1041 | .kill_sb = aufs_kill_sb, | |
1042 | /* no need to __module_get() and module_put(). */ | |
1043 | .owner = THIS_MODULE, | |
1044 | }; |