diff options
author | kib <kib@FreeBSD.org> | 2012-09-09 19:17:15 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2012-09-09 19:17:15 +0000 |
commit | 5a86a6849adc026d814651fd6afc864b2377b9c8 (patch) | |
tree | 23fb14fcdb2f9274e6cc5294ce7f1bf0634f2755 /sys/kern/vfs_mount.c | |
parent | 01b848f0eebd0e92a90c06e0708aa3d48942ed79 (diff) | |
download | FreeBSD-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.c | 5 |
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); |