aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-03-30 14:13:15 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-03-31 16:03:16 -0400
commitacc9cb3cd425f479d8fc4a441bff45dce23aa6dd (patch)
tree08ffc4b16ad2d00069189440dbfd4b893e2cc96e /fs
parent37c17e1f377696c797e75c1e915e838b3e0c6120 (diff)
untangling do_lookup() - eliminate a loop.
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/namei.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 48fc0fb8c9d1..9ce43a358c33 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1173,7 +1173,6 @@ retry:
1173 BUG_ON(nd->inode != dir); 1173 BUG_ON(nd->inode != dir);
1174 1174
1175 mutex_lock(&dir->i_mutex); 1175 mutex_lock(&dir->i_mutex);
1176l:
1177 dentry = d_lookup(parent, name); 1176 dentry = d_lookup(parent, name);
1178 if (likely(!dentry)) { 1177 if (likely(!dentry)) {
1179 dentry = d_alloc_and_lookup(parent, name, nd); 1178 dentry = d_alloc_and_lookup(parent, name, nd);
@@ -1204,9 +1203,14 @@ l:
1204 } 1203 }
1205 if (!d_invalidate(dentry)) { 1204 if (!d_invalidate(dentry)) {
1206 dput(dentry); 1205 dput(dentry);
1207 dentry = NULL; 1206 dentry = d_alloc_and_lookup(parent, name, nd);
1208 need_reval = 1; 1207 if (IS_ERR(dentry)) {
1209 goto l; 1208 mutex_unlock(&dir->i_mutex);
1209 return PTR_ERR(dentry);
1210 }
1211 /* known good */
1212 need_reval = 0;
1213 status = 1;
1210 } 1214 }
1211 } 1215 }
1212 mutex_unlock(&dir->i_mutex); 1216 mutex_unlock(&dir->i_mutex);