From owner-svn-src-all@FreeBSD.ORG Sun Apr 12 17:43:41 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 96FB6106564A; Sun, 12 Apr 2009 17:43:41 +0000 (UTC) (envelope-from kan@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 846F88FC0C; Sun, 12 Apr 2009 17:43:41 +0000 (UTC) (envelope-from kan@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n3CHhfqZ032783; Sun, 12 Apr 2009 17:43:41 GMT (envelope-from kan@svn.freebsd.org) Received: (from kan@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n3CHhfUV032779; Sun, 12 Apr 2009 17:43:41 GMT (envelope-from kan@svn.freebsd.org) Message-Id: <200904121743.n3CHhfUV032779@svn.freebsd.org> From: Alexander Kabaev Date: Sun, 12 Apr 2009 17:43:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r190970 - in stable/7/sys: kern nfsclient sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Apr 2009 17:43:42 -0000 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 */