Date: Tue, 31 Aug 2010 10:49:13 GMT From: Gleb Kurtsou <gk@FreeBSD.org> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/150143: [patch][tmpfs] Source directory vnode can disappear before locking it in tmpfs_rename Message-ID: <201008311049.o7VAnD8Z048257@www.freebsd.org> Resent-Message-ID: <201008311050.o7VAo2LI061032@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 150143 >Category: kern >Synopsis: [patch][tmpfs] Source directory vnode can disappear before locking it in tmpfs_rename >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Aug 31 10:50:02 UTC 2010 >Closed-Date: >Last-Modified: >Originator: Gleb Kurtsou >Release: FreeBSD 9.0-CURRENT >Organization: >Environment: >Description: Source directory vnode can disappear before locking it in tmpfs_rename. Fixes panic triggered by blogbench. Also note that fdvp vnode locking order may be incorrect in tmpfs_rename, and thus rename is deadlock prone. It was initially incorrect, possible solution could be to lock all necessary vnodes similarly to ufs, but it seems not to work well with tmpfs. >How-To-Repeat: >Fix: Patch attached, tested by Ivan Voras Patch attached with submission follows: commit 82d1664e6831dbc44d380170ed5590ff67113749 Author: Gleb Kurtsou <gleb.kurtsou@gmail.com> Date: Thu Aug 12 13:05:17 2010 +0300 tmpfs: Source entry can disappear before we lock fdvp in tmpfs_rename() Fixes panic triggered by blogbench diff --git a/fs/tmpfs/tmpfs_vnops.c b/fs/tmpfs/tmpfs_vnops.c index ef54e5e..117700b 100644 --- a/fs/tmpfs/tmpfs_vnops.c +++ b/fs/tmpfs/tmpfs_vnops.c @@ -991,10 +991,14 @@ tmpfs_rename(struct vop_rename_args *v) fnode = VP_TO_TMPFS_NODE(fvp); de = tmpfs_dir_lookup(fdnode, fnode, fcnp); - /* Avoid manipulating '.' and '..' entries. */ + /* Entry can disappear before we lock fdvp, + * also avoid manipulating '.' and '..' entries. */ if (de == NULL) { - MPASS(fvp->v_type == VDIR); - error = EINVAL; + if ((fcnp->cn_flags & ISDOTDOT) != 0 || + (fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.')) + error = EINVAL; + else + error = ENOENT; goto out_locked; } MPASS(de->td_node == fnode); >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008311049.o7VAnD8Z048257>