]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - fs/aufs/hnotify.c
2 * Copyright (C) 2005-2017 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, see <http://www.gnu.org/licenses/>.
19 * abstraction to notify the direct changes on lower directories
24 int au_hn_alloc(struct au_hinode
*hinode
, struct inode
*inode
)
27 struct au_hnotify
*hn
;
30 hn
= au_cache_alloc_hnotify();
32 hn
->hn_aufs_inode
= inode
;
33 hinode
->hi_notify
= hn
;
34 err
= au_hnotify_op
.alloc(hinode
);
37 hinode
->hi_notify
= NULL
;
38 au_cache_free_hnotify(hn
);
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.
54 void au_hn_free(struct au_hinode
*hinode
)
56 struct au_hnotify
*hn
;
58 hn
= hinode
->hi_notify
;
60 hinode
->hi_notify
= NULL
;
61 if (au_hnotify_op
.free(hinode
, hn
))
62 au_cache_free_hnotify(hn
);
66 /* ---------------------------------------------------------------------- */
68 void au_hn_ctl(struct au_hinode
*hinode
, int do_set
)
70 if (hinode
->hi_notify
)
71 au_hnotify_op
.ctl(hinode
, do_set
);
74 void au_hn_reset(struct inode
*inode
, unsigned int flags
)
76 aufs_bindex_t bindex
, bbot
;
78 struct dentry
*iwhdentry
;
80 bbot
= au_ibbot(inode
);
81 for (bindex
= au_ibtop(inode
); bindex
<= bbot
; bindex
++) {
82 hi
= au_h_iptr(inode
, bindex
);
86 /* inode_lock_nested(hi, AuLsc_I_CHILD); */
87 iwhdentry
= au_hi_wh(inode
, bindex
);
91 au_set_h_iptr(inode
, bindex
, NULL
, 0);
92 au_set_h_iptr(inode
, bindex
, au_igrab(hi
),
96 /* inode_unlock(hi); */
100 /* ---------------------------------------------------------------------- */
102 static int hn_xino(struct inode
*inode
, struct inode
*h_inode
)
105 aufs_bindex_t bindex
, bbot
, bfound
, btop
;
109 if (unlikely(inode
->i_ino
== AUFS_ROOT_INO
)) {
110 pr_warn("branch root dir was changed\n");
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 */
123 for (bindex
= btop
; bindex
<= bbot
; bindex
++)
124 if (au_h_iptr(inode
, bindex
) == h_inode
) {
131 for (bindex
= btop
; bindex
<= bbot
; bindex
++) {
132 h_i
= au_h_iptr(inode
, bindex
);
136 err
= au_xino_write(inode
->i_sb
, bindex
, h_i
->i_ino
, /*ino*/0);
137 /* ignore this error */
141 /* children inode number will be broken */
148 static int hn_gen_tree(struct dentry
*dentry
)
150 int err
, i
, j
, ndentry
;
151 struct au_dcsub_pages dpages
;
152 struct au_dpage
*dpage
;
153 struct dentry
**dentries
;
155 err
= au_dpages_init(&dpages
, GFP_NOFS
);
158 err
= au_dcsub_pages(&dpages
, dentry
, NULL
, NULL
);
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
++) {
174 if (d_really_is_positive(d
))
175 /* todo: reset children xino?
176 cached children only? */
177 au_iigen_dec(d_inode(d
));
182 au_dpages_free(&dpages
);
185 /* discard children */
186 dentry_unhash(dentry
);
194 * return 0 if processed.
196 static int hn_gen_by_inode(char *name
, unsigned int nlen
, struct inode
*inode
,
197 const unsigned int isdir
)
204 if (unlikely(inode
->i_ino
== AUFS_ROOT_INO
)) {
205 pr_warn("branch root dir was changed\n");
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
);
217 if (dname
->len
!= nlen
218 && memcmp(dname
->name
, name
, nlen
)) {
219 spin_unlock(&d
->d_lock
);
224 spin_unlock(&d
->d_lock
);
227 spin_unlock(&inode
->i_lock
);
229 au_fset_si(au_sbi(inode
->i_sb
), FAILED_REFRESH_DIR
);
230 d
= d_find_any_alias(inode
);
236 spin_lock(&d
->d_lock
);
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
);
243 spin_unlock(&d
->d_lock
);
252 static int hn_gen_by_name(struct dentry
*dentry
, const unsigned int isdir
)
256 if (IS_ROOT(dentry
)) {
257 pr_warn("branch root dir was changed\n");
263 au_digen_dec(dentry
);
264 if (d_really_is_positive(dentry
))
265 au_iigen_dec(d_inode(dentry
));
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
);
276 /* ---------------------------------------------------------------------- */
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)
297 struct au_hnotify_args
{
298 struct inode
*h_dir
, *dir
, *h_child_inode
;
300 unsigned int flags
[AuHnLast
];
301 unsigned int h_child_nlen
;
307 struct inode
*inode
, *h_inode
, *dir
, *h_dir
;
308 struct dentry
*dentry
;
313 static int hn_job(struct hn_job_args
*a
)
315 const unsigned int isdir
= au_ftest_hnjob(a
->flags
, ISDIR
);
319 if (au_ftest_hnjob(a
->flags
, XINO0
) && a
->inode
)
320 hn_xino(a
->inode
, a
->h_inode
); /* ignore this error */
322 if (au_ftest_hnjob(a
->flags
, TRYXINO0
)
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
);
332 /* make the generation obsolete */
333 if (au_ftest_hnjob(a
->flags
, GEN
)) {
336 e
= hn_gen_by_inode(a
->h_name
, a
->h_nlen
, a
->inode
,
339 hn_gen_by_name(a
->dentry
, isdir
);
340 /* ignore this error */
343 /* make dir entries obsolete */
344 if (au_ftest_hnjob(a
->flags
, DIRENT
) && a
->inode
) {
345 struct au_vdir
*vdir
;
347 vdir
= au_ivdir(a
->inode
);
350 /* IMustLock(a->inode); */
351 /* a->inode->i_version++; */
354 /* can do nothing but warn */
355 if (au_ftest_hnjob(a
->flags
, MNTPNT
)
357 && d_mountpoint(a
->dentry
))
358 pr_warn("mount-point %pd is removed or renamed\n", a
->dentry
);
363 /* ---------------------------------------------------------------------- */
365 static struct dentry
*lookup_wlock_by_name(char *name
, unsigned int nlen
,
368 struct dentry
*dentry
, *d
, *parent
;
371 parent
= d_find_any_alias(dir
);
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
);
381 if (dname
->len
!= nlen
|| memcmp(dname
->name
, name
, nlen
))
387 if (au_dcount(d
) > 0) {
388 dentry
= dget_dlock(d
);
389 spin_unlock(&d
->d_lock
);
394 spin_unlock(&d
->d_lock
);
396 spin_unlock(&parent
->d_lock
);
400 di_write_lock_child(dentry
);
405 static struct inode
*lookup_wlock_by_ino(struct super_block
*sb
,
406 aufs_bindex_t bindex
, ino_t h_ino
)
413 err
= au_xino_read(sb
, bindex
, h_ino
, &ino
);
415 inode
= ilookup(sb
, ino
);
419 if (unlikely(inode
->i_ino
== AUFS_ROOT_INO
)) {
420 pr_warn("wrong root branch\n");
426 ii_write_lock_child(inode
);
432 static void au_hn_bh(void *_args
)
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
;
441 struct hn_job_args args
;
442 struct dentry
*dentry
;
443 struct au_sbinfo
*sbinfo
;
446 AuDebugOn(!a
->h_dir
);
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);
456 * do not lock a->dir->i_mutex here
457 * because of d_revalidate() may cause a deadlock.
463 si_write_lock(sb
, AuLock_NOPLMW
);
465 ii_read_lock_parent(a
->dir
);
467 bbot
= au_ibbot(a
->dir
);
468 for (bindex
= au_ibtop(a
->dir
); bindex
<= bbot
; bindex
++)
469 if (au_h_iptr(a
->dir
, bindex
) == a
->h_dir
) {
473 ii_read_unlock(a
->dir
);
474 if (unlikely(bfound
< 0))
477 xino
= !!au_opt_test(au_mntflags(sb
), XINO
);
479 if (a
->h_child_inode
)
480 h_ino
= a
->h_child_inode
->i_ino
;
483 && (au_ftest_hnjob(a
->flags
[AuHn_CHILD
], GEN
)
484 || au_ftest_hnjob(a
->flags
[AuHn_CHILD
], MNTPNT
)))
485 dentry
= lookup_wlock_by_name(a
->h_child_name
, a
->h_child_nlen
,
488 if (dentry
&& d_really_is_positive(dentry
))
489 inode
= d_inode(dentry
);
490 if (xino
&& !inode
&& h_ino
491 && (au_ftest_hnjob(a
->flags
[AuHn_CHILD
], XINO0
)
492 || au_ftest_hnjob(a
->flags
[AuHn_CHILD
], TRYXINO0
)
493 || au_ftest_hnjob(a
->flags
[AuHn_CHILD
], GEN
))) {
494 inode
= lookup_wlock_by_ino(sb
, bfound
, h_ino
);
498 args
.flags
= a
->flags
[AuHn_CHILD
];
499 args
.dentry
= dentry
;
501 args
.h_inode
= a
->h_child_inode
;
503 args
.h_dir
= a
->h_dir
;
504 args
.h_name
= a
->h_child_name
;
505 args
.h_nlen
= a
->h_child_nlen
;
509 di_write_unlock(dentry
);
512 if (inode
&& try_iput
) {
513 ii_write_unlock(inode
);
517 ii_write_lock_parent(a
->dir
);
518 args
.flags
= a
->flags
[AuHn_PARENT
];
521 args
.h_inode
= a
->h_dir
;
527 ii_write_unlock(a
->dir
);
530 iput(a
->h_child_inode
);
534 au_nwt_done(&sbinfo
->si_nowait
);
538 /* ---------------------------------------------------------------------- */
540 int au_hnotify(struct inode
*h_dir
, struct au_hnotify
*hnotify
, u32 mask
,
541 struct qstr
*h_child_qstr
, struct inode
*h_child_inode
)
544 unsigned int flags
[AuHnLast
], f
;
545 unsigned char isdir
, isroot
, wh
;
547 struct au_hnotify_args
*args
;
548 char *p
, *h_child_name
;
551 AuDebugOn(!hnotify
|| !hnotify
->hn_aufs_inode
);
552 dir
= igrab(hnotify
->hn_aufs_inode
);
556 isroot
= (dir
->i_ino
== AUFS_ROOT_INO
);
558 h_child_name
= (void *)h_child_qstr
->name
;
559 len
= h_child_qstr
->len
;
561 if (len
> AUFS_WH_PFX_LEN
562 && !memcmp(h_child_name
, AUFS_WH_PFX
, AUFS_WH_PFX_LEN
)) {
563 h_child_name
+= AUFS_WH_PFX_LEN
;
564 len
-= AUFS_WH_PFX_LEN
;
571 isdir
= !!S_ISDIR(h_child_inode
->i_mode
);
572 flags
[AuHn_PARENT
] = AuHnJob_ISDIR
;
573 flags
[AuHn_CHILD
] = 0;
575 flags
[AuHn_CHILD
] = AuHnJob_ISDIR
;
576 au_fset_hnjob(flags
[AuHn_PARENT
], DIRENT
);
577 au_fset_hnjob(flags
[AuHn_CHILD
], GEN
);
578 switch (mask
& FS_EVENTS_POSS_ON_CHILD
) {
581 au_fset_hnjob(flags
[AuHn_CHILD
], XINO0
);
582 au_fset_hnjob(flags
[AuHn_CHILD
], MNTPNT
);
585 AuDebugOn(!h_child_name
);
590 * aufs never be able to get this child inode.
591 * revalidation should be in d_revalidate()
592 * by checking i_nlink, i_generation or d_unhashed().
594 AuDebugOn(!h_child_name
);
595 au_fset_hnjob(flags
[AuHn_CHILD
], TRYXINO0
);
596 au_fset_hnjob(flags
[AuHn_CHILD
], MNTPNT
);
604 h_child_inode
= NULL
;
607 /* iput() and kfree() will be called in au_hnotify() */
608 args
= kmalloc(sizeof(*args
) + len
+ 1, GFP_NOFS
);
609 if (unlikely(!args
)) {
610 AuErr1("no memory\n");
614 args
->flags
[AuHn_PARENT
] = flags
[AuHn_PARENT
];
615 args
->flags
[AuHn_CHILD
] = flags
[AuHn_CHILD
];
618 args
->h_dir
= igrab(h_dir
);
620 h_child_inode
= igrab(h_child_inode
); /* can be NULL */
621 args
->h_child_inode
= h_child_inode
;
622 args
->h_child_nlen
= len
;
626 memcpy(p
, h_child_name
, len
);
630 /* NFS fires the event for silly-renamed one from kworker */
633 || (au_test_nfs(h_dir
->i_sb
) && (mask
& FS_DELETE
)))
635 err
= au_wkq_nowait(au_hn_bh
, args
, dir
->i_sb
, f
);
637 pr_err("wkq %d\n", err
);
638 iput(args
->h_child_inode
);
648 /* ---------------------------------------------------------------------- */
650 int au_hnotify_reset_br(unsigned int udba
, struct au_branch
*br
, int perm
)
654 AuDebugOn(!(udba
& AuOptMask_UDBA
));
657 if (au_hnotify_op
.reset_br
)
658 err
= au_hnotify_op
.reset_br(udba
, br
, perm
);
663 int au_hnotify_init_br(struct au_branch
*br
, int perm
)
668 if (au_hnotify_op
.init_br
)
669 err
= au_hnotify_op
.init_br(br
, perm
);
674 void au_hnotify_fin_br(struct au_branch
*br
)
676 if (au_hnotify_op
.fin_br
)
677 au_hnotify_op
.fin_br(br
);
680 static void au_hn_destroy_cache(void)
682 kmem_cache_destroy(au_cache
[AuCache_HNOTIFY
]);
683 au_cache
[AuCache_HNOTIFY
] = NULL
;
686 int __init
au_hnotify_init(void)
691 au_cache
[AuCache_HNOTIFY
] = AuCache(au_hnotify
);
692 if (au_cache
[AuCache_HNOTIFY
]) {
694 if (au_hnotify_op
.init
)
695 err
= au_hnotify_op
.init();
697 au_hn_destroy_cache();
703 void au_hnotify_fin(void)
705 if (au_hnotify_op
.fin
)
708 /* cf. au_cache_fin() */
709 if (au_cache
[AuCache_HNOTIFY
])
710 au_hn_destroy_cache();