From owner-freebsd-current@FreeBSD.ORG Tue Jul 12 10:31:26 2011 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8448C1065679 for ; Tue, 12 Jul 2011 10:31:26 +0000 (UTC) (envelope-from okuno.kohji@jp.panasonic.com) Received: from smtp.mei.co.jp (smtp.mei.co.jp [133.183.100.20]) by mx1.freebsd.org (Postfix) with ESMTP id 136938FC16 for ; Tue, 12 Jul 2011 10:31:25 +0000 (UTC) Received: from mail-gw.jp.panasonic.com ([157.8.1.157]) by smtp.mei.co.jp (8.12.11.20060614/3.7W/kc-maile12) with ESMTP id p6CAATWl009467 for ; Tue, 12 Jul 2011 19:10:29 +0900 (JST) Received: from epochmail.jp.panasonic.com ([157.8.1.130]) by mail.jp.panasonic.com (8.11.6p2/3.7W/kc-maili17) with ESMTP id p6CAATf10855 for ; Tue, 12 Jul 2011 19:10:29 +0900 Received: by epochmail.jp.panasonic.com (8.12.11.20060308/3.7W/lomi12) id p6CAAT1G022397 for freebsd-current@freebsd.org; Tue, 12 Jul 2011 19:10:29 +0900 Received: from localhost by lomi12.jp.panasonic.com (8.12.11.20060308/3.7W) with ESMTP id p6CAATFk022370 for ; Tue, 12 Jul 2011 19:10:29 +0900 Date: Tue, 12 Jul 2011 19:10:28 +0900 (JST) Message-Id: <20110712.191028.650619413057975749.okuno.kohji@jp.panasonic.com> To: freebsd-current@freebsd.org From: Kohji Okuno Organization: Panasonic Corporation X-Mailer: Mew version 6.3 on Emacs 23.3 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Subject: Bug about devfs? X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jul 2011 10:31:26 -0000 Hello, I think that devfs has a problem. I encountered the problem that open("/dev/AAA") returned ENOENT. Of course, /dev/AAA exists. ENOENT was created by the point(***) in devfs_allocv(). I think that the race condition had occurred between process A and vnlru kernel thread. Please check the following. If vnlru set VI_DOOMED to vp->v_iflag but vnlru didn't still execute VOP_RECLAIM(), process A cat get valid vp from de->de_vnode. But, vget() will return ENOENT, because vp->v_iflag has VI_DOOMED. When I set the break point to (***), I checked that de->de_vnode and vp->v_data were NULL. process A: vnlru: devfs_allocv() { vgonel(vp) { ... ... vp->v_iflag |= VI_DOOMED; mtx_lock(&devfs_de_interlock); ... vp = de->de_vnode; if (vp != NULL) { VI_UNLOCK(vp); _____________/ ... VI_LOCK(vp); ____________/ if (VOP_RECLAIM(vp, td)) mtx_unlock(&devfs_de_interlock); ... ... \ devfs_reclaim(ap) { error = vget(vp,...); \ ... \______ mtx_lock(&devfs_de_interlock); if (devfs_allocv_drop_refs(...)) { de = vp->v_data; ... if (de != NULL) { } de->de_vnode = NULL; else if (error) { vp->v_data = NULL; ... } rturn (error); (***) mtx_unlock(&devfs_de_interlock); } ... } I think that devfs_allocv() should be fixed as below. How do you think? devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp) { int error; struct vnode *vp; struct cdev *dev; struct devfs_mount *dmp; dmp = VFSTODEVFS(mp); +#if 1 + retry: +#endif if (de->de_flags & DE_DOOMED) { ... mtx_lock(&devfs_de_interlock); vp = de->de_vnode; if (vp != NULL) { VI_LOCK(vp); mtx_unlock(&devfs_de_interlock); sx_xunlock(&dmp->dm_lock); error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread); sx_xlock(&dmp->dm_lock); if (devfs_allocv_drop_refs(0, dmp, de)) { if (error == 0) vput(vp); return (ENOENT); } else if (error) { +#if 1 + if (error == ENOENT) + goto retry; +#endif sx_xunlock(&dmp->dm_lock); return (error); } Thanks, Kohji Okuno.