diff options
| -rw-r--r-- | fs/namei.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/fs/namei.c b/fs/namei.c index a919affd1531..5eeec562a03d 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1208,22 +1208,14 @@ unlazy: | |||
| 1208 | dentry = __d_lookup(parent, name); | 1208 | dentry = __d_lookup(parent, name); |
| 1209 | } | 1209 | } |
| 1210 | 1210 | ||
| 1211 | if (dentry && unlikely(d_need_lookup(dentry))) { | 1211 | if (unlikely(!dentry)) |
| 1212 | goto need_lookup; | ||
| 1213 | |||
| 1214 | if (unlikely(d_need_lookup(dentry))) { | ||
| 1212 | dput(dentry); | 1215 | dput(dentry); |
| 1213 | dentry = NULL; | 1216 | goto need_lookup; |
| 1214 | } | 1217 | } |
| 1215 | retry: | ||
| 1216 | if (unlikely(!dentry)) { | ||
| 1217 | struct inode *dir = parent->d_inode; | ||
| 1218 | BUG_ON(nd->inode != dir); | ||
| 1219 | 1218 | ||
| 1220 | mutex_lock(&dir->i_mutex); | ||
| 1221 | dentry = __lookup_hash(name, parent, nd); | ||
| 1222 | mutex_unlock(&dir->i_mutex); | ||
| 1223 | if (IS_ERR(dentry)) | ||
| 1224 | return PTR_ERR(dentry); | ||
| 1225 | goto done; | ||
| 1226 | } | ||
| 1227 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) | 1219 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) |
| 1228 | status = d_revalidate(dentry, nd); | 1220 | status = d_revalidate(dentry, nd); |
| 1229 | if (unlikely(status <= 0)) { | 1221 | if (unlikely(status <= 0)) { |
| @@ -1233,8 +1225,7 @@ retry: | |||
| 1233 | } | 1225 | } |
| 1234 | if (!d_invalidate(dentry)) { | 1226 | if (!d_invalidate(dentry)) { |
| 1235 | dput(dentry); | 1227 | dput(dentry); |
| 1236 | dentry = NULL; | 1228 | goto need_lookup; |
| 1237 | goto retry; | ||
| 1238 | } | 1229 | } |
| 1239 | } | 1230 | } |
| 1240 | done: | 1231 | done: |
| @@ -1249,6 +1240,16 @@ done: | |||
| 1249 | nd->flags |= LOOKUP_JUMPED; | 1240 | nd->flags |= LOOKUP_JUMPED; |
| 1250 | *inode = path->dentry->d_inode; | 1241 | *inode = path->dentry->d_inode; |
| 1251 | return 0; | 1242 | return 0; |
| 1243 | |||
| 1244 | need_lookup: | ||
| 1245 | BUG_ON(nd->inode != parent->d_inode); | ||
| 1246 | |||
| 1247 | mutex_lock(&parent->d_inode->i_mutex); | ||
| 1248 | dentry = __lookup_hash(name, parent, nd); | ||
| 1249 | mutex_unlock(&parent->d_inode->i_mutex); | ||
| 1250 | if (IS_ERR(dentry)) | ||
| 1251 | return PTR_ERR(dentry); | ||
| 1252 | goto done; | ||
| 1252 | } | 1253 | } |
| 1253 | 1254 | ||
| 1254 | static inline int may_lookup(struct nameidata *nd) | 1255 | static inline int may_lookup(struct nameidata *nd) |
