diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 8086636bf796..3a463d0c4fe8 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -389,7 +389,7 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) | |||
389 | * Inform try_to_ascend() that we are no longer attached to the | 389 | * Inform try_to_ascend() that we are no longer attached to the |
390 | * dentry tree | 390 | * dentry tree |
391 | */ | 391 | */ |
392 | dentry->d_flags |= DCACHE_DISCONNECTED; | 392 | dentry->d_flags |= DCACHE_DENTRY_KILLED; |
393 | if (parent) | 393 | if (parent) |
394 | spin_unlock(&parent->d_lock); | 394 | spin_unlock(&parent->d_lock); |
395 | dentry_iput(dentry); | 395 | dentry_iput(dentry); |
@@ -1048,7 +1048,7 @@ static struct dentry *try_to_ascend(struct dentry *old, int locked, unsigned seq | |||
1048 | * or deletion | 1048 | * or deletion |
1049 | */ | 1049 | */ |
1050 | if (new != old->d_parent || | 1050 | if (new != old->d_parent || |
1051 | (old->d_flags & DCACHE_DISCONNECTED) || | 1051 | (old->d_flags & DCACHE_DENTRY_KILLED) || |
1052 | (!locked && read_seqretry(&rename_lock, seq))) { | 1052 | (!locked && read_seqretry(&rename_lock, seq))) { |
1053 | spin_unlock(&new->d_lock); | 1053 | spin_unlock(&new->d_lock); |
1054 | new = NULL; | 1054 | new = NULL; |
@@ -1134,6 +1134,8 @@ positive: | |||
1134 | return 1; | 1134 | return 1; |
1135 | 1135 | ||
1136 | rename_retry: | 1136 | rename_retry: |
1137 | if (locked) | ||
1138 | goto again; | ||
1137 | locked = 1; | 1139 | locked = 1; |
1138 | write_seqlock(&rename_lock); | 1140 | write_seqlock(&rename_lock); |
1139 | goto again; | 1141 | goto again; |
@@ -1141,7 +1143,7 @@ rename_retry: | |||
1141 | EXPORT_SYMBOL(have_submounts); | 1143 | EXPORT_SYMBOL(have_submounts); |
1142 | 1144 | ||
1143 | /* | 1145 | /* |
1144 | * Search the dentry child list for the specified parent, | 1146 | * Search the dentry child list of the specified parent, |
1145 | * and move any unused dentries to the end of the unused | 1147 | * and move any unused dentries to the end of the unused |
1146 | * list for prune_dcache(). We descend to the next level | 1148 | * list for prune_dcache(). We descend to the next level |
1147 | * whenever the d_subdirs list is non-empty and continue | 1149 | * whenever the d_subdirs list is non-empty and continue |
@@ -1236,6 +1238,8 @@ out: | |||
1236 | rename_retry: | 1238 | rename_retry: |
1237 | if (found) | 1239 | if (found) |
1238 | return found; | 1240 | return found; |
1241 | if (locked) | ||
1242 | goto again; | ||
1239 | locked = 1; | 1243 | locked = 1; |
1240 | write_seqlock(&rename_lock); | 1244 | write_seqlock(&rename_lock); |
1241 | goto again; | 1245 | goto again; |
@@ -2109,7 +2113,7 @@ again: | |||
2109 | inode = dentry->d_inode; | 2113 | inode = dentry->d_inode; |
2110 | isdir = S_ISDIR(inode->i_mode); | 2114 | isdir = S_ISDIR(inode->i_mode); |
2111 | if (dentry->d_count == 1) { | 2115 | if (dentry->d_count == 1) { |
2112 | if (inode && !spin_trylock(&inode->i_lock)) { | 2116 | if (!spin_trylock(&inode->i_lock)) { |
2113 | spin_unlock(&dentry->d_lock); | 2117 | spin_unlock(&dentry->d_lock); |
2114 | cpu_relax(); | 2118 | cpu_relax(); |
2115 | goto again; | 2119 | goto again; |
@@ -3035,6 +3039,8 @@ resume: | |||
3035 | return; | 3039 | return; |
3036 | 3040 | ||
3037 | rename_retry: | 3041 | rename_retry: |
3042 | if (locked) | ||
3043 | goto again; | ||
3038 | locked = 1; | 3044 | locked = 1; |
3039 | write_seqlock(&rename_lock); | 3045 | write_seqlock(&rename_lock); |
3040 | goto again; | 3046 | goto again; |