]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - fs/aufs/hnotify.c
UBUNTU: ubuntu: vbox -- update to 5.2.6-dfsg-5
[mirror_ubuntu-bionic-kernel.git] / fs / aufs / hnotify.c
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 * abstraction to notify the direct changes on lower directories
20 */
21
22 #include "aufs.h"
23
24 int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
25 {
26 int err;
27 struct au_hnotify *hn;
28
29 err = -ENOMEM;
30 hn = au_cache_alloc_hnotify();
31 if (hn) {
32 hn->hn_aufs_inode = inode;
33 hinode->hi_notify = hn;
34 err = au_hnotify_op.alloc(hinode);
35 AuTraceErr(err);
36 if (unlikely(err)) {
37 hinode->hi_notify = NULL;
38 au_cache_free_hnotify(hn);
39 /*
40 * The upper dir was removed by udba, but the same named
41 * dir left. In this case, aufs assignes a new inode
42 * number and set the monitor again.
43 * For the lower dir, the old monitnor is still left.
44 */
45 if (err == -EEXIST)
46 err = 0;
47 }
48 }
49
50 AuTraceErr(err);
51 return err;
52 }
53
54 void au_hn_free(struct au_hinode *hinode)
55 {
56 struct au_hnotify *hn;
57
58 hn = hinode->hi_notify;
59 if (hn) {
60 hinode->hi_notify = NULL;
61 if (au_hnotify_op.free(hinode, hn))
62 au_cache_free_hnotify(hn);
63 }
64 }
65
66 /* ---------------------------------------------------------------------- */
67
68 void au_hn_ctl(struct au_hinode *hinode, int do_set)
69 {
70 if (hinode->hi_notify)
71 au_hnotify_op.ctl(hinode, do_set);
72 }
73
74 void au_hn_reset(struct inode *inode, unsigned int flags)
75 {
76 aufs_bindex_t bindex, bbot;
77 struct inode *hi;
78 struct dentry *iwhdentry;
79
80 bbot = au_ibbot(inode);
81 for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
82 hi = au_h_iptr(inode, bindex);
83 if (!hi)
84 continue;
85
86 /* inode_lock_nested(hi, AuLsc_I_CHILD); */
87 iwhdentry = au_hi_wh(inode, bindex);
88 if (iwhdentry)
89 dget(iwhdentry);
90 au_igrab(hi);
91 au_set_h_iptr(inode, bindex, NULL, 0);
92 au_set_h_iptr(inode, bindex, au_igrab(hi),
93 flags & ~AuHi_XINO);
94 iput(hi);
95 dput(iwhdentry);
96 /* inode_unlock(hi); */
97 }
98 }
99
100 /* ---------------------------------------------------------------------- */
101
102 static int hn_xino(struct inode *inode, struct inode *h_inode)
103 {
104 int err;
105 aufs_bindex_t bindex, bbot, bfound, btop;
106 struct inode *h_i;
107
108 err = 0;
109 if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
110 pr_warn("branch root dir was changed\n");
111 goto out;
112 }
113
114 bfound = -1;
115 bbot = au_ibbot(inode);
116 btop = au_ibtop(inode);
117 #if 0 /* reserved for future use */
118 if (bindex == bbot) {
119 /* keep this ino in rename case */
120 goto out;
121 }
122 #endif
123 for (bindex = btop; bindex <= bbot; bindex++)
124 if (au_h_iptr(inode, bindex) == h_inode) {
125 bfound = bindex;
126 break;
127 }
128 if (bfound < 0)
129 goto out;
130
131 for (bindex = btop; bindex <= bbot; bindex++) {
132 h_i = au_h_iptr(inode, bindex);
133 if (!h_i)
134 continue;
135
136 err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
137 /* ignore this error */
138 /* bad action? */
139 }
140
141 /* children inode number will be broken */
142
143 out:
144 AuTraceErr(err);
145 return err;
146 }
147
148 static int hn_gen_tree(struct dentry *dentry)
149 {
150 int err, i, j, ndentry;
151 struct au_dcsub_pages dpages;
152 struct au_dpage *dpage;
153 struct dentry **dentries;
154
155 err = au_dpages_init(&dpages, GFP_NOFS);
156 if (unlikely(err))
157 goto out;
158 err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
159 if (unlikely(err))
160 goto out_dpages;
161
162 for (i = 0; i < dpages.ndpage; i++) {
163 dpage = dpages.dpages + i;
164 dentries = dpage->dentries;
165 ndentry = dpage->ndentry;
166 for (j = 0; j < ndentry; j++) {
167 struct dentry *d;
168
169 d = dentries[j];
170 if (IS_ROOT(d))
171 continue;
172
173 au_digen_dec(d);
174 if (d_really_is_positive(d))
175 /* todo: reset children xino?
176 cached children only? */
177 au_iigen_dec(d_inode(d));
178 }
179 }
180
181 out_dpages:
182 au_dpages_free(&dpages);
183
184 #if 0
185 /* discard children */
186 dentry_unhash(dentry);
187 dput(dentry);
188 #endif
189 out:
190 return err;
191 }
192
193 /*
194 * return 0 if processed.
195 */
196 static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
197 const unsigned int isdir)
198 {
199 int err;
200 struct dentry *d;
201 struct qstr *dname;
202
203 err = 1;
204 if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
205 pr_warn("branch root dir was changed\n");
206 err = 0;
207 goto out;
208 }
209
210 if (!isdir) {
211 AuDebugOn(!name);
212 au_iigen_dec(inode);
213 spin_lock(&inode->i_lock);
214 hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
215 spin_lock(&d->d_lock);
216 dname = &d->d_name;
217 if (dname->len != nlen
218 && memcmp(dname->name, name, nlen)) {
219 spin_unlock(&d->d_lock);
220 continue;
221 }
222 err = 0;
223 au_digen_dec(d);
224 spin_unlock(&d->d_lock);
225 break;
226 }
227 spin_unlock(&inode->i_lock);
228 } else {
229 au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
230 d = d_find_any_alias(inode);
231 if (!d) {
232 au_iigen_dec(inode);
233 goto out;
234 }
235
236 spin_lock(&d->d_lock);
237 dname = &d->d_name;
238 if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
239 spin_unlock(&d->d_lock);
240 err = hn_gen_tree(d);
241 spin_lock(&d->d_lock);
242 }
243 spin_unlock(&d->d_lock);
244 dput(d);
245 }
246
247 out:
248 AuTraceErr(err);
249 return err;
250 }
251
252 static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
253 {
254 int err;
255
256 if (IS_ROOT(dentry)) {
257 pr_warn("branch root dir was changed\n");
258 return 0;
259 }
260
261 err = 0;
262 if (!isdir) {
263 au_digen_dec(dentry);
264 if (d_really_is_positive(dentry))
265 au_iigen_dec(d_inode(dentry));
266 } else {
267 au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
268 if (d_really_is_positive(dentry))
269 err = hn_gen_tree(dentry);
270 }
271
272 AuTraceErr(err);
273 return err;
274 }
275
276 /* ---------------------------------------------------------------------- */
277
278 /* hnotify job flags */
279 #define AuHnJob_XINO0 1
280 #define AuHnJob_GEN (1 << 1)
281 #define AuHnJob_DIRENT (1 << 2)
282 #define AuHnJob_ISDIR (1 << 3)
283 #define AuHnJob_TRYXINO0 (1 << 4)
284 #define AuHnJob_MNTPNT (1 << 5)
285 #define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
286 #define au_fset_hnjob(flags, name) \
287 do { (flags) |= AuHnJob_##name; } while (0)
288 #define au_fclr_hnjob(flags, name) \
289 do { (flags) &= ~AuHnJob_##name; } while (0)
290
291 enum {
292 AuHn_CHILD,
293 AuHn_PARENT,
294 AuHnLast
295 };
296
297 struct au_hnotify_args {
298 struct inode *h_dir, *dir, *h_child_inode;
299 u32 mask;
300 unsigned int flags[AuHnLast];
301 unsigned int h_child_nlen;
302 char h_child_name[];
303 };
304
305 struct hn_job_args {
306 unsigned int flags;
307 struct inode *inode, *h_inode, *dir, *h_dir;
308 struct dentry *dentry;
309 char *h_name;
310 int h_nlen;
311 };
312
313 static int hn_job(struct hn_job_args *a)
314 {
315 const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
316 int e;
317
318 /* reset xino */
319 if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
320 hn_xino(a->inode, a->h_inode); /* ignore this error */
321
322 if (au_ftest_hnjob(a->flags, TRYXINO0)
323 && a->inode
324 && a->h_inode) {
325 vfsub_inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
326 if (!a->h_inode->i_nlink
327 && !(a->h_inode->i_state & I_LINKABLE))
328 hn_xino(a->inode, a->h_inode); /* ignore this error */
329 inode_unlock_shared(a->h_inode);
330 }
331
332 /* make the generation obsolete */
333 if (au_ftest_hnjob(a->flags, GEN)) {
334 e = -1;
335 if (a->inode)
336 e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
337 isdir);
338 if (e && a->dentry)
339 hn_gen_by_name(a->dentry, isdir);
340 /* ignore this error */
341 }
342
343 /* make dir entries obsolete */
344 if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
345 struct au_vdir *vdir;
346
347 vdir = au_ivdir(a->inode);
348 if (vdir)
349 vdir->vd_jiffy = 0;
350 /* IMustLock(a->inode); */
351 /* a->inode->i_version++; */
352 }
353
354 /* can do nothing but warn */
355 if (au_ftest_hnjob(a->flags, MNTPNT)
356 && a->dentry
357 && d_mountpoint(a->dentry))
358 pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
359
360 return 0;
361 }
362
363 /* ---------------------------------------------------------------------- */
364
365 static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
366 struct inode *dir)
367 {
368 struct dentry *dentry, *d, *parent;
369 struct qstr *dname;
370
371 parent = d_find_any_alias(dir);
372 if (!parent)
373 return NULL;
374
375 dentry = NULL;
376 spin_lock(&parent->d_lock);
377 list_for_each_entry(d, &parent->d_subdirs, d_child) {
378 /* AuDbg("%pd\n", d); */
379 spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
380 dname = &d->d_name;
381 if (dname->len != nlen || memcmp(dname->name, name, nlen))
382 goto cont_unlock;
383 if (au_di(d))
384 au_digen_dec(d);
385 else
386 goto cont_unlock;
387 if (au_dcount(d) > 0) {
388 dentry = dget_dlock(d);
389 spin_unlock(&d->d_lock);
390 break;
391 }
392
393 cont_unlock:
394 spin_unlock(&d->d_lock);
395 }
396 spin_unlock(&parent->d_lock);
397 dput(parent);
398
399 if (dentry)
400 di_write_lock_child(dentry);
401
402 return dentry;
403 }
404
405 static struct inode *lookup_wlock_by_ino(struct super_block *sb,
406 aufs_bindex_t bindex, ino_t h_ino)
407 {
408 struct inode *inode;
409 ino_t ino;
410 int err;
411
412 inode = NULL;
413 err = au_xino_read(sb, bindex, h_ino, &ino);
414 if (!err && ino)
415 inode = ilookup(sb, ino);
416 if (!inode)
417 goto out;
418
419 if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
420 pr_warn("wrong root branch\n");
421 iput(inode);
422 inode = NULL;
423 goto out;
424 }
425
426 ii_write_lock_child(inode);
427
428 out:
429 return inode;
430 }
431
432 static void au_hn_bh(void *_args)
433 {
434 struct au_hnotify_args *a = _args;
435 struct super_block *sb;
436 aufs_bindex_t bindex, bbot, bfound;
437 unsigned char xino, try_iput;
438 int err;
439 struct inode *inode;
440 ino_t h_ino;
441 struct hn_job_args args;
442 struct dentry *dentry;
443 struct au_sbinfo *sbinfo;
444
445 AuDebugOn(!_args);
446 AuDebugOn(!a->h_dir);
447 AuDebugOn(!a->dir);
448 AuDebugOn(!a->mask);
449 AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
450 a->mask, a->dir->i_ino, a->h_dir->i_ino,
451 a->h_child_inode ? a->h_child_inode->i_ino : 0);
452
453 inode = NULL;
454 dentry = NULL;
455 /*
456 * do not lock a->dir->i_mutex here
457 * because of d_revalidate() may cause a deadlock.
458 */
459 sb = a->dir->i_sb;
460 AuDebugOn(!sb);
461 sbinfo = au_sbi(sb);
462 AuDebugOn(!sbinfo);
463 si_write_lock(sb, AuLock_NOPLMW);
464
465 if (au_opt_test(sbinfo->si_mntflags, DIRREN))
466 switch (a->mask & FS_EVENTS_POSS_ON_CHILD) {
467 case FS_MOVED_FROM:
468 case FS_MOVED_TO:
469 AuWarn1("DIRREN with UDBA may not work correctly "
470 "for the direct rename(2)\n");
471 }
472
473 ii_read_lock_parent(a->dir);
474 bfound = -1;
475 bbot = au_ibbot(a->dir);
476 for (bindex = au_ibtop(a->dir); bindex <= bbot; bindex++)
477 if (au_h_iptr(a->dir, bindex) == a->h_dir) {
478 bfound = bindex;
479 break;
480 }
481 ii_read_unlock(a->dir);
482 if (unlikely(bfound < 0))
483 goto out;
484
485 xino = !!au_opt_test(au_mntflags(sb), XINO);
486 h_ino = 0;
487 if (a->h_child_inode)
488 h_ino = a->h_child_inode->i_ino;
489
490 if (a->h_child_nlen
491 && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
492 || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
493 dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
494 a->dir);
495 try_iput = 0;
496 if (dentry && d_really_is_positive(dentry))
497 inode = d_inode(dentry);
498 if (xino && !inode && h_ino
499 && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
500 || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
501 || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
502 inode = lookup_wlock_by_ino(sb, bfound, h_ino);
503 try_iput = 1;
504 }
505
506 args.flags = a->flags[AuHn_CHILD];
507 args.dentry = dentry;
508 args.inode = inode;
509 args.h_inode = a->h_child_inode;
510 args.dir = a->dir;
511 args.h_dir = a->h_dir;
512 args.h_name = a->h_child_name;
513 args.h_nlen = a->h_child_nlen;
514 err = hn_job(&args);
515 if (dentry) {
516 if (au_di(dentry))
517 di_write_unlock(dentry);
518 dput(dentry);
519 }
520 if (inode && try_iput) {
521 ii_write_unlock(inode);
522 iput(inode);
523 }
524
525 ii_write_lock_parent(a->dir);
526 args.flags = a->flags[AuHn_PARENT];
527 args.dentry = NULL;
528 args.inode = a->dir;
529 args.h_inode = a->h_dir;
530 args.dir = NULL;
531 args.h_dir = NULL;
532 args.h_name = NULL;
533 args.h_nlen = 0;
534 err = hn_job(&args);
535 ii_write_unlock(a->dir);
536
537 out:
538 iput(a->h_child_inode);
539 iput(a->h_dir);
540 iput(a->dir);
541 si_write_unlock(sb);
542 au_nwt_done(&sbinfo->si_nowait);
543 kfree(a);
544 }
545
546 /* ---------------------------------------------------------------------- */
547
548 int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
549 struct qstr *h_child_qstr, struct inode *h_child_inode)
550 {
551 int err, len;
552 unsigned int flags[AuHnLast], f;
553 unsigned char isdir, isroot, wh;
554 struct inode *dir;
555 struct au_hnotify_args *args;
556 char *p, *h_child_name;
557
558 err = 0;
559 AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
560 dir = igrab(hnotify->hn_aufs_inode);
561 if (!dir)
562 goto out;
563
564 isroot = (dir->i_ino == AUFS_ROOT_INO);
565 wh = 0;
566 h_child_name = (void *)h_child_qstr->name;
567 len = h_child_qstr->len;
568 if (h_child_name) {
569 if (len > AUFS_WH_PFX_LEN
570 && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
571 h_child_name += AUFS_WH_PFX_LEN;
572 len -= AUFS_WH_PFX_LEN;
573 wh = 1;
574 }
575 }
576
577 isdir = 0;
578 if (h_child_inode)
579 isdir = !!S_ISDIR(h_child_inode->i_mode);
580 flags[AuHn_PARENT] = AuHnJob_ISDIR;
581 flags[AuHn_CHILD] = 0;
582 if (isdir)
583 flags[AuHn_CHILD] = AuHnJob_ISDIR;
584 au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
585 au_fset_hnjob(flags[AuHn_CHILD], GEN);
586 switch (mask & FS_EVENTS_POSS_ON_CHILD) {
587 case FS_MOVED_FROM:
588 case FS_MOVED_TO:
589 au_fset_hnjob(flags[AuHn_CHILD], XINO0);
590 au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
591 /*FALLTHROUGH*/
592 case FS_CREATE:
593 AuDebugOn(!h_child_name);
594 break;
595
596 case FS_DELETE:
597 /*
598 * aufs never be able to get this child inode.
599 * revalidation should be in d_revalidate()
600 * by checking i_nlink, i_generation or d_unhashed().
601 */
602 AuDebugOn(!h_child_name);
603 au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
604 au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
605 break;
606
607 default:
608 AuDebugOn(1);
609 }
610
611 if (wh)
612 h_child_inode = NULL;
613
614 err = -ENOMEM;
615 /* iput() and kfree() will be called in au_hnotify() */
616 args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
617 if (unlikely(!args)) {
618 AuErr1("no memory\n");
619 iput(dir);
620 goto out;
621 }
622 args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
623 args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
624 args->mask = mask;
625 args->dir = dir;
626 args->h_dir = igrab(h_dir);
627 if (h_child_inode)
628 h_child_inode = igrab(h_child_inode); /* can be NULL */
629 args->h_child_inode = h_child_inode;
630 args->h_child_nlen = len;
631 if (len) {
632 p = (void *)args;
633 p += sizeof(*args);
634 memcpy(p, h_child_name, len);
635 p[len] = 0;
636 }
637
638 /* NFS fires the event for silly-renamed one from kworker */
639 f = 0;
640 if (!dir->i_nlink
641 || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
642 f = AuWkq_NEST;
643 err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
644 if (unlikely(err)) {
645 pr_err("wkq %d\n", err);
646 iput(args->h_child_inode);
647 iput(args->h_dir);
648 iput(args->dir);
649 kfree(args);
650 }
651
652 out:
653 return err;
654 }
655
656 /* ---------------------------------------------------------------------- */
657
658 int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
659 {
660 int err;
661
662 AuDebugOn(!(udba & AuOptMask_UDBA));
663
664 err = 0;
665 if (au_hnotify_op.reset_br)
666 err = au_hnotify_op.reset_br(udba, br, perm);
667
668 return err;
669 }
670
671 int au_hnotify_init_br(struct au_branch *br, int perm)
672 {
673 int err;
674
675 err = 0;
676 if (au_hnotify_op.init_br)
677 err = au_hnotify_op.init_br(br, perm);
678
679 return err;
680 }
681
682 void au_hnotify_fin_br(struct au_branch *br)
683 {
684 if (au_hnotify_op.fin_br)
685 au_hnotify_op.fin_br(br);
686 }
687
688 static void au_hn_destroy_cache(void)
689 {
690 kmem_cache_destroy(au_cache[AuCache_HNOTIFY]);
691 au_cache[AuCache_HNOTIFY] = NULL;
692 }
693
694 int __init au_hnotify_init(void)
695 {
696 int err;
697
698 err = -ENOMEM;
699 au_cache[AuCache_HNOTIFY] = AuCache(au_hnotify);
700 if (au_cache[AuCache_HNOTIFY]) {
701 err = 0;
702 if (au_hnotify_op.init)
703 err = au_hnotify_op.init();
704 if (unlikely(err))
705 au_hn_destroy_cache();
706 }
707 AuTraceErr(err);
708 return err;
709 }
710
711 void au_hnotify_fin(void)
712 {
713 if (au_hnotify_op.fin)
714 au_hnotify_op.fin();
715
716 /* cf. au_cache_fin() */
717 if (au_cache[AuCache_HNOTIFY])
718 au_hn_destroy_cache();
719 }