diff options
-rw-r--r-- | fs/dcache.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index ccdc5c2512df..01f016799fd4 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1828,10 +1828,15 @@ void d_delete(struct dentry * dentry) | |||
1828 | /* | 1828 | /* |
1829 | * Are we the only user? | 1829 | * Are we the only user? |
1830 | */ | 1830 | */ |
1831 | spin_lock(&dcache_inode_lock); | 1831 | again: |
1832 | spin_lock(&dentry->d_lock); | 1832 | spin_lock(&dentry->d_lock); |
1833 | isdir = S_ISDIR(dentry->d_inode->i_mode); | 1833 | isdir = S_ISDIR(dentry->d_inode->i_mode); |
1834 | if (dentry->d_count == 1) { | 1834 | if (dentry->d_count == 1) { |
1835 | if (!spin_trylock(&dcache_inode_lock)) { | ||
1836 | spin_unlock(&dentry->d_lock); | ||
1837 | cpu_relax(); | ||
1838 | goto again; | ||
1839 | } | ||
1835 | dentry->d_flags &= ~DCACHE_CANT_MOUNT; | 1840 | dentry->d_flags &= ~DCACHE_CANT_MOUNT; |
1836 | dentry_iput(dentry); | 1841 | dentry_iput(dentry); |
1837 | fsnotify_nameremove(dentry, isdir); | 1842 | fsnotify_nameremove(dentry, isdir); |
@@ -1842,7 +1847,6 @@ void d_delete(struct dentry * dentry) | |||
1842 | __d_drop(dentry); | 1847 | __d_drop(dentry); |
1843 | 1848 | ||
1844 | spin_unlock(&dentry->d_lock); | 1849 | spin_unlock(&dentry->d_lock); |
1845 | spin_unlock(&dcache_inode_lock); | ||
1846 | 1850 | ||
1847 | fsnotify_nameremove(dentry, isdir); | 1851 | fsnotify_nameremove(dentry, isdir); |
1848 | } | 1852 | } |
@@ -2164,14 +2168,15 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) | |||
2164 | 2168 | ||
2165 | BUG_ON(!d_unhashed(dentry)); | 2169 | BUG_ON(!d_unhashed(dentry)); |
2166 | 2170 | ||
2167 | spin_lock(&dcache_inode_lock); | ||
2168 | |||
2169 | if (!inode) { | 2171 | if (!inode) { |
2170 | actual = dentry; | 2172 | actual = dentry; |
2171 | __d_instantiate(dentry, NULL); | 2173 | __d_instantiate(dentry, NULL); |
2172 | goto found_lock; | 2174 | d_rehash(actual); |
2175 | goto out_nolock; | ||
2173 | } | 2176 | } |
2174 | 2177 | ||
2178 | spin_lock(&dcache_inode_lock); | ||
2179 | |||
2175 | if (S_ISDIR(inode->i_mode)) { | 2180 | if (S_ISDIR(inode->i_mode)) { |
2176 | struct dentry *alias; | 2181 | struct dentry *alias; |
2177 | 2182 | ||
@@ -2198,10 +2203,9 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) | |||
2198 | actual = __d_instantiate_unique(dentry, inode); | 2203 | actual = __d_instantiate_unique(dentry, inode); |
2199 | if (!actual) | 2204 | if (!actual) |
2200 | actual = dentry; | 2205 | actual = dentry; |
2201 | else if (unlikely(!d_unhashed(actual))) | 2206 | else |
2202 | goto shouldnt_be_hashed; | 2207 | BUG_ON(!d_unhashed(actual)); |
2203 | 2208 | ||
2204 | found_lock: | ||
2205 | spin_lock(&actual->d_lock); | 2209 | spin_lock(&actual->d_lock); |
2206 | found: | 2210 | found: |
2207 | spin_lock(&dcache_hash_lock); | 2211 | spin_lock(&dcache_hash_lock); |
@@ -2217,10 +2221,6 @@ out_nolock: | |||
2217 | 2221 | ||
2218 | iput(inode); | 2222 | iput(inode); |
2219 | return actual; | 2223 | return actual; |
2220 | |||
2221 | shouldnt_be_hashed: | ||
2222 | spin_unlock(&dcache_inode_lock); | ||
2223 | BUG(); | ||
2224 | } | 2224 | } |
2225 | EXPORT_SYMBOL_GPL(d_materialise_unique); | 2225 | EXPORT_SYMBOL_GPL(d_materialise_unique); |
2226 | 2226 | ||