From owner-svn-src-head@FreeBSD.ORG Mon Mar 2 20:51:39 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9792C106566C; Mon, 2 Mar 2009 20:51:39 +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 6BF688FC1C; Mon, 2 Mar 2009 20:51:39 +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 n22KpdGB085951; Mon, 2 Mar 2009 20:51:39 GMT (envelope-from kan@svn.freebsd.org) Received: (from kan@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n22KpdfS085950; Mon, 2 Mar 2009 20:51:39 GMT (envelope-from kan@svn.freebsd.org) Message-Id: <200903022051.n22KpdfS085950@svn.freebsd.org> From: Alexander Kabaev Date: Mon, 2 Mar 2009 20:51:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r189287 - head/sys/kern X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Mar 2009 20:51:40 -0000 Author: kan Date: Mon Mar 2 20:51:39 2009 New Revision: 189287 URL: http://svn.freebsd.org/changeset/base/189287 Log: 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. Reported by: dhw Reviewed by: kib, attilio Sponsored by: Juniper Networks, Inc. Modified: head/sys/kern/vfs_subr.c Modified: head/sys/kern/vfs_subr.c ============================================================================== --- head/sys/kern/vfs_subr.c Mon Mar 2 19:42:01 2009 (r189286) +++ head/sys/kern/vfs_subr.c Mon Mar 2 20:51:39 2009 (r189287) @@ -345,7 +345,19 @@ vfs_busy(struct mount *mp, int flags) MNT_ILOCK(mp); MNT_REF(mp); - if (mp->mnt_kern_flag & MNTK_UNMOUNT) { + /* + * If mount point is currenly being unmounted, sleep until the + * mount point fate is decided. If thread doing the unmounting fails, + * it will clear MNTK_UNMOUNT flag before waking us up, indicating + * that this mount point has survived the unmount attempt and vfs_busy + * should retry. Otherwise the unmounter thread will set MNTK_REFEXPIRE + * flag in addition to MNTK_UNMOUNT, indicating that mount point is + * about to be really destroyed. vfs_busy needs to release its + * reference on the mount point in this case and return with ENOENT, + * telling the caller that mount mount it tried to busy is no longer + * valid. + */ + while (mp->mnt_kern_flag & MNTK_UNMOUNT) { if (flags & MBF_NOWAIT || mp->mnt_kern_flag & MNTK_REFEXPIRE) { MNT_REL(mp); MNT_IUNLOCK(mp); @@ -357,12 +369,8 @@ vfs_busy(struct mount *mp, int flags) mtx_unlock(&mountlist_mtx); mp->mnt_kern_flag |= MNTK_MWAIT; msleep(mp, MNT_MTX(mp), PVFS, "vfs_busy", 0); - MNT_REL(mp); - MNT_IUNLOCK(mp); if (flags & MBF_MNTLSTLOCK) mtx_lock(&mountlist_mtx); - CTR1(KTR_VFS, "%s: failed busying after sleep", __func__); - return (ENOENT); } if (flags & MBF_MNTLSTLOCK) mtx_unlock(&mountlist_mtx);