From owner-svn-src-stable@FreeBSD.ORG Wed Aug 3 14:29:20 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A06FE106564A; Wed, 3 Aug 2011 14:29:20 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 764788FC12; Wed, 3 Aug 2011 14:29:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p73ETKHH017233; Wed, 3 Aug 2011 14:29:20 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p73ETK2X017231; Wed, 3 Aug 2011 14:29:20 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201108031429.p73ETK2X017231@svn.freebsd.org> From: Konstantin Belousov Date: Wed, 3 Aug 2011 14:29:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r224635 - stable/8/sys/fs/devfs X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Aug 2011 14:29:20 -0000 Author: kib Date: Wed Aug 3 14:29:20 2011 New Revision: 224635 URL: http://svn.freebsd.org/changeset/base/224635 Log: MFC r223988: While fixing the looping of a thread while devfs vnode is reclaimed, r179247 introduced a possibility of devfs_allocv() returning spurious ENOENT. If the vnode is selected by vnlru daemon for reclamation, then devfs_allocv() can get ENOENT from vget() due to devfs_close() dropping vnode lock around the call to cdevsw d_close method. Use LK_RETRY in the vget() call, and do some part of the devfs_reclaim() work in devfs_allocv(), clearing vp->v_data and de->de_vnode. Retry the allocation of the vnode, now with de->de_vnode == NULL. The check vp->v_data == NULL at the start of devfs_close() cannot be affected by the change, since vnode lock must be held while VI_DOOMED is set, and only dropped after the check. Modified: stable/8/sys/fs/devfs/devfs_vnops.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/fs/devfs/devfs_vnops.c ============================================================================== --- stable/8/sys/fs/devfs/devfs_vnops.c Wed Aug 3 13:39:11 2011 (r224634) +++ stable/8/sys/fs/devfs/devfs_vnops.c Wed Aug 3 14:29:20 2011 (r224635) @@ -346,6 +346,7 @@ devfs_allocv(struct devfs_dirent *de, st sx_xunlock(&dmp->dm_lock); return (ENOENT); } +loop: DEVFS_DE_HOLD(de); DEVFS_DMP_HOLD(dmp); mtx_lock(&devfs_de_interlock); @@ -354,16 +355,21 @@ devfs_allocv(struct devfs_dirent *de, st VI_LOCK(vp); mtx_unlock(&devfs_de_interlock); sx_xunlock(&dmp->dm_lock); - error = vget(vp, lockmode | LK_INTERLOCK, curthread); + vget(vp, lockmode | LK_INTERLOCK | LK_RETRY, curthread); sx_xlock(&dmp->dm_lock); if (devfs_allocv_drop_refs(0, dmp, de)) { - if (error == 0) - vput(vp); + vput(vp); return (ENOENT); } - else if (error) { - sx_xunlock(&dmp->dm_lock); - return (error); + else if ((vp->v_iflag & VI_DOOMED) != 0) { + mtx_lock(&devfs_de_interlock); + if (de->de_vnode == vp) { + de->de_vnode = NULL; + vp->v_data = NULL; + } + mtx_unlock(&devfs_de_interlock); + vput(vp); + goto loop; } sx_xunlock(&dmp->dm_lock); *vpp = vp;