Commit 5dd12af05ca6b7d052c06a9ca4ff755fdfa25ae4
Exists in
master
and in
7 other branches
Merge branch 'dcache-cleanup'
* dcache-cleanup: vfs: get rid of insane dentry hashing rules
Showing 2 changed files Side-by-side Diff
fs/dcache.c
... | ... | @@ -164,8 +164,8 @@ |
164 | 164 | if (dentry->d_op && dentry->d_op->d_release) |
165 | 165 | dentry->d_op->d_release(dentry); |
166 | 166 | |
167 | - /* if dentry was never inserted into hash, immediate free is OK */ | |
168 | - if (hlist_bl_unhashed(&dentry->d_hash)) | |
167 | + /* if dentry was never visible to RCU, immediate free is OK */ | |
168 | + if (!(dentry->d_flags & DCACHE_RCUACCESS)) | |
169 | 169 | __d_free(&dentry->d_u.d_rcu); |
170 | 170 | else |
171 | 171 | call_rcu(&dentry->d_u.d_rcu, __d_free); |
172 | 172 | |
173 | 173 | |
174 | 174 | |
... | ... | @@ -327,28 +327,19 @@ |
327 | 327 | */ |
328 | 328 | void __d_drop(struct dentry *dentry) |
329 | 329 | { |
330 | - if (!(dentry->d_flags & DCACHE_UNHASHED)) { | |
330 | + if (!d_unhashed(dentry)) { | |
331 | 331 | struct hlist_bl_head *b; |
332 | - if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) { | |
332 | + if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) | |
333 | 333 | b = &dentry->d_sb->s_anon; |
334 | - spin_lock_bucket(b); | |
335 | - dentry->d_flags |= DCACHE_UNHASHED; | |
336 | - hlist_bl_del_init(&dentry->d_hash); | |
337 | - spin_unlock_bucket(b); | |
338 | - } else { | |
339 | - struct hlist_bl_head *b; | |
334 | + else | |
340 | 335 | b = d_hash(dentry->d_parent, dentry->d_name.hash); |
341 | - spin_lock_bucket(b); | |
342 | - /* | |
343 | - * We may not actually need to put DCACHE_UNHASHED | |
344 | - * manipulations under the hash lock, but follow | |
345 | - * the principle of least surprise. | |
346 | - */ | |
347 | - dentry->d_flags |= DCACHE_UNHASHED; | |
348 | - hlist_bl_del_rcu(&dentry->d_hash); | |
349 | - spin_unlock_bucket(b); | |
350 | - dentry_rcuwalk_barrier(dentry); | |
351 | - } | |
336 | + | |
337 | + spin_lock_bucket(b); | |
338 | + __hlist_bl_del(&dentry->d_hash); | |
339 | + dentry->d_hash.pprev = NULL; | |
340 | + spin_unlock_bucket(b); | |
341 | + | |
342 | + dentry_rcuwalk_barrier(dentry); | |
352 | 343 | } |
353 | 344 | } |
354 | 345 | EXPORT_SYMBOL(__d_drop); |
... | ... | @@ -1301,7 +1292,7 @@ |
1301 | 1292 | dname[name->len] = 0; |
1302 | 1293 | |
1303 | 1294 | dentry->d_count = 1; |
1304 | - dentry->d_flags = DCACHE_UNHASHED; | |
1295 | + dentry->d_flags = 0; | |
1305 | 1296 | spin_lock_init(&dentry->d_lock); |
1306 | 1297 | seqcount_init(&dentry->d_seq); |
1307 | 1298 | dentry->d_inode = NULL; |
1308 | 1299 | |
... | ... | @@ -1603,10 +1594,9 @@ |
1603 | 1594 | tmp->d_inode = inode; |
1604 | 1595 | tmp->d_flags |= DCACHE_DISCONNECTED; |
1605 | 1596 | list_add(&tmp->d_alias, &inode->i_dentry); |
1606 | - bit_spin_lock(0, (unsigned long *)&tmp->d_sb->s_anon.first); | |
1607 | - tmp->d_flags &= ~DCACHE_UNHASHED; | |
1597 | + spin_lock_bucket(&tmp->d_sb->s_anon); | |
1608 | 1598 | hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); |
1609 | - __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first); | |
1599 | + spin_unlock_bucket(&tmp->d_sb->s_anon); | |
1610 | 1600 | spin_unlock(&tmp->d_lock); |
1611 | 1601 | spin_unlock(&inode->i_lock); |
1612 | 1602 | security_d_instantiate(tmp, inode); |
... | ... | @@ -2087,7 +2077,7 @@ |
2087 | 2077 | { |
2088 | 2078 | BUG_ON(!d_unhashed(entry)); |
2089 | 2079 | spin_lock_bucket(b); |
2090 | - entry->d_flags &= ~DCACHE_UNHASHED; | |
2080 | + entry->d_flags |= DCACHE_RCUACCESS; | |
2091 | 2081 | hlist_bl_add_head_rcu(&entry->d_hash, b); |
2092 | 2082 | spin_unlock_bucket(b); |
2093 | 2083 | } |
include/linux/dcache.h
... | ... | @@ -197,7 +197,7 @@ |
197 | 197 | * typically using d_splice_alias. */ |
198 | 198 | |
199 | 199 | #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ |
200 | -#define DCACHE_UNHASHED 0x0010 | |
200 | +#define DCACHE_RCUACCESS 0x0010 /* Entry has ever been RCU-visible */ | |
201 | 201 | #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 |
202 | 202 | /* Parent inode is watched by inotify */ |
203 | 203 | |
... | ... | @@ -384,7 +384,7 @@ |
384 | 384 | |
385 | 385 | static inline int d_unhashed(struct dentry *dentry) |
386 | 386 | { |
387 | - return (dentry->d_flags & DCACHE_UNHASHED); | |
387 | + return hlist_bl_unhashed(&dentry->d_hash); | |
388 | 388 | } |
389 | 389 | |
390 | 390 | static inline int d_unlinked(struct dentry *dentry) |