fs: Factor inode hash operations into functions
Before replacing the inode hash locking with a more scalable mechanism, factor the removal of the inode from the hashes rather than open coding it in several places. Based on a patch originally from Nick Piggin. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
100
fs/inode.c
100
fs/inode.c
@@ -336,6 +336,58 @@ static void inode_lru_list_del(struct inode *inode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long hash(struct super_block *sb, unsigned long hashval)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) /
|
||||||
|
L1_CACHE_BYTES;
|
||||||
|
tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS);
|
||||||
|
return tmp & I_HASHMASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __insert_inode_hash - hash an inode
|
||||||
|
* @inode: unhashed inode
|
||||||
|
* @hashval: unsigned long value used to locate this object in the
|
||||||
|
* inode_hashtable.
|
||||||
|
*
|
||||||
|
* Add an inode to the inode hash for this superblock.
|
||||||
|
*/
|
||||||
|
void __insert_inode_hash(struct inode *inode, unsigned long hashval)
|
||||||
|
{
|
||||||
|
struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval);
|
||||||
|
spin_lock(&inode_lock);
|
||||||
|
hlist_add_head(&inode->i_hash, head);
|
||||||
|
spin_unlock(&inode_lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__insert_inode_hash);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __remove_inode_hash - remove an inode from the hash
|
||||||
|
* @inode: inode to unhash
|
||||||
|
*
|
||||||
|
* Remove an inode from the superblock.
|
||||||
|
*/
|
||||||
|
static void __remove_inode_hash(struct inode *inode)
|
||||||
|
{
|
||||||
|
hlist_del_init(&inode->i_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove_inode_hash - remove an inode from the hash
|
||||||
|
* @inode: inode to unhash
|
||||||
|
*
|
||||||
|
* Remove an inode from the superblock.
|
||||||
|
*/
|
||||||
|
void remove_inode_hash(struct inode *inode)
|
||||||
|
{
|
||||||
|
spin_lock(&inode_lock);
|
||||||
|
hlist_del_init(&inode->i_hash);
|
||||||
|
spin_unlock(&inode_lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(remove_inode_hash);
|
||||||
|
|
||||||
void end_writeback(struct inode *inode)
|
void end_writeback(struct inode *inode)
|
||||||
{
|
{
|
||||||
might_sleep();
|
might_sleep();
|
||||||
@@ -383,7 +435,7 @@ static void dispose_list(struct list_head *head)
|
|||||||
evict(inode);
|
evict(inode);
|
||||||
|
|
||||||
spin_lock(&inode_lock);
|
spin_lock(&inode_lock);
|
||||||
hlist_del_init(&inode->i_hash);
|
__remove_inode_hash(inode);
|
||||||
list_del_init(&inode->i_sb_list);
|
list_del_init(&inode->i_sb_list);
|
||||||
spin_unlock(&inode_lock);
|
spin_unlock(&inode_lock);
|
||||||
|
|
||||||
@@ -634,16 +686,6 @@ repeat:
|
|||||||
return node ? inode : NULL;
|
return node ? inode : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long hash(struct super_block *sb, unsigned long hashval)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
|
|
||||||
tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) /
|
|
||||||
L1_CACHE_BYTES;
|
|
||||||
tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS);
|
|
||||||
return tmp & I_HASHMASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
__inode_add_to_lists(struct super_block *sb, struct hlist_head *head,
|
__inode_add_to_lists(struct super_block *sb, struct hlist_head *head,
|
||||||
struct inode *inode)
|
struct inode *inode)
|
||||||
@@ -1194,36 +1236,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(insert_inode_locked4);
|
EXPORT_SYMBOL(insert_inode_locked4);
|
||||||
|
|
||||||
/**
|
|
||||||
* __insert_inode_hash - hash an inode
|
|
||||||
* @inode: unhashed inode
|
|
||||||
* @hashval: unsigned long value used to locate this object in the
|
|
||||||
* inode_hashtable.
|
|
||||||
*
|
|
||||||
* Add an inode to the inode hash for this superblock.
|
|
||||||
*/
|
|
||||||
void __insert_inode_hash(struct inode *inode, unsigned long hashval)
|
|
||||||
{
|
|
||||||
struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval);
|
|
||||||
spin_lock(&inode_lock);
|
|
||||||
hlist_add_head(&inode->i_hash, head);
|
|
||||||
spin_unlock(&inode_lock);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(__insert_inode_hash);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* remove_inode_hash - remove an inode from the hash
|
|
||||||
* @inode: inode to unhash
|
|
||||||
*
|
|
||||||
* Remove an inode from the superblock.
|
|
||||||
*/
|
|
||||||
void remove_inode_hash(struct inode *inode)
|
|
||||||
{
|
|
||||||
spin_lock(&inode_lock);
|
|
||||||
hlist_del_init(&inode->i_hash);
|
|
||||||
spin_unlock(&inode_lock);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(remove_inode_hash);
|
|
||||||
|
|
||||||
int generic_delete_inode(struct inode *inode)
|
int generic_delete_inode(struct inode *inode)
|
||||||
{
|
{
|
||||||
@@ -1279,7 +1291,7 @@ static void iput_final(struct inode *inode)
|
|||||||
spin_lock(&inode_lock);
|
spin_lock(&inode_lock);
|
||||||
WARN_ON(inode->i_state & I_NEW);
|
WARN_ON(inode->i_state & I_NEW);
|
||||||
inode->i_state &= ~I_WILL_FREE;
|
inode->i_state &= ~I_WILL_FREE;
|
||||||
hlist_del_init(&inode->i_hash);
|
__remove_inode_hash(inode);
|
||||||
}
|
}
|
||||||
WARN_ON(inode->i_state & I_NEW);
|
WARN_ON(inode->i_state & I_NEW);
|
||||||
inode->i_state |= I_FREEING;
|
inode->i_state |= I_FREEING;
|
||||||
@@ -1294,9 +1306,7 @@ static void iput_final(struct inode *inode)
|
|||||||
list_del_init(&inode->i_sb_list);
|
list_del_init(&inode->i_sb_list);
|
||||||
spin_unlock(&inode_lock);
|
spin_unlock(&inode_lock);
|
||||||
evict(inode);
|
evict(inode);
|
||||||
spin_lock(&inode_lock);
|
remove_inode_hash(inode);
|
||||||
hlist_del_init(&inode->i_hash);
|
|
||||||
spin_unlock(&inode_lock);
|
|
||||||
wake_up_inode(inode);
|
wake_up_inode(inode);
|
||||||
BUG_ON(inode->i_state != (I_FREEING | I_CLEAR));
|
BUG_ON(inode->i_state != (I_FREEING | I_CLEAR));
|
||||||
destroy_inode(inode);
|
destroy_inode(inode);
|
||||||
|
Reference in New Issue
Block a user