[PATCH] count ghost references to vfsmounts

make propagate_mount_busy() exclude references from the vfsmounts
that had been isolated by umount_tree() and are just waiting for
release_mounts() to dispose of their ->mnt_parent/->mnt_mountpoint.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 7c4b93d8 1a390689

+6 -2
+4 -1
fs/namespace.c
··· 548 548 m = mnt->mnt_parent; 549 549 mnt->mnt_mountpoint = mnt->mnt_root; 550 550 mnt->mnt_parent = mnt; 551 + m->mnt_ghosts--; 551 552 spin_unlock(&vfsmount_lock); 552 553 dput(dentry); 553 554 mntput(m); ··· 573 572 __touch_mnt_namespace(p->mnt_ns); 574 573 p->mnt_ns = NULL; 575 574 list_del_init(&p->mnt_child); 576 - if (p->mnt_parent != p) 575 + if (p->mnt_parent != p) { 576 + p->mnt_parent->mnt_ghosts++; 577 577 p->mnt_mountpoint->d_mounted--; 578 + } 578 579 change_mnt_propagation(p, MS_PRIVATE); 579 580 } 580 581 }
+1 -1
fs/pnode.c
··· 225 225 */ 226 226 static inline int do_refcount_check(struct vfsmount *mnt, int count) 227 227 { 228 - int mycount = atomic_read(&mnt->mnt_count); 228 + int mycount = atomic_read(&mnt->mnt_count) - mnt->mnt_ghosts; 229 229 return (mycount > count); 230 230 } 231 231
+1
include/linux/mount.h
··· 61 61 atomic_t mnt_count; 62 62 int mnt_expiry_mark; /* true if marked for expiry */ 63 63 int mnt_pinned; 64 + int mnt_ghosts; 64 65 }; 65 66 66 67 static inline struct vfsmount *mntget(struct vfsmount *mnt)