diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-03-30 14:13:15 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-03-31 16:03:16 -0400 |
commit | acc9cb3cd425f479d8fc4a441bff45dce23aa6dd (patch) | |
tree | 08ffc4b16ad2d00069189440dbfd4b893e2cc96e /fs | |
parent | 37c17e1f377696c797e75c1e915e838b3e0c6120 (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.c | 12 |
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); |
1176 | l: | ||
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); |