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:
parent
9e38d86ff2
commit
4c51acbc66
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)
|
||||
{
|
||||
might_sleep();
|
||||
|
@ -383,7 +435,7 @@ static void dispose_list(struct list_head *head)
|
|||
evict(inode);
|
||||
|
||||
spin_lock(&inode_lock);
|
||||
hlist_del_init(&inode->i_hash);
|
||||
__remove_inode_hash(inode);
|
||||
list_del_init(&inode->i_sb_list);
|
||||
spin_unlock(&inode_lock);
|
||||
|
||||
|
@ -634,16 +686,6 @@ repeat:
|
|||
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
|
||||
__inode_add_to_lists(struct super_block *sb, struct hlist_head *head,
|
||||
struct inode *inode)
|
||||
|
@ -1194,36 +1236,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
|
|||
}
|
||||
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)
|
||||
{
|
||||
|
@ -1279,7 +1291,7 @@ static void iput_final(struct inode *inode)
|
|||
spin_lock(&inode_lock);
|
||||
WARN_ON(inode->i_state & I_NEW);
|
||||
inode->i_state &= ~I_WILL_FREE;
|
||||
hlist_del_init(&inode->i_hash);
|
||||
__remove_inode_hash(inode);
|
||||
}
|
||||
WARN_ON(inode->i_state & I_NEW);
|
||||
inode->i_state |= I_FREEING;
|
||||
|
@ -1294,9 +1306,7 @@ static void iput_final(struct inode *inode)
|
|||
list_del_init(&inode->i_sb_list);
|
||||
spin_unlock(&inode_lock);
|
||||
evict(inode);
|
||||
spin_lock(&inode_lock);
|
||||
hlist_del_init(&inode->i_hash);
|
||||
spin_unlock(&inode_lock);
|
||||
remove_inode_hash(inode);
|
||||
wake_up_inode(inode);
|
||||
BUG_ON(inode->i_state != (I_FREEING | I_CLEAR));
|
||||
destroy_inode(inode);
|
||||
|
|
Loading…
Reference in New Issue