summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kabaev <kan@FreeBSD.org>2009-04-12 17:43:41 +0000
committerAlexander Kabaev <kan@FreeBSD.org>2009-04-12 17:43:41 +0000
commit66fc931eec84a2fa5a9068e9d8771a0fe42eb0ad (patch)
tree50bff3e39ed92fc6f160dc8ff7b009a0e029fd05
parenta0b7611fb83c6a67e4e957cf933c8a2917480c33 (diff)
Notes
-rw-r--r--sys/kern/vfs_mount.c5
-rw-r--r--sys/kern/vfs_subr.c7
-rw-r--r--sys/nfsclient/nfs_vfsops.c2
-rw-r--r--sys/sys/mount.h1
4 files changed, 9 insertions, 6 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 1020cca94555..dd9b5fe2c830 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -508,6 +508,11 @@ vfs_mount_destroy(struct mount *mp)
int i;
MNT_ILOCK(mp);
+ mp->mnt_kern_flag |= MNTK_REFEXPIRE;
+ if (mp->mnt_kern_flag & MNTK_MWAIT) {
+ mp->mnt_kern_flag &= ~MNTK_MWAIT;
+ wakeup(mp);
+ }
for (i = 0; mp->mnt_ref && i < 3; i++)
msleep(mp, MNT_MTX(mp), PVFS, "mntref", hz);
/*
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 03aa0c744da9..483f0e9c0e5b 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -337,8 +337,8 @@ vfs_busy(struct mount *mp, int flags, struct mtx *interlkp,
MNT_ILOCK(mp);
MNT_REF(mp);
- if (mp->mnt_kern_flag & MNTK_UNMOUNT) {
- if (flags & LK_NOWAIT) {
+ while (mp->mnt_kern_flag & MNTK_UNMOUNT) {
+ if (flags & LK_NOWAIT || mp->mnt_kern_flag & MNTK_REFEXPIRE) {
MNT_REL(mp);
MNT_IUNLOCK(mp);
return (ENOENT);
@@ -353,11 +353,8 @@ vfs_busy(struct mount *mp, int flags, struct mtx *interlkp,
* exclusive lock at the end of dounmount.
*/
msleep(mp, MNT_MTX(mp), PVFS, "vfs_busy", 0);
- MNT_REL(mp);
- MNT_IUNLOCK(mp);
if (interlkp)
mtx_lock(interlkp);
- return (ENOENT);
}
if (interlkp)
mtx_unlock(interlkp);
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index 864d53e8b60c..a963083fd4ab 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -256,7 +256,7 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
#ifndef nolint
sfp = NULL;
#endif
- error = vfs_busy(mp, LK_NOWAIT, NULL, td);
+ error = vfs_busy(mp, 0, NULL, td);
if (error)
return (error);
error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 9216a2382913..f2655f116c9e 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -319,6 +319,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
#define MNTK_ASYNC 0x00000002 /* filtered async flag */
#define MNTK_SOFTDEP 0x00000004 /* async disabled by softdep */
#define MNTK_NOINSMNTQ 0x00000008 /* insmntque is not allowed */
+#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 */