Skip to content

Commit

Permalink
vfs: get rid of 'struct dcache_hash_bucket' abstraction
Browse files Browse the repository at this point in the history
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: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Linus Torvalds committed Apr 24, 2011
1 parent 0f1d9f7 commit b07ad99
Showing 1 changed file with 21 additions and 24 deletions.
45 changes: 21 additions & 24 deletions fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,24 @@ static struct kmem_cache *dentry_cache __read_mostly;
static unsigned int d_hash_mask __read_mostly;
static unsigned int d_hash_shift __read_mostly;

struct dcache_hash_bucket {
struct hlist_bl_head head;
};
static struct dcache_hash_bucket *dentry_hashtable __read_mostly;
static struct hlist_bl_head *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)
{
hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES;
hash = hash ^ ((hash ^ GOLDEN_RATIO_PRIME) >> D_HASHBITS);
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. */
Expand Down Expand Up @@ -331,15 +328,15 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
void __d_drop(struct dentry *dentry)
{
if (!(dentry->d_flags & DCACHE_UNHASHED)) {
struct hlist_bl_head *b;
if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) {
bit_spin_lock(0,
(unsigned long *)&dentry->d_sb->s_anon.first);
b = &dentry->d_sb->s_anon;
spin_lock_bucket(b);
dentry->d_flags |= DCACHE_UNHASHED;
hlist_bl_del_init(&dentry->d_hash);
__bit_spin_unlock(0,
(unsigned long *)&dentry->d_sb->s_anon.first);
spin_unlock_bucket(b);
} else {
struct dcache_hash_bucket *b;
struct hlist_bl_head *b;
b = d_hash(dentry->d_parent, dentry->d_name.hash);
spin_lock_bucket(b);
/*
Expand Down Expand Up @@ -1789,7 +1786,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
unsigned int len = name->len;
unsigned int hash = name->hash;
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 dentry *dentry;

Expand All @@ -1813,7 +1810,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
*
* 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;
const char *tname;
int tlen;
Expand Down Expand Up @@ -1908,7 +1905,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name)
unsigned int len = name->len;
unsigned int hash = name->hash;
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 dentry *found = NULL;
struct dentry *dentry;
Expand All @@ -1935,7 +1932,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name)
*/
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;
int tlen;

Expand Down Expand Up @@ -2086,12 +2083,12 @@ void d_delete(struct dentry * dentry)
}
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));
spin_lock_bucket(b);
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);
}

Expand Down Expand Up @@ -3025,7 +3022,7 @@ static void __init dcache_init_early(void)

dentry_hashtable =
alloc_large_system_hash("Dentry cache",
sizeof(struct dcache_hash_bucket),
sizeof(struct hlist_bl_head),
dhash_entries,
13,
HASH_EARLY,
Expand All @@ -3034,7 +3031,7 @@ static void __init dcache_init_early(void)
0);

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)
Expand All @@ -3057,7 +3054,7 @@ static void __init dcache_init(void)

dentry_hashtable =
alloc_large_system_hash("Dentry cache",
sizeof(struct dcache_hash_bucket),
sizeof(struct hlist_bl_head),
dhash_entries,
13,
0,
Expand All @@ -3066,7 +3063,7 @@ static void __init dcache_init(void)
0);

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 */
Expand Down

0 comments on commit b07ad99

Please sign in to comment.