Commit 5dd12af05ca6b7d052c06a9ca4ff755fdfa25ae4

Authored by Linus Torvalds

Merge branch 'dcache-cleanup'

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

Showing 2 changed files Side-by-side Diff

... ... @@ -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)