From owner-svn-src-head@FreeBSD.ORG Mon Dec 29 12:12:23 2008 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 A9D2B1065672; Mon, 29 Dec 2008 12:12:23 +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 902C78FC1C; Mon, 29 Dec 2008 12:12:23 +0000 (UTC) (envelope-from kib@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 mBTCCNuD056861; Mon, 29 Dec 2008 12:12:23 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mBTCCN0I056860; Mon, 29 Dec 2008 12:12:23 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <200812291212.mBTCCN0I056860@svn.freebsd.org> From: Konstantin Belousov Date: Mon, 29 Dec 2008 12:12:23 +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: r186561 - head/sys/fs/pseudofs 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, 29 Dec 2008 12:12:23 -0000 Author: kib Date: Mon Dec 29 12:12:23 2008 New Revision: 186561 URL: http://svn.freebsd.org/changeset/base/186561 Log: Drop the pseudofs vnode lock around call to pfs_read handler. The handler may need to lock arbitrary vnodes, causing either lock order reversal or recursive vnode lock acquisition. Tested by: pho Approved by: des MFC after: 2 weeks Modified: head/sys/fs/pseudofs/pseudofs_vnops.c Modified: head/sys/fs/pseudofs/pseudofs_vnops.c ============================================================================== --- head/sys/fs/pseudofs/pseudofs_vnops.c Mon Dec 29 12:07:18 2008 (r186560) +++ head/sys/fs/pseudofs/pseudofs_vnops.c Mon Dec 29 12:12:23 2008 (r186561) @@ -476,7 +476,7 @@ pfs_read(struct vop_read_args *va) struct uio *uio = va->a_uio; struct proc *proc; struct sbuf *sb = NULL; - int error; + int error, locked; unsigned int buflen, offset, resid; PFS_TRACE(("%s", pn->pn_name)); @@ -502,13 +502,15 @@ pfs_read(struct vop_read_args *va) PROC_UNLOCK(proc); } + vhold(vn); + locked = VOP_ISLOCKED(vn); + VOP_UNLOCK(vn, 0); + if (pn->pn_flags & PFS_RAWRD) { PFS_TRACE(("%lu resid", (unsigned long)uio->uio_resid)); error = pn_fill(curthread, proc, pn, NULL, uio); PFS_TRACE(("%lu resid", (unsigned long)uio->uio_resid)); - if (proc != NULL) - PRELE(proc); - PFS_RETURN (error); + goto ret; } /* beaucoup sanity checks so we don't ask for bogus allocation */ @@ -518,34 +520,35 @@ pfs_read(struct vop_read_args *va) (buflen = offset + resid + 1) < offset || buflen > INT_MAX) { if (proc != NULL) PRELE(proc); - PFS_RETURN (EINVAL); + error = EINVAL; + goto ret; } if (buflen > MAXPHYS + 1) { - if (proc != NULL) - PRELE(proc); - PFS_RETURN (EIO); + error = EIO; + goto ret; } sb = sbuf_new(sb, NULL, buflen, 0); if (sb == NULL) { - if (proc != NULL) - PRELE(proc); - PFS_RETURN (EIO); + error = EIO; + goto ret; } error = pn_fill(curthread, proc, pn, sb, uio); - if (proc != NULL) - PRELE(proc); - if (error) { sbuf_delete(sb); - PFS_RETURN (error); + goto ret; } sbuf_finish(sb); error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio); sbuf_delete(sb); +ret: + vn_lock(vn, locked | LK_RETRY); + vdrop(vn); + if (proc != NULL) + PRELE(proc); PFS_RETURN (error); }