svn commit: r190970 - in stable/7/sys: kern nfsclient sys

Alexander Kabaev kan at FreeBSD.org
Sun Apr 12 17:43:42 UTC 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-all mailing list