]>
Commit | Line | Data |
---|---|---|
c088e31d SF |
1 | /* |
2 | * Copyright (C) 2005-2017 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_free_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 & SB_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(DIRREN, dirren); | |
292 | AuBool(SUM, sum); | |
293 | /* AuBool(SUM_W, wsum); */ | |
294 | AuBool(WARN_PERM, warn_perm); | |
295 | AuBool(VERBOSE, verbose); | |
296 | ||
297 | out: | |
298 | /* be sure to print "br:" last */ | |
299 | if (!sysaufs_brs) { | |
300 | seq_puts(m, ",br:"); | |
301 | au_show_brs(m, sb); | |
302 | } | |
303 | si_read_unlock(sb); | |
304 | return 0; | |
305 | ||
306 | #undef AuBool | |
307 | #undef AuStr | |
308 | #undef AuUInt | |
309 | } | |
310 | ||
311 | /* ---------------------------------------------------------------------- */ | |
312 | ||
313 | /* sum mode which returns the summation for statfs(2) */ | |
314 | ||
315 | static u64 au_add_till_max(u64 a, u64 b) | |
316 | { | |
317 | u64 old; | |
318 | ||
319 | old = a; | |
320 | a += b; | |
321 | if (old <= a) | |
322 | return a; | |
323 | return ULLONG_MAX; | |
324 | } | |
325 | ||
326 | static u64 au_mul_till_max(u64 a, long mul) | |
327 | { | |
328 | u64 old; | |
329 | ||
330 | old = a; | |
331 | a *= mul; | |
332 | if (old <= a) | |
333 | return a; | |
334 | return ULLONG_MAX; | |
335 | } | |
336 | ||
337 | static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf) | |
338 | { | |
339 | int err; | |
340 | long bsize, factor; | |
341 | u64 blocks, bfree, bavail, files, ffree; | |
342 | aufs_bindex_t bbot, bindex, i; | |
343 | unsigned char shared; | |
344 | struct path h_path; | |
345 | struct super_block *h_sb; | |
346 | ||
347 | err = 0; | |
348 | bsize = LONG_MAX; | |
349 | files = 0; | |
350 | ffree = 0; | |
351 | blocks = 0; | |
352 | bfree = 0; | |
353 | bavail = 0; | |
354 | bbot = au_sbbot(sb); | |
355 | for (bindex = 0; bindex <= bbot; bindex++) { | |
356 | h_path.mnt = au_sbr_mnt(sb, bindex); | |
357 | h_sb = h_path.mnt->mnt_sb; | |
358 | shared = 0; | |
359 | for (i = 0; !shared && i < bindex; i++) | |
360 | shared = (au_sbr_sb(sb, i) == h_sb); | |
361 | if (shared) | |
362 | continue; | |
363 | ||
364 | /* sb->s_root for NFS is unreliable */ | |
365 | h_path.dentry = h_path.mnt->mnt_root; | |
366 | err = vfs_statfs(&h_path, buf); | |
367 | if (unlikely(err)) | |
368 | goto out; | |
369 | ||
370 | if (bsize > buf->f_bsize) { | |
371 | /* | |
372 | * we will reduce bsize, so we have to expand blocks | |
373 | * etc. to match them again | |
374 | */ | |
375 | factor = (bsize / buf->f_bsize); | |
376 | blocks = au_mul_till_max(blocks, factor); | |
377 | bfree = au_mul_till_max(bfree, factor); | |
378 | bavail = au_mul_till_max(bavail, factor); | |
379 | bsize = buf->f_bsize; | |
380 | } | |
381 | ||
382 | factor = (buf->f_bsize / bsize); | |
383 | blocks = au_add_till_max(blocks, | |
384 | au_mul_till_max(buf->f_blocks, factor)); | |
385 | bfree = au_add_till_max(bfree, | |
386 | au_mul_till_max(buf->f_bfree, factor)); | |
387 | bavail = au_add_till_max(bavail, | |
388 | au_mul_till_max(buf->f_bavail, factor)); | |
389 | files = au_add_till_max(files, buf->f_files); | |
390 | ffree = au_add_till_max(ffree, buf->f_ffree); | |
391 | } | |
392 | ||
393 | buf->f_bsize = bsize; | |
394 | buf->f_blocks = blocks; | |
395 | buf->f_bfree = bfree; | |
396 | buf->f_bavail = bavail; | |
397 | buf->f_files = files; | |
398 | buf->f_ffree = ffree; | |
399 | buf->f_frsize = 0; | |
400 | ||
401 | out: | |
402 | return err; | |
403 | } | |
404 | ||
405 | static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) | |
406 | { | |
407 | int err; | |
408 | struct path h_path; | |
409 | struct super_block *sb; | |
410 | ||
411 | /* lock free root dinfo */ | |
412 | sb = dentry->d_sb; | |
413 | si_noflush_read_lock(sb); | |
414 | if (!au_opt_test(au_mntflags(sb), SUM)) { | |
415 | /* sb->s_root for NFS is unreliable */ | |
416 | h_path.mnt = au_sbr_mnt(sb, 0); | |
417 | h_path.dentry = h_path.mnt->mnt_root; | |
418 | err = vfs_statfs(&h_path, buf); | |
419 | } else | |
420 | err = au_statfs_sum(sb, buf); | |
421 | si_read_unlock(sb); | |
422 | ||
423 | if (!err) { | |
424 | buf->f_type = AUFS_SUPER_MAGIC; | |
425 | buf->f_namelen = AUFS_MAX_NAMELEN; | |
426 | memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); | |
427 | } | |
428 | /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ | |
429 | ||
430 | return err; | |
431 | } | |
432 | ||
433 | /* ---------------------------------------------------------------------- */ | |
434 | ||
435 | static int aufs_sync_fs(struct super_block *sb, int wait) | |
436 | { | |
437 | int err, e; | |
438 | aufs_bindex_t bbot, bindex; | |
439 | struct au_branch *br; | |
440 | struct super_block *h_sb; | |
441 | ||
442 | err = 0; | |
443 | si_noflush_read_lock(sb); | |
444 | bbot = au_sbbot(sb); | |
445 | for (bindex = 0; bindex <= bbot; bindex++) { | |
446 | br = au_sbr(sb, bindex); | |
447 | if (!au_br_writable(br->br_perm)) | |
448 | continue; | |
449 | ||
450 | h_sb = au_sbr_sb(sb, bindex); | |
451 | e = vfsub_sync_filesystem(h_sb, wait); | |
452 | if (unlikely(e && !err)) | |
453 | err = e; | |
454 | /* go on even if an error happens */ | |
455 | } | |
456 | si_read_unlock(sb); | |
457 | ||
458 | return err; | |
459 | } | |
460 | ||
461 | /* ---------------------------------------------------------------------- */ | |
462 | ||
463 | /* final actions when unmounting a file system */ | |
464 | static void aufs_put_super(struct super_block *sb) | |
465 | { | |
466 | struct au_sbinfo *sbinfo; | |
467 | ||
468 | sbinfo = au_sbi(sb); | |
469 | if (!sbinfo) | |
470 | return; | |
471 | ||
472 | dbgaufs_si_fin(sbinfo); | |
473 | kobject_put(&sbinfo->si_kobj); | |
474 | } | |
475 | ||
476 | /* ---------------------------------------------------------------------- */ | |
477 | ||
478 | void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, | |
479 | struct super_block *sb, void *arg) | |
480 | { | |
481 | void *array; | |
482 | unsigned long long n, sz; | |
483 | ||
484 | array = NULL; | |
485 | n = 0; | |
486 | if (!*hint) | |
487 | goto out; | |
488 | ||
489 | if (*hint > ULLONG_MAX / sizeof(array)) { | |
490 | array = ERR_PTR(-EMFILE); | |
491 | pr_err("hint %llu\n", *hint); | |
492 | goto out; | |
493 | } | |
494 | ||
495 | sz = sizeof(array) * *hint; | |
496 | array = kzalloc(sz, GFP_NOFS); | |
497 | if (unlikely(!array)) | |
498 | array = vzalloc(sz); | |
499 | if (unlikely(!array)) { | |
500 | array = ERR_PTR(-ENOMEM); | |
501 | goto out; | |
502 | } | |
503 | ||
504 | n = cb(sb, array, *hint, arg); | |
505 | AuDebugOn(n > *hint); | |
506 | ||
507 | out: | |
508 | *hint = n; | |
509 | return array; | |
510 | } | |
511 | ||
512 | static unsigned long long au_iarray_cb(struct super_block *sb, void *a, | |
513 | unsigned long long max __maybe_unused, | |
514 | void *arg) | |
515 | { | |
516 | unsigned long long n; | |
517 | struct inode **p, *inode; | |
518 | struct list_head *head; | |
519 | ||
520 | n = 0; | |
521 | p = a; | |
522 | head = arg; | |
523 | spin_lock(&sb->s_inode_list_lock); | |
524 | list_for_each_entry(inode, head, i_sb_list) { | |
525 | if (!au_is_bad_inode(inode) | |
526 | && au_ii(inode)->ii_btop >= 0) { | |
527 | spin_lock(&inode->i_lock); | |
528 | if (atomic_read(&inode->i_count)) { | |
529 | au_igrab(inode); | |
530 | *p++ = inode; | |
531 | n++; | |
532 | AuDebugOn(n > max); | |
533 | } | |
534 | spin_unlock(&inode->i_lock); | |
535 | } | |
536 | } | |
537 | spin_unlock(&sb->s_inode_list_lock); | |
538 | ||
539 | return n; | |
540 | } | |
541 | ||
542 | struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max) | |
543 | { | |
544 | *max = au_ninodes(sb); | |
545 | return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes); | |
546 | } | |
547 | ||
548 | void au_iarray_free(struct inode **a, unsigned long long max) | |
549 | { | |
550 | unsigned long long ull; | |
551 | ||
552 | for (ull = 0; ull < max; ull++) | |
553 | iput(a[ull]); | |
554 | kvfree(a); | |
555 | } | |
556 | ||
557 | /* ---------------------------------------------------------------------- */ | |
558 | ||
559 | /* | |
560 | * refresh dentry and inode at remount time. | |
561 | */ | |
562 | /* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */ | |
563 | static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags, | |
564 | struct dentry *parent) | |
565 | { | |
566 | int err; | |
567 | ||
568 | di_write_lock_child(dentry); | |
569 | di_read_lock_parent(parent, AuLock_IR); | |
570 | err = au_refresh_dentry(dentry, parent); | |
571 | if (!err && dir_flags) | |
572 | au_hn_reset(d_inode(dentry), dir_flags); | |
573 | di_read_unlock(parent, AuLock_IR); | |
574 | di_write_unlock(dentry); | |
575 | ||
576 | return err; | |
577 | } | |
578 | ||
579 | static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen, | |
580 | struct au_sbinfo *sbinfo, | |
581 | const unsigned int dir_flags, unsigned int do_idop) | |
582 | { | |
583 | int err; | |
584 | struct dentry *parent; | |
585 | ||
586 | err = 0; | |
587 | parent = dget_parent(dentry); | |
588 | if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) { | |
589 | if (d_really_is_positive(dentry)) { | |
590 | if (!d_is_dir(dentry)) | |
591 | err = au_do_refresh(dentry, /*dir_flags*/0, | |
592 | parent); | |
593 | else { | |
594 | err = au_do_refresh(dentry, dir_flags, parent); | |
595 | if (unlikely(err)) | |
596 | au_fset_si(sbinfo, FAILED_REFRESH_DIR); | |
597 | } | |
598 | } else | |
599 | err = au_do_refresh(dentry, /*dir_flags*/0, parent); | |
600 | AuDbgDentry(dentry); | |
601 | } | |
602 | dput(parent); | |
603 | ||
604 | if (!err) { | |
605 | if (do_idop) | |
606 | au_refresh_dop(dentry, /*force_reval*/0); | |
607 | } else | |
608 | au_refresh_dop(dentry, /*force_reval*/1); | |
609 | ||
610 | AuTraceErr(err); | |
611 | return err; | |
612 | } | |
613 | ||
614 | static int au_refresh_d(struct super_block *sb, unsigned int do_idop) | |
615 | { | |
616 | int err, i, j, ndentry, e; | |
617 | unsigned int sigen; | |
618 | struct au_dcsub_pages dpages; | |
619 | struct au_dpage *dpage; | |
620 | struct dentry **dentries, *d; | |
621 | struct au_sbinfo *sbinfo; | |
622 | struct dentry *root = sb->s_root; | |
623 | const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1); | |
624 | ||
625 | if (do_idop) | |
626 | au_refresh_dop(root, /*force_reval*/0); | |
627 | ||
628 | err = au_dpages_init(&dpages, GFP_NOFS); | |
629 | if (unlikely(err)) | |
630 | goto out; | |
631 | err = au_dcsub_pages(&dpages, root, NULL, NULL); | |
632 | if (unlikely(err)) | |
633 | goto out_dpages; | |
634 | ||
635 | sigen = au_sigen(sb); | |
636 | sbinfo = au_sbi(sb); | |
637 | for (i = 0; i < dpages.ndpage; i++) { | |
638 | dpage = dpages.dpages + i; | |
639 | dentries = dpage->dentries; | |
640 | ndentry = dpage->ndentry; | |
641 | for (j = 0; j < ndentry; j++) { | |
642 | d = dentries[j]; | |
643 | e = au_do_refresh_d(d, sigen, sbinfo, dir_flags, | |
644 | do_idop); | |
645 | if (unlikely(e && !err)) | |
646 | err = e; | |
647 | /* go on even err */ | |
648 | } | |
649 | } | |
650 | ||
651 | out_dpages: | |
652 | au_dpages_free(&dpages); | |
653 | out: | |
654 | return err; | |
655 | } | |
656 | ||
657 | static int au_refresh_i(struct super_block *sb, unsigned int do_idop) | |
658 | { | |
659 | int err, e; | |
660 | unsigned int sigen; | |
661 | unsigned long long max, ull; | |
662 | struct inode *inode, **array; | |
663 | ||
664 | array = au_iarray_alloc(sb, &max); | |
665 | err = PTR_ERR(array); | |
666 | if (IS_ERR(array)) | |
667 | goto out; | |
668 | ||
669 | err = 0; | |
670 | sigen = au_sigen(sb); | |
671 | for (ull = 0; ull < max; ull++) { | |
672 | inode = array[ull]; | |
673 | if (unlikely(!inode)) | |
674 | break; | |
675 | ||
676 | e = 0; | |
677 | ii_write_lock_child(inode); | |
678 | if (au_iigen(inode, NULL) != sigen) { | |
679 | e = au_refresh_hinode_self(inode); | |
680 | if (unlikely(e)) { | |
681 | au_refresh_iop(inode, /*force_getattr*/1); | |
682 | pr_err("error %d, i%lu\n", e, inode->i_ino); | |
683 | if (!err) | |
684 | err = e; | |
685 | /* go on even if err */ | |
686 | } | |
687 | } | |
688 | if (!e && do_idop) | |
689 | au_refresh_iop(inode, /*force_getattr*/0); | |
690 | ii_write_unlock(inode); | |
691 | } | |
692 | ||
693 | au_iarray_free(array, max); | |
694 | ||
695 | out: | |
696 | return err; | |
697 | } | |
698 | ||
699 | static void au_remount_refresh(struct super_block *sb, unsigned int do_idop) | |
700 | { | |
701 | int err, e; | |
702 | unsigned int udba; | |
703 | aufs_bindex_t bindex, bbot; | |
704 | struct dentry *root; | |
705 | struct inode *inode; | |
706 | struct au_branch *br; | |
707 | struct au_sbinfo *sbi; | |
708 | ||
709 | au_sigen_inc(sb); | |
710 | sbi = au_sbi(sb); | |
711 | au_fclr_si(sbi, FAILED_REFRESH_DIR); | |
712 | ||
713 | root = sb->s_root; | |
714 | DiMustNoWaiters(root); | |
715 | inode = d_inode(root); | |
716 | IiMustNoWaiters(inode); | |
717 | ||
718 | udba = au_opt_udba(sb); | |
719 | bbot = au_sbbot(sb); | |
720 | for (bindex = 0; bindex <= bbot; bindex++) { | |
721 | br = au_sbr(sb, bindex); | |
722 | err = au_hnotify_reset_br(udba, br, br->br_perm); | |
723 | if (unlikely(err)) | |
724 | AuIOErr("hnotify failed on br %d, %d, ignored\n", | |
725 | bindex, err); | |
726 | /* go on even if err */ | |
727 | } | |
728 | au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1)); | |
729 | ||
730 | if (do_idop) { | |
731 | if (au_ftest_si(sbi, NO_DREVAL)) { | |
732 | AuDebugOn(sb->s_d_op == &aufs_dop_noreval); | |
733 | sb->s_d_op = &aufs_dop_noreval; | |
734 | AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr); | |
735 | sbi->si_iop_array = aufs_iop_nogetattr; | |
736 | } else { | |
737 | AuDebugOn(sb->s_d_op == &aufs_dop); | |
738 | sb->s_d_op = &aufs_dop; | |
739 | AuDebugOn(sbi->si_iop_array == aufs_iop); | |
740 | sbi->si_iop_array = aufs_iop; | |
741 | } | |
742 | pr_info("reset to %pf and %pf\n", | |
743 | sb->s_d_op, sbi->si_iop_array); | |
744 | } | |
745 | ||
746 | di_write_unlock(root); | |
747 | err = au_refresh_d(sb, do_idop); | |
748 | e = au_refresh_i(sb, do_idop); | |
749 | if (unlikely(e && !err)) | |
750 | err = e; | |
751 | /* aufs_write_lock() calls ..._child() */ | |
752 | di_write_lock_child(root); | |
753 | ||
754 | au_cpup_attr_all(inode, /*force*/1); | |
755 | ||
756 | if (unlikely(err)) | |
757 | AuIOErr("refresh failed, ignored, %d\n", err); | |
758 | } | |
759 | ||
760 | /* stop extra interpretation of errno in mount(8), and strange error messages */ | |
761 | static int cvt_err(int err) | |
762 | { | |
763 | AuTraceErr(err); | |
764 | ||
765 | switch (err) { | |
766 | case -ENOENT: | |
767 | case -ENOTDIR: | |
768 | case -EEXIST: | |
769 | case -EIO: | |
770 | err = -EINVAL; | |
771 | } | |
772 | return err; | |
773 | } | |
774 | ||
775 | static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) | |
776 | { | |
777 | int err, do_dx; | |
778 | unsigned int mntflags; | |
779 | struct au_opts opts = { | |
780 | .opt = NULL | |
781 | }; | |
782 | struct dentry *root; | |
783 | struct inode *inode; | |
784 | struct au_sbinfo *sbinfo; | |
785 | ||
786 | err = 0; | |
787 | root = sb->s_root; | |
788 | if (!data || !*data) { | |
789 | err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); | |
790 | if (!err) { | |
791 | di_write_lock_child(root); | |
792 | err = au_opts_verify(sb, *flags, /*pending*/0); | |
793 | aufs_write_unlock(root); | |
794 | } | |
795 | goto out; | |
796 | } | |
797 | ||
798 | err = -ENOMEM; | |
799 | opts.opt = (void *)__get_free_page(GFP_NOFS); | |
800 | if (unlikely(!opts.opt)) | |
801 | goto out; | |
802 | opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); | |
803 | opts.flags = AuOpts_REMOUNT; | |
804 | opts.sb_flags = *flags; | |
805 | ||
806 | /* parse it before aufs lock */ | |
807 | err = au_opts_parse(sb, data, &opts); | |
808 | if (unlikely(err)) | |
809 | goto out_opts; | |
810 | ||
811 | sbinfo = au_sbi(sb); | |
812 | inode = d_inode(root); | |
813 | inode_lock(inode); | |
814 | err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); | |
815 | if (unlikely(err)) | |
816 | goto out_mtx; | |
817 | di_write_lock_child(root); | |
818 | ||
819 | /* au_opts_remount() may return an error */ | |
820 | err = au_opts_remount(sb, &opts); | |
821 | au_opts_free(&opts); | |
822 | ||
823 | if (au_ftest_opts(opts.flags, REFRESH)) | |
824 | au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP)); | |
825 | ||
826 | if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) { | |
827 | mntflags = au_mntflags(sb); | |
828 | do_dx = !!au_opt_test(mntflags, DIO); | |
829 | au_dy_arefresh(do_dx); | |
830 | } | |
831 | ||
832 | au_fhsm_wrote_all(sb, /*force*/1); /* ?? */ | |
833 | aufs_write_unlock(root); | |
834 | ||
835 | out_mtx: | |
836 | inode_unlock(inode); | |
837 | out_opts: | |
838 | free_page((unsigned long)opts.opt); | |
839 | out: | |
840 | err = cvt_err(err); | |
841 | AuTraceErr(err); | |
842 | return err; | |
843 | } | |
844 | ||
845 | static const struct super_operations aufs_sop = { | |
846 | .alloc_inode = aufs_alloc_inode, | |
847 | .destroy_inode = aufs_destroy_inode, | |
848 | /* always deleting, no clearing */ | |
849 | .drop_inode = generic_delete_inode, | |
850 | .show_options = aufs_show_options, | |
851 | .statfs = aufs_statfs, | |
852 | .put_super = aufs_put_super, | |
853 | .sync_fs = aufs_sync_fs, | |
854 | .remount_fs = aufs_remount_fs, | |
855 | #ifdef CONFIG_AUFS_BDEV_LOOP | |
856 | .real_loop = aufs_real_loop | |
857 | #endif | |
858 | }; | |
859 | ||
860 | /* ---------------------------------------------------------------------- */ | |
861 | ||
862 | static int alloc_root(struct super_block *sb) | |
863 | { | |
864 | int err; | |
865 | struct inode *inode; | |
866 | struct dentry *root; | |
867 | ||
868 | err = -ENOMEM; | |
869 | inode = au_iget_locked(sb, AUFS_ROOT_INO); | |
870 | err = PTR_ERR(inode); | |
871 | if (IS_ERR(inode)) | |
872 | goto out; | |
873 | ||
874 | inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */ | |
875 | inode->i_fop = &aufs_dir_fop; | |
876 | inode->i_mode = S_IFDIR; | |
877 | set_nlink(inode, 2); | |
878 | unlock_new_inode(inode); | |
879 | ||
880 | root = d_make_root(inode); | |
881 | if (unlikely(!root)) | |
882 | goto out; | |
883 | err = PTR_ERR(root); | |
884 | if (IS_ERR(root)) | |
885 | goto out; | |
886 | ||
887 | err = au_di_init(root); | |
888 | if (!err) { | |
889 | sb->s_root = root; | |
890 | return 0; /* success */ | |
891 | } | |
892 | dput(root); | |
893 | ||
894 | out: | |
895 | return err; | |
896 | } | |
897 | ||
898 | static int aufs_fill_super(struct super_block *sb, void *raw_data, | |
899 | int silent __maybe_unused) | |
900 | { | |
901 | int err; | |
902 | struct au_opts opts = { | |
903 | .opt = NULL | |
904 | }; | |
905 | struct au_sbinfo *sbinfo; | |
906 | struct dentry *root; | |
907 | struct inode *inode; | |
908 | char *arg = raw_data; | |
909 | ||
910 | if (unlikely(!arg || !*arg)) { | |
911 | err = -EINVAL; | |
912 | pr_err("no arg\n"); | |
913 | goto out; | |
914 | } | |
915 | ||
916 | err = -ENOMEM; | |
917 | opts.opt = (void *)__get_free_page(GFP_NOFS); | |
918 | if (unlikely(!opts.opt)) | |
919 | goto out; | |
920 | opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); | |
921 | opts.sb_flags = sb->s_flags; | |
922 | ||
923 | err = au_si_alloc(sb); | |
924 | if (unlikely(err)) | |
925 | goto out_opts; | |
926 | sbinfo = au_sbi(sb); | |
927 | ||
928 | /* all timestamps always follow the ones on the branch */ | |
929 | sb->s_flags |= SB_NOATIME | SB_NODIRATIME; | |
930 | sb->s_op = &aufs_sop; | |
931 | sb->s_d_op = &aufs_dop; | |
932 | sb->s_magic = AUFS_SUPER_MAGIC; | |
933 | sb->s_maxbytes = 0; | |
934 | sb->s_stack_depth = 1; | |
935 | au_export_init(sb); | |
936 | au_xattr_init(sb); | |
937 | ||
938 | err = alloc_root(sb); | |
939 | if (unlikely(err)) { | |
940 | si_write_unlock(sb); | |
941 | goto out_info; | |
942 | } | |
943 | root = sb->s_root; | |
944 | inode = d_inode(root); | |
945 | ||
946 | /* | |
947 | * actually we can parse options regardless aufs lock here. | |
948 | * but at remount time, parsing must be done before aufs lock. | |
949 | * so we follow the same rule. | |
950 | */ | |
951 | ii_write_lock_parent(inode); | |
952 | aufs_write_unlock(root); | |
953 | err = au_opts_parse(sb, arg, &opts); | |
954 | if (unlikely(err)) | |
955 | goto out_root; | |
956 | ||
957 | /* lock vfs_inode first, then aufs. */ | |
958 | inode_lock(inode); | |
959 | aufs_write_lock(root); | |
960 | err = au_opts_mount(sb, &opts); | |
961 | au_opts_free(&opts); | |
962 | if (!err && au_ftest_si(sbinfo, NO_DREVAL)) { | |
963 | sb->s_d_op = &aufs_dop_noreval; | |
964 | pr_info("%pf\n", sb->s_d_op); | |
965 | au_refresh_dop(root, /*force_reval*/0); | |
966 | sbinfo->si_iop_array = aufs_iop_nogetattr; | |
967 | au_refresh_iop(inode, /*force_getattr*/0); | |
968 | } | |
969 | aufs_write_unlock(root); | |
970 | inode_unlock(inode); | |
971 | if (!err) | |
972 | goto out_opts; /* success */ | |
973 | ||
974 | out_root: | |
975 | dput(root); | |
976 | sb->s_root = NULL; | |
977 | out_info: | |
978 | dbgaufs_si_fin(sbinfo); | |
979 | kobject_put(&sbinfo->si_kobj); | |
980 | sb->s_fs_info = NULL; | |
981 | out_opts: | |
982 | free_page((unsigned long)opts.opt); | |
983 | out: | |
984 | AuTraceErr(err); | |
985 | err = cvt_err(err); | |
986 | AuTraceErr(err); | |
987 | return err; | |
988 | } | |
989 | ||
990 | /* ---------------------------------------------------------------------- */ | |
991 | ||
992 | static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags, | |
993 | const char *dev_name __maybe_unused, | |
994 | void *raw_data) | |
995 | { | |
996 | struct dentry *root; | |
997 | struct super_block *sb; | |
998 | ||
999 | /* all timestamps always follow the ones on the branch */ | |
1000 | /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ | |
1001 | root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super); | |
1002 | if (IS_ERR(root)) | |
1003 | goto out; | |
1004 | ||
1005 | sb = root->d_sb; | |
1006 | si_write_lock(sb, !AuLock_FLUSH); | |
1007 | sysaufs_brs_add(sb, 0); | |
1008 | si_write_unlock(sb); | |
1009 | au_sbilist_add(sb); | |
1010 | ||
1011 | out: | |
1012 | return root; | |
1013 | } | |
1014 | ||
1015 | static void aufs_kill_sb(struct super_block *sb) | |
1016 | { | |
1017 | struct au_sbinfo *sbinfo; | |
1018 | ||
1019 | sbinfo = au_sbi(sb); | |
1020 | if (sbinfo) { | |
1021 | au_sbilist_del(sb); | |
1022 | aufs_write_lock(sb->s_root); | |
1023 | au_fhsm_fin(sb); | |
1024 | if (sbinfo->si_wbr_create_ops->fin) | |
1025 | sbinfo->si_wbr_create_ops->fin(sb); | |
1026 | if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) { | |
1027 | au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE); | |
1028 | au_remount_refresh(sb, /*do_idop*/0); | |
1029 | } | |
1030 | if (au_opt_test(sbinfo->si_mntflags, PLINK)) | |
1031 | au_plink_put(sb, /*verbose*/1); | |
1032 | au_xino_clr(sb); | |
1033 | au_dr_opt_flush(sb); | |
1034 | sbinfo->si_sb = NULL; | |
1035 | aufs_write_unlock(sb->s_root); | |
1036 | au_nwt_flush(&sbinfo->si_nowait); | |
1037 | } | |
1038 | kill_anon_super(sb); | |
1039 | } | |
1040 | ||
1041 | struct file_system_type aufs_fs_type = { | |
1042 | .name = AUFS_FSTYPE, | |
1043 | /* a race between rename and others */ | |
1044 | .fs_flags = FS_RENAME_DOES_D_MOVE, | |
1045 | .mount = aufs_mount, | |
1046 | .kill_sb = aufs_kill_sb, | |
1047 | /* no need to __module_get() and module_put(). */ | |
1048 | .owner = THIS_MODULE, | |
1049 | }; |