summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/vfs_mount.c45
-rw-r--r--sys/kern/vfs_subr.c2
-rw-r--r--sys/sys/mount.h1
3 files changed, 16 insertions, 32 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 12368c9..2b870f0 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -507,29 +507,20 @@ vfs_mount_destroy(struct mount *mp)
{
MNT_ILOCK(mp);
+ mp->mnt_kern_flag |= MNTK_REFEXPIRE;
+ if (mp->mnt_kern_flag & MNTK_MWAIT) {
+ mp->mnt_kern_flag &= ~MNTK_MWAIT;
+ wakeup(mp);
+ }
while (mp->mnt_ref)
msleep(mp, MNT_MTX(mp), PVFS, "mntref", 0);
- if (mp->mnt_writeopcount > 0) {
- printf("Waiting for mount point write ops\n");
- while (mp->mnt_writeopcount > 0) {
- mp->mnt_kern_flag |= MNTK_SUSPEND;
- msleep(&mp->mnt_writeopcount,
- MNT_MTX(mp),
- PZERO, "mntdestroy2", 0);
- }
- printf("mount point write ops completed\n");
- }
- if (mp->mnt_secondary_writes > 0) {
- printf("Waiting for mount point secondary write ops\n");
- while (mp->mnt_secondary_writes > 0) {
- mp->mnt_kern_flag |= MNTK_SUSPEND;
- msleep(&mp->mnt_secondary_writes,
- MNT_MTX(mp),
- PZERO, "mntdestroy3", 0);
- }
- printf("mount point secondary write ops completed\n");
- }
- MNT_IUNLOCK(mp);
+ KASSERT(mp->mnt_ref == 0,
+ ("%s: invalid refcount in the drain path @ %s:%d", __func__,
+ __FILE__, __LINE__));
+ if (mp->mnt_writeopcount != 0)
+ panic("vfs_mount_destroy: nonzero writeopcount");
+ if (mp->mnt_secondary_writes != 0)
+ panic("vfs_mount_destroy: nonzero secondary_writes");
mp->mnt_vfc->vfc_refcount--;
if (!TAILQ_EMPTY(&mp->mnt_nvnodelist)) {
struct vnode *vp;
@@ -538,18 +529,10 @@ vfs_mount_destroy(struct mount *mp)
vprint("", vp);
panic("unmount: dangling vnode");
}
- MNT_ILOCK(mp);
- if (mp->mnt_kern_flag & MNTK_MWAIT)
- wakeup(mp);
- if (mp->mnt_writeopcount != 0)
- panic("vfs_mount_destroy: nonzero writeopcount");
- if (mp->mnt_secondary_writes != 0)
- panic("vfs_mount_destroy: nonzero secondary_writes");
if (mp->mnt_nvnodelistsize != 0)
panic("vfs_mount_destroy: nonzero nvnodelistsize");
- mp->mnt_writeopcount = -1000;
- mp->mnt_nvnodelistsize = -1000;
- mp->mnt_secondary_writes = -1000;
+ if (mp->mnt_lockref != 0)
+ panic("vfs_mount_destroy: nonzero lock refcount");
MNT_IUNLOCK(mp);
#ifdef MAC
mac_mount_destroy(mp);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 16373b1..eb02693 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -345,7 +345,7 @@ vfs_busy(struct mount *mp, int flags)
MNT_ILOCK(mp);
MNT_REF(mp);
if (mp->mnt_kern_flag & MNTK_UNMOUNT) {
- if (flags & MBF_NOWAIT) {
+ if (flags & MBF_NOWAIT || mp->mnt_kern_flag & MNTK_REFEXPIRE) {
MNT_REL(mp);
MNT_IUNLOCK(mp);
return (ENOENT);
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 51cff5d..60086c6 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -316,6 +316,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
#define MNTK_SOFTDEP 0x00000004 /* async disabled by softdep */
#define MNTK_NOINSMNTQ 0x00000008 /* insmntque is not allowed */
#define MNTK_DRAINING 0x00000010 /* lock draining is happening */
+#define MNTK_REFEXPIRE 0x00000020 /* refcount expiring is happening */
#define MNTK_UNMOUNT 0x01000000 /* unmount in progress */
#define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */
#define MNTK_SUSPEND 0x08000000 /* request write suspension */
OpenPOWER on IntegriCloud