]> Pileus Git - ~andy/linux/commitdiff
untangling do_lookup() - eliminate a loop.
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 30 Mar 2012 18:13:15 +0000 (14:13 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 31 Mar 2012 20:03:16 +0000 (16:03 -0400)
d_lookup() *will* fail after successful d_invalidate(), if we are
holding i_mutex all along.  IOW, we don't need to jump back to
l: - we know what path will be taken there and can do that (i.e.
d_alloc_and_lookup()) directly.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c

index 48fc0fb8c9d17719d4a47fe6d7b211df9376bf17..9ce43a358c33e047b95a3e2153351af824377ffd 100644 (file)
@@ -1173,7 +1173,6 @@ retry:
                BUG_ON(nd->inode != dir);
 
                mutex_lock(&dir->i_mutex);
-l:
                dentry = d_lookup(parent, name);
                if (likely(!dentry)) {
                        dentry = d_alloc_and_lookup(parent, name, nd);
@@ -1204,9 +1203,14 @@ l:
                        }
                        if (!d_invalidate(dentry)) {
                                dput(dentry);
-                               dentry = NULL;
-                               need_reval = 1;
-                               goto l;
+                               dentry = d_alloc_and_lookup(parent, name, nd);
+                               if (IS_ERR(dentry)) {
+                                       mutex_unlock(&dir->i_mutex);
+                                       return PTR_ERR(dentry);
+                               }
+                               /* known good */
+                               need_reval = 0;
+                               status = 1;
                        }
                }
                mutex_unlock(&dir->i_mutex);