Skip to content

Commit

Permalink
add hlist_bl_lock/unlock helpers
Browse files Browse the repository at this point in the history
Now that the whole dcache_hash_bucket crap is gone, go all the way and
also remove the weird locking layering violations for locking the hash
buckets.  Add hlist_bl_lock/unlock helpers to move the locking into the
list abstraction instead of requiring each caller to open code it.
After all allowing for the bit locks is the whole point of these helpers
over the plain hlist variant.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Christoph Hellwig authored and Linus Torvalds committed Apr 26, 2011
1 parent 3dd2ee4 commit 1879fd6
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 20 deletions.
22 changes: 6 additions & 16 deletions fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,6 @@ static inline struct hlist_bl_head *d_hash(struct dentry *parent,
return dentry_hashtable + (hash & D_HASHMASK);
}

static inline void spin_lock_bucket(struct hlist_bl_head *b)
{
bit_spin_lock(0, (unsigned long *)&b->first);
}

static inline void spin_unlock_bucket(struct hlist_bl_head *b)
{
__bit_spin_unlock(0, (unsigned long *)&b->first);
}

/* Statistics gathering. */
struct dentry_stat_t dentry_stat = {
.age_limit = 45,
Expand Down Expand Up @@ -334,10 +324,10 @@ void __d_drop(struct dentry *dentry)
else
b = d_hash(dentry->d_parent, dentry->d_name.hash);

spin_lock_bucket(b);
hlist_bl_lock(b);
__hlist_bl_del(&dentry->d_hash);
dentry->d_hash.pprev = NULL;
spin_unlock_bucket(b);
hlist_bl_unlock(b);

dentry_rcuwalk_barrier(dentry);
}
Expand Down Expand Up @@ -1594,9 +1584,9 @@ struct dentry *d_obtain_alias(struct inode *inode)
tmp->d_inode = inode;
tmp->d_flags |= DCACHE_DISCONNECTED;
list_add(&tmp->d_alias, &inode->i_dentry);
spin_lock_bucket(&tmp->d_sb->s_anon);
hlist_bl_lock(&tmp->d_sb->s_anon);
hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
spin_unlock_bucket(&tmp->d_sb->s_anon);
hlist_bl_unlock(&tmp->d_sb->s_anon);
spin_unlock(&tmp->d_lock);
spin_unlock(&inode->i_lock);
security_d_instantiate(tmp, inode);
Expand Down Expand Up @@ -2076,10 +2066,10 @@ EXPORT_SYMBOL(d_delete);
static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b)
{
BUG_ON(!d_unhashed(entry));
spin_lock_bucket(b);
hlist_bl_lock(b);
entry->d_flags |= DCACHE_RCUACCESS;
hlist_bl_add_head_rcu(&entry->d_hash, b);
spin_unlock_bucket(b);
hlist_bl_unlock(b);
}

static void _d_rehash(struct dentry * entry)
Expand Down
6 changes: 2 additions & 4 deletions fs/gfs2/glock.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,12 @@ static unsigned int gl_hash(const struct gfs2_sbd *sdp,

static inline void spin_lock_bucket(unsigned int hash)
{
struct hlist_bl_head *bl = &gl_hash_table[hash];
bit_spin_lock(0, (unsigned long *)bl);
hlist_bl_lock(&gl_hash_table[hash]);
}

static inline void spin_unlock_bucket(unsigned int hash)
{
struct hlist_bl_head *bl = &gl_hash_table[hash];
__bit_spin_unlock(0, (unsigned long *)bl);
hlist_bl_unlock(&gl_hash_table[hash]);
}

static void gfs2_glock_dealloc(struct rcu_head *rcu)
Expand Down
11 changes: 11 additions & 0 deletions include/linux/list_bl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _LINUX_LIST_BL_H

#include <linux/list.h>
#include <linux/bit_spinlock.h>

/*
* Special version of lists, where head of the list has a lock in the lowest
Expand Down Expand Up @@ -114,6 +115,16 @@ static inline void hlist_bl_del_init(struct hlist_bl_node *n)
}
}

static inline void hlist_bl_lock(struct hlist_bl_head *b)
{
bit_spin_lock(0, (unsigned long *)b);
}

static inline void hlist_bl_unlock(struct hlist_bl_head *b)
{
__bit_spin_unlock(0, (unsigned long *)b);
}

/**
* hlist_bl_for_each_entry - iterate over list of given type
* @tpos: the type * to use as a loop cursor.
Expand Down

0 comments on commit 1879fd6

Please sign in to comment.