2 * Copyright (C) 2005-2013 Junjiro R. Okajima
4 * This program, aufs is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * abstraction to notify the direct changes on lower directories
25 int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
28 struct au_hnotify *hn;
31 hn = au_cache_alloc_hnotify();
33 hn->hn_aufs_inode = inode;
34 hinode->hi_notify = hn;
35 err = au_hnotify_op.alloc(hinode);
38 hinode->hi_notify = NULL;
39 au_cache_free_hnotify(hn);
41 * The upper dir was removed by udba, but the same named
42 * dir left. In this case, aufs assignes a new inode
43 * number and set the monitor again.
44 * For the lower dir, the old monitnor is still left.
55 void au_hn_free(struct au_hinode *hinode)
57 struct au_hnotify *hn;
59 hn = hinode->hi_notify;
61 hinode->hi_notify = NULL;
62 if (au_hnotify_op.free(hinode, hn))
63 au_cache_free_hnotify(hn);
67 /* ---------------------------------------------------------------------- */
69 void au_hn_ctl(struct au_hinode *hinode, int do_set)
71 if (hinode->hi_notify)
72 au_hnotify_op.ctl(hinode, do_set);
75 void au_hn_reset(struct inode *inode, unsigned int flags)
77 aufs_bindex_t bindex, bend;
79 struct dentry *iwhdentry;
81 bend = au_ibend(inode);
82 for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
83 hi = au_h_iptr(inode, bindex);
87 /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
88 iwhdentry = au_hi_wh(inode, bindex);
92 au_set_h_iptr(inode, bindex, NULL, 0);
93 au_set_h_iptr(inode, bindex, au_igrab(hi),
97 /* mutex_unlock(&hi->i_mutex); */
101 /* ---------------------------------------------------------------------- */
103 static int hn_xino(struct inode *inode, struct inode *h_inode)
106 aufs_bindex_t bindex, bend, bfound, bstart;
110 if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
111 pr_warn("branch root dir was changed\n");
116 bend = au_ibend(inode);
117 bstart = au_ibstart(inode);
118 #if 0 /* reserved for future use */
119 if (bindex == bend) {
120 /* keep this ino in rename case */
124 for (bindex = bstart; bindex <= bend; bindex++)
125 if (au_h_iptr(inode, bindex) == h_inode) {
132 for (bindex = bstart; bindex <= bend; bindex++) {
133 h_i = au_h_iptr(inode, bindex);
137 err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
138 /* ignore this error */
142 /* children inode number will be broken */
149 static int hn_gen_tree(struct dentry *dentry)
151 int err, i, j, ndentry;
152 struct au_dcsub_pages dpages;
153 struct au_dpage *dpage;
154 struct dentry **dentries;
156 err = au_dpages_init(&dpages, GFP_NOFS);
159 err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
163 for (i = 0; i < dpages.ndpage; i++) {
164 dpage = dpages.dpages + i;
165 dentries = dpage->dentries;
166 ndentry = dpage->ndentry;
167 for (j = 0; j < ndentry; j++) {
176 /* todo: reset children xino?
177 cached children only? */
178 au_iigen_dec(d->d_inode);
183 au_dpages_free(&dpages);
186 /* discard children */
187 dentry_unhash(dentry);
195 * return 0 if processed.
197 static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
198 const unsigned int isdir)
205 if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
206 pr_warn("branch root dir was changed\n");
214 spin_lock(&inode->i_lock);
215 list_for_each_entry(d, &inode->i_dentry, d_alias) {
216 spin_lock(&d->d_lock);
218 if (dname->len != nlen
219 && memcmp(dname->name, name, nlen)) {
220 spin_unlock(&d->d_lock);
225 spin_unlock(&d->d_lock);
228 spin_unlock(&inode->i_lock);
230 au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
231 d = d_find_alias(inode);
237 spin_lock(&d->d_lock);
239 if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
240 spin_unlock(&d->d_lock);
241 err = hn_gen_tree(d);
242 spin_lock(&d->d_lock);
244 spin_unlock(&d->d_lock);
253 static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
258 inode = dentry->d_inode;
260 /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
262 pr_warn("branch root dir was changed\n");
268 au_digen_dec(dentry);
272 au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
274 err = hn_gen_tree(dentry);
281 /* ---------------------------------------------------------------------- */
283 /* hnotify job flags */
284 #define AuHnJob_XINO0 1
285 #define AuHnJob_GEN (1 << 1)
286 #define AuHnJob_DIRENT (1 << 2)
287 #define AuHnJob_ISDIR (1 << 3)
288 #define AuHnJob_TRYXINO0 (1 << 4)
289 #define AuHnJob_MNTPNT (1 << 5)
290 #define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
291 #define au_fset_hnjob(flags, name) \
292 do { (flags) |= AuHnJob_##name; } while (0)
293 #define au_fclr_hnjob(flags, name) \
294 do { (flags) &= ~AuHnJob_##name; } while (0)
302 struct au_hnotify_args {
303 struct inode *h_dir, *dir, *h_child_inode;
305 unsigned int flags[AuHnLast];
306 unsigned int h_child_nlen;
312 struct inode *inode, *h_inode, *dir, *h_dir;
313 struct dentry *dentry;
318 static int hn_job(struct hn_job_args *a)
320 const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
323 if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
324 hn_xino(a->inode, a->h_inode); /* ignore this error */
326 if (au_ftest_hnjob(a->flags, TRYXINO0)
329 mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
330 if (!a->h_inode->i_nlink)
331 hn_xino(a->inode, a->h_inode); /* ignore this error */
332 mutex_unlock(&a->h_inode->i_mutex);
335 /* make the generation obsolete */
336 if (au_ftest_hnjob(a->flags, GEN)) {
339 err = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
341 if (err && a->dentry)
342 hn_gen_by_name(a->dentry, isdir);
343 /* ignore this error */
346 /* make dir entries obsolete */
347 if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
348 struct au_vdir *vdir;
350 vdir = au_ivdir(a->inode);
353 /* IMustLock(a->inode); */
354 /* a->inode->i_version++; */
357 /* can do nothing but warn */
358 if (au_ftest_hnjob(a->flags, MNTPNT)
360 && d_mountpoint(a->dentry))
361 pr_warn("mount-point %.*s is removed or renamed\n",
362 AuDLNPair(a->dentry));
367 /* ---------------------------------------------------------------------- */
369 static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
372 struct dentry *dentry, *d, *parent;
375 parent = d_find_alias(dir);
380 spin_lock(&parent->d_lock);
381 list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
382 /* AuDbg("%.*s\n", AuDLNPair(d)); */
383 spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
385 if (dname->len != nlen || memcmp(dname->name, name, nlen))
392 dentry = dget_dlock(d);
393 spin_unlock(&d->d_lock);
398 spin_unlock(&d->d_lock);
400 spin_unlock(&parent->d_lock);
404 di_write_lock_child(dentry);
409 static struct inode *lookup_wlock_by_ino(struct super_block *sb,
410 aufs_bindex_t bindex, ino_t h_ino)
417 err = au_xino_read(sb, bindex, h_ino, &ino);
419 inode = ilookup(sb, ino);
423 if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
424 pr_warn("wrong root branch\n");
430 ii_write_lock_child(inode);
436 static void au_hn_bh(void *_args)
438 struct au_hnotify_args *a = _args;
439 struct super_block *sb;
440 aufs_bindex_t bindex, bend, bfound;
441 unsigned char xino, try_iput;
445 struct hn_job_args args;
446 struct dentry *dentry;
447 struct au_sbinfo *sbinfo;
450 AuDebugOn(!a->h_dir);
453 AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
454 a->mask, a->dir->i_ino, a->h_dir->i_ino,
455 a->h_child_inode ? a->h_child_inode->i_ino : 0);
460 * do not lock a->dir->i_mutex here
461 * because of d_revalidate() may cause a deadlock.
467 si_write_lock(sb, AuLock_NOPLMW);
469 ii_read_lock_parent(a->dir);
471 bend = au_ibend(a->dir);
472 for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
473 if (au_h_iptr(a->dir, bindex) == a->h_dir) {
477 ii_read_unlock(a->dir);
478 if (unlikely(bfound < 0))
481 xino = !!au_opt_test(au_mntflags(sb), XINO);
483 if (a->h_child_inode)
484 h_ino = a->h_child_inode->i_ino;
487 && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
488 || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
489 dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
493 inode = dentry->d_inode;
494 if (xino && !inode && h_ino
495 && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
496 || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
497 || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
498 inode = lookup_wlock_by_ino(sb, bfound, h_ino);
502 args.flags = a->flags[AuHn_CHILD];
503 args.dentry = dentry;
505 args.h_inode = a->h_child_inode;
507 args.h_dir = a->h_dir;
508 args.h_name = a->h_child_name;
509 args.h_nlen = a->h_child_nlen;
513 di_write_unlock(dentry);
516 if (inode && try_iput) {
517 ii_write_unlock(inode);
521 ii_write_lock_parent(a->dir);
522 args.flags = a->flags[AuHn_PARENT];
525 args.h_inode = a->h_dir;
531 ii_write_unlock(a->dir);
534 iput(a->h_child_inode);
538 au_nwt_done(&sbinfo->si_nowait);
542 /* ---------------------------------------------------------------------- */
544 int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
545 struct qstr *h_child_qstr, struct inode *h_child_inode)
548 unsigned int flags[AuHnLast], f;
549 unsigned char isdir, isroot, wh;
551 struct au_hnotify_args *args;
552 char *p, *h_child_name;
555 AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
556 dir = igrab(hnotify->hn_aufs_inode);
560 isroot = (dir->i_ino == AUFS_ROOT_INO);
562 h_child_name = (void *)h_child_qstr->name;
563 len = h_child_qstr->len;
565 if (len > AUFS_WH_PFX_LEN
566 && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
567 h_child_name += AUFS_WH_PFX_LEN;
568 len -= AUFS_WH_PFX_LEN;
575 isdir = !!S_ISDIR(h_child_inode->i_mode);
576 flags[AuHn_PARENT] = AuHnJob_ISDIR;
577 flags[AuHn_CHILD] = 0;
579 flags[AuHn_CHILD] = AuHnJob_ISDIR;
580 au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
581 au_fset_hnjob(flags[AuHn_CHILD], GEN);
582 switch (mask & FS_EVENTS_POSS_ON_CHILD) {
585 au_fset_hnjob(flags[AuHn_CHILD], XINO0);
586 au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
589 AuDebugOn(!h_child_name || !h_child_inode);
594 * aufs never be able to get this child inode.
595 * revalidation should be in d_revalidate()
596 * by checking i_nlink, i_generation or d_unhashed().
598 AuDebugOn(!h_child_name);
599 au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
600 au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
608 h_child_inode = NULL;
611 /* iput() and kfree() will be called in au_hnotify() */
612 args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
613 if (unlikely(!args)) {
614 AuErr1("no memory\n");
618 args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
619 args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
622 args->h_dir = igrab(h_dir);
624 h_child_inode = igrab(h_child_inode); /* can be NULL */
625 args->h_child_inode = h_child_inode;
626 args->h_child_nlen = len;
630 memcpy(p, h_child_name, len);
637 err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
639 pr_err("wkq %d\n", err);
640 iput(args->h_child_inode);
650 /* ---------------------------------------------------------------------- */
652 int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
656 AuDebugOn(!(udba & AuOptMask_UDBA));
659 if (au_hnotify_op.reset_br)
660 err = au_hnotify_op.reset_br(udba, br, perm);
665 int au_hnotify_init_br(struct au_branch *br, int perm)
670 if (au_hnotify_op.init_br)
671 err = au_hnotify_op.init_br(br, perm);
676 void au_hnotify_fin_br(struct au_branch *br)
678 if (au_hnotify_op.fin_br)
679 au_hnotify_op.fin_br(br);
682 static void au_hn_destroy_cache(void)
684 kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
685 au_cachep[AuCache_HNOTIFY] = NULL;
688 int __init au_hnotify_init(void)
693 au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
694 if (au_cachep[AuCache_HNOTIFY]) {
696 if (au_hnotify_op.init)
697 err = au_hnotify_op.init();
699 au_hn_destroy_cache();
705 void au_hnotify_fin(void)
707 if (au_hnotify_op.fin)
709 /* cf. au_cache_fin() */
710 if (au_cachep[AuCache_HNOTIFY])
711 au_hn_destroy_cache();