Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c51acbc authored by Dave Chinner's avatar Dave Chinner Committed by Al Viro
Browse files

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: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 9e38d86f
Loading
Loading
Loading
Loading
+55 −45
Original line number Diff line number Diff line
@@ -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 @@ static struct inode *find_inode_fast(struct super_block *sb,
	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);