提交 b07ad996 编写于 作者: L Linus Torvalds

vfs: get rid of 'struct dcache_hash_bucket' abstraction

It's a useless abstraction for 'hlist_bl_head', and it doesn't actually
help anything - quite the reverse.  All the users end up having to know
about the hlist_bl_head details anyway, using 'struct hlist_bl_node *'
etc. So it just makes the code look confusing.

And the cost of it is extra '&b->head' syntactic noise, but more
importantly it spuriously makes the hash table dentry list look
different from the per-superblock DCACHE_DISCONNECTED dentry list.

As a result, the code ended up using ad-hoc locking for one case and
special helper functions for what is really another totally identical
case in the very same function.

Make it all look and work the same.
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 0f1d9f78
...@@ -99,12 +99,9 @@ static struct kmem_cache *dentry_cache __read_mostly; ...@@ -99,12 +99,9 @@ static struct kmem_cache *dentry_cache __read_mostly;
static unsigned int d_hash_mask __read_mostly; static unsigned int d_hash_mask __read_mostly;
static unsigned int d_hash_shift __read_mostly; static unsigned int d_hash_shift __read_mostly;
struct dcache_hash_bucket { static struct hlist_bl_head *dentry_hashtable __read_mostly;
struct hlist_bl_head head;
};
static struct dcache_hash_bucket *dentry_hashtable __read_mostly;
static inline struct dcache_hash_bucket *d_hash(struct dentry *parent, static inline struct hlist_bl_head *d_hash(struct dentry *parent,
unsigned long hash) unsigned long hash)
{ {
hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES; hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES;
...@@ -112,14 +109,14 @@ static inline struct dcache_hash_bucket *d_hash(struct dentry *parent, ...@@ -112,14 +109,14 @@ static inline struct dcache_hash_bucket *d_hash(struct dentry *parent,
return dentry_hashtable + (hash & D_HASHMASK); return dentry_hashtable + (hash & D_HASHMASK);
} }
static inline void spin_lock_bucket(struct dcache_hash_bucket *b) static inline void spin_lock_bucket(struct hlist_bl_head *b)
{ {
bit_spin_lock(0, (unsigned long *)&b->head.first); bit_spin_lock(0, (unsigned long *)&b->first);
} }
static inline void spin_unlock_bucket(struct dcache_hash_bucket *b) static inline void spin_unlock_bucket(struct hlist_bl_head *b)
{ {
__bit_spin_unlock(0, (unsigned long *)&b->head.first); __bit_spin_unlock(0, (unsigned long *)&b->first);
} }
/* Statistics gathering. */ /* Statistics gathering. */
...@@ -331,15 +328,15 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) ...@@ -331,15 +328,15 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
void __d_drop(struct dentry *dentry) void __d_drop(struct dentry *dentry)
{ {
if (!(dentry->d_flags & DCACHE_UNHASHED)) { if (!(dentry->d_flags & DCACHE_UNHASHED)) {
struct hlist_bl_head *b;
if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) { if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) {
bit_spin_lock(0, b = &dentry->d_sb->s_anon;
(unsigned long *)&dentry->d_sb->s_anon.first); spin_lock_bucket(b);
dentry->d_flags |= DCACHE_UNHASHED; dentry->d_flags |= DCACHE_UNHASHED;
hlist_bl_del_init(&dentry->d_hash); hlist_bl_del_init(&dentry->d_hash);
__bit_spin_unlock(0, spin_unlock_bucket(b);
(unsigned long *)&dentry->d_sb->s_anon.first);
} else { } else {
struct dcache_hash_bucket *b; struct hlist_bl_head *b;
b = d_hash(dentry->d_parent, dentry->d_name.hash); b = d_hash(dentry->d_parent, dentry->d_name.hash);
spin_lock_bucket(b); spin_lock_bucket(b);
/* /*
...@@ -1789,7 +1786,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, ...@@ -1789,7 +1786,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
unsigned int len = name->len; unsigned int len = name->len;
unsigned int hash = name->hash; unsigned int hash = name->hash;
const unsigned char *str = name->name; const unsigned char *str = name->name;
struct dcache_hash_bucket *b = d_hash(parent, hash); struct hlist_bl_head *b = d_hash(parent, hash);
struct hlist_bl_node *node; struct hlist_bl_node *node;
struct dentry *dentry; struct dentry *dentry;
...@@ -1813,7 +1810,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, ...@@ -1813,7 +1810,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
* *
* See Documentation/filesystems/path-lookup.txt for more details. * See Documentation/filesystems/path-lookup.txt for more details.
*/ */
hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) { hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
struct inode *i; struct inode *i;
const char *tname; const char *tname;
int tlen; int tlen;
...@@ -1908,7 +1905,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) ...@@ -1908,7 +1905,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name)
unsigned int len = name->len; unsigned int len = name->len;
unsigned int hash = name->hash; unsigned int hash = name->hash;
const unsigned char *str = name->name; const unsigned char *str = name->name;
struct dcache_hash_bucket *b = d_hash(parent, hash); struct hlist_bl_head *b = d_hash(parent, hash);
struct hlist_bl_node *node; struct hlist_bl_node *node;
struct dentry *found = NULL; struct dentry *found = NULL;
struct dentry *dentry; struct dentry *dentry;
...@@ -1935,7 +1932,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) ...@@ -1935,7 +1932,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name)
*/ */
rcu_read_lock(); rcu_read_lock();
hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) { hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
const char *tname; const char *tname;
int tlen; int tlen;
...@@ -2086,12 +2083,12 @@ void d_delete(struct dentry * dentry) ...@@ -2086,12 +2083,12 @@ void d_delete(struct dentry * dentry)
} }
EXPORT_SYMBOL(d_delete); EXPORT_SYMBOL(d_delete);
static void __d_rehash(struct dentry * entry, struct dcache_hash_bucket *b) static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b)
{ {
BUG_ON(!d_unhashed(entry)); BUG_ON(!d_unhashed(entry));
spin_lock_bucket(b); spin_lock_bucket(b);
entry->d_flags &= ~DCACHE_UNHASHED; entry->d_flags &= ~DCACHE_UNHASHED;
hlist_bl_add_head_rcu(&entry->d_hash, &b->head); hlist_bl_add_head_rcu(&entry->d_hash, b);
spin_unlock_bucket(b); spin_unlock_bucket(b);
} }
...@@ -3025,7 +3022,7 @@ static void __init dcache_init_early(void) ...@@ -3025,7 +3022,7 @@ static void __init dcache_init_early(void)
dentry_hashtable = dentry_hashtable =
alloc_large_system_hash("Dentry cache", alloc_large_system_hash("Dentry cache",
sizeof(struct dcache_hash_bucket), sizeof(struct hlist_bl_head),
dhash_entries, dhash_entries,
13, 13,
HASH_EARLY, HASH_EARLY,
...@@ -3034,7 +3031,7 @@ static void __init dcache_init_early(void) ...@@ -3034,7 +3031,7 @@ static void __init dcache_init_early(void)
0); 0);
for (loop = 0; loop < (1 << d_hash_shift); loop++) for (loop = 0; loop < (1 << d_hash_shift); loop++)
INIT_HLIST_BL_HEAD(&dentry_hashtable[loop].head); INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
} }
static void __init dcache_init(void) static void __init dcache_init(void)
...@@ -3057,7 +3054,7 @@ static void __init dcache_init(void) ...@@ -3057,7 +3054,7 @@ static void __init dcache_init(void)
dentry_hashtable = dentry_hashtable =
alloc_large_system_hash("Dentry cache", alloc_large_system_hash("Dentry cache",
sizeof(struct dcache_hash_bucket), sizeof(struct hlist_bl_head),
dhash_entries, dhash_entries,
13, 13,
0, 0,
...@@ -3066,7 +3063,7 @@ static void __init dcache_init(void) ...@@ -3066,7 +3063,7 @@ static void __init dcache_init(void)
0); 0);
for (loop = 0; loop < (1 << d_hash_shift); loop++) for (loop = 0; loop < (1 << d_hash_shift); loop++)
INIT_HLIST_BL_HEAD(&dentry_hashtable[loop].head); INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
} }
/* SLAB cache for __getname() consumers */ /* SLAB cache for __getname() consumers */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册