svn commit: r190970 - in stable/7/sys: kern nfsclient sys
Alexander Kabaev
kan at FreeBSD.org
Sun Apr 12 10:43:42 PDT 2009
Author: kan
Date: Sun Apr 12 17:43:41 2009
New Revision: 190970
URL: http://svn.freebsd.org/changeset/base/190970
Log:
Reimplement r189287 for -stable:
Change vfs_busy to wait until an outcome of pending unmount
operation is known and to retry or fail accordingly to that
outcome. This fixes the problem with namespace traversing
programs failing with random ENOENT errors if someone just
happened to try to unmount that same filesystem at the same
time.
Prodded by: dhw, obrien
Approved by: re(kib)
Sponsored by: Juniper Networks, Inc.
Modified:
stable/7/sys/kern/vfs_mount.c
stable/7/sys/kern/vfs_subr.c
stable/7/sys/nfsclient/nfs_vfsops.c
stable/7/sys/sys/mount.h
Modified: stable/7/sys/kern/vfs_mount.c
==============================================================================
--- stable/7/sys/kern/vfs_mount.c Sun Apr 12 16:53:56 2009 (r190969)
+++ stable/7/sys/kern/vfs_mount.c Sun Apr 12 17:43:41 2009 (r190970)
@@ -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);
/*
Modified: stable/7/sys/kern/vfs_subr.c
==============================================================================
--- stable/7/sys/kern/vfs_subr.c Sun Apr 12 16:53:56 2009 (r190969)
+++ stable/7/sys/kern/vfs_subr.c Sun Apr 12 17:43:41 2009 (r190970)
@@ -337,8 +337,8 @@ vfs_busy(struct mount *mp, int flags, st
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, st
* 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);
Modified: stable/7/sys/nfsclient/nfs_vfsops.c
==============================================================================
--- stable/7/sys/nfsclient/nfs_vfsops.c Sun Apr 12 16:53:56 2009 (r190969)
+++ stable/7/sys/nfsclient/nfs_vfsops.c Sun Apr 12 17:43:41 2009 (r190970)
@@ -256,7 +256,7 @@ nfs_statfs(struct mount *mp, struct stat
#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);
Modified: stable/7/sys/sys/mount.h
==============================================================================
--- stable/7/sys/sys/mount.h Sun Apr 12 16:53:56 2009 (r190969)
+++ stable/7/sys/sys/mount.h Sun Apr 12 17:43:41 2009 (r190970)
@@ -319,6 +319,7 @@ void __mnt_vnode_markerfree(str
#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 */
More information about the svn-src-stable
mailing list