summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_mount.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2012-09-09 19:17:15 +0000
committerkib <kib@FreeBSD.org>2012-09-09 19:17:15 +0000
commit5a86a6849adc026d814651fd6afc864b2377b9c8 (patch)
tree23fb14fcdb2f9274e6cc5294ce7f1bf0634f2755 /sys/kern/vfs_mount.c
parent01b848f0eebd0e92a90c06e0708aa3d48942ed79 (diff)
downloadFreeBSD-src-5a86a6849adc026d814651fd6afc864b2377b9c8.zip
FreeBSD-src-5a86a6849adc026d814651fd6afc864b2377b9c8.tar.gz
Add a facility for vgone() to inform the set of subscribed mounts
about vnode reclamation. Typical use is for the bypass mounts like nullfs to get a notification about lower vnode going away. Now, vgone() calls new VFS op vfs_reclaim_lowervp() with an argument lowervp which is reclaimed. It is possible to register several reclamation event listeners, to correctly handle the case of several nullfs mounts over the same directory. For the filesystem not having nullfs mounts over it, the overhead added is a single mount interlock lock/unlock in the vnode reclamation path. In collaboration with: pho MFC after: 3 weeks
Diffstat (limited to 'sys/kern/vfs_mount.c')
-rw-r--r--sys/kern/vfs_mount.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index e9d3abe..f397842 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -481,6 +481,7 @@ vfs_mount_alloc(struct vnode *vp, struct vfsconf *vfsp, const char *fspath,
mac_mount_create(cred, mp);
#endif
arc4rand(&mp->mnt_hashseed, sizeof mp->mnt_hashseed, 0);
+ TAILQ_INIT(&mp->mnt_uppers);
return (mp);
}
@@ -514,6 +515,7 @@ vfs_mount_destroy(struct mount *mp)
vprint("", vp);
panic("unmount: dangling vnode");
}
+ KASSERT(TAILQ_EMPTY(&mp->mnt_uppers), ("mnt_uppers"));
if (mp->mnt_nvnodelistsize != 0)
panic("vfs_mount_destroy: nonzero nvnodelistsize");
if (mp->mnt_activevnodelistsize != 0)
@@ -1275,7 +1277,8 @@ dounmount(mp, flags, td)
}
MNT_ILOCK(mp);
- if (mp->mnt_kern_flag & MNTK_UNMOUNT) {
+ if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 ||
+ !TAILQ_EMPTY(&mp->mnt_uppers)) {
MNT_IUNLOCK(mp);
if (coveredvp)
VOP_UNLOCK(coveredvp, 0);
OpenPOWER on IntegriCloud