>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.kurt...@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:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to