Merge branch 'dcache-cleanup'

* dcache-cleanup:
vfs: get rid of insane dentry hashing rules

+18 -28
+16 -26
fs/dcache.c
··· 164 if (dentry->d_op && dentry->d_op->d_release) 165 dentry->d_op->d_release(dentry); 166 167 - /* if dentry was never inserted into hash, immediate free is OK */ 168 - if (hlist_bl_unhashed(&dentry->d_hash)) 169 __d_free(&dentry->d_u.d_rcu); 170 else 171 call_rcu(&dentry->d_u.d_rcu, __d_free); ··· 327 */ 328 void __d_drop(struct dentry *dentry) 329 { 330 - if (!(dentry->d_flags & DCACHE_UNHASHED)) { 331 struct hlist_bl_head *b; 332 - if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) { 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; 340 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 - } 352 } 353 } 354 EXPORT_SYMBOL(__d_drop); ··· 1292 dname[name->len] = 0; 1293 1294 dentry->d_count = 1; 1295 - dentry->d_flags = DCACHE_UNHASHED; 1296 spin_lock_init(&dentry->d_lock); 1297 seqcount_init(&dentry->d_seq); 1298 dentry->d_inode = NULL; ··· 1594 tmp->d_inode = inode; 1595 tmp->d_flags |= DCACHE_DISCONNECTED; 1596 list_add(&tmp->d_alias, &inode->i_dentry); 1597 - bit_spin_lock(0, (unsigned long *)&tmp->d_sb->s_anon.first); 1598 - tmp->d_flags &= ~DCACHE_UNHASHED; 1599 hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); 1600 - __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first); 1601 spin_unlock(&tmp->d_lock); 1602 spin_unlock(&inode->i_lock); 1603 security_d_instantiate(tmp, inode); ··· 2077 { 2078 BUG_ON(!d_unhashed(entry)); 2079 spin_lock_bucket(b); 2080 - entry->d_flags &= ~DCACHE_UNHASHED; 2081 hlist_bl_add_head_rcu(&entry->d_hash, b); 2082 spin_unlock_bucket(b); 2083 }
··· 164 if (dentry->d_op && dentry->d_op->d_release) 165 dentry->d_op->d_release(dentry); 166 167 + /* if dentry was never visible to RCU, immediate free is OK */ 168 + if (!(dentry->d_flags & DCACHE_RCUACCESS)) 169 __d_free(&dentry->d_u.d_rcu); 170 else 171 call_rcu(&dentry->d_u.d_rcu, __d_free); ··· 327 */ 328 void __d_drop(struct dentry *dentry) 329 { 330 + if (!d_unhashed(dentry)) { 331 struct hlist_bl_head *b; 332 + if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) 333 b = &dentry->d_sb->s_anon; 334 + else 335 b = d_hash(dentry->d_parent, dentry->d_name.hash); 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); 343 } 344 } 345 EXPORT_SYMBOL(__d_drop); ··· 1301 dname[name->len] = 0; 1302 1303 dentry->d_count = 1; 1304 + dentry->d_flags = 0; 1305 spin_lock_init(&dentry->d_lock); 1306 seqcount_init(&dentry->d_seq); 1307 dentry->d_inode = NULL; ··· 1603 tmp->d_inode = inode; 1604 tmp->d_flags |= DCACHE_DISCONNECTED; 1605 list_add(&tmp->d_alias, &inode->i_dentry); 1606 + spin_lock_bucket(&tmp->d_sb->s_anon); 1607 hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); 1608 + spin_unlock_bucket(&tmp->d_sb->s_anon); 1609 spin_unlock(&tmp->d_lock); 1610 spin_unlock(&inode->i_lock); 1611 security_d_instantiate(tmp, inode); ··· 2087 { 2088 BUG_ON(!d_unhashed(entry)); 2089 spin_lock_bucket(b); 2090 + entry->d_flags |= DCACHE_RCUACCESS; 2091 hlist_bl_add_head_rcu(&entry->d_hash, b); 2092 spin_unlock_bucket(b); 2093 }
+2 -2
include/linux/dcache.h
··· 197 * typically using d_splice_alias. */ 198 199 #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ 200 - #define DCACHE_UNHASHED 0x0010 201 #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 202 /* Parent inode is watched by inotify */ 203 ··· 384 385 static inline int d_unhashed(struct dentry *dentry) 386 { 387 - return (dentry->d_flags & DCACHE_UNHASHED); 388 } 389 390 static inline int d_unlinked(struct dentry *dentry)
··· 197 * typically using d_splice_alias. */ 198 199 #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ 200 + #define DCACHE_RCUACCESS 0x0010 /* Entry has ever been RCU-visible */ 201 #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 202 /* Parent inode is watched by inotify */ 203 ··· 384 385 static inline int d_unhashed(struct dentry *dentry) 386 { 387 + return hlist_bl_unhashed(&dentry->d_hash); 388 } 389 390 static inline int d_unlinked(struct dentry *dentry)