mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
fs: change test in inode_insert5 for adding to the sb list
inode_insert5 currently looks at I_CREATING to decide whether to insert the inode into the sb list. This test is a bit ambiguous, as I_CREATING state is not directly related to that list. This test is also problematic for some upcoming ceph changes to add fscrypt support. We need to be able to allocate an inode using new_inode and insert it into the hash later iff we end up using it, and doing that now means that we double add it and corrupt the list. What we really want to know in this test is whether the inode is already in its superblock list, and then add it if it isn't. Have it test for list_empty instead and ensure that we always initialize the list by doing it in inode_init_once. It's only ever removed from the list with list_del_init, so that should be sufficient. Suggested-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
3d7cb6b04c
commit
18cc912b8a
10
fs/inode.c
10
fs/inode.c
@ -422,6 +422,7 @@ void inode_init_once(struct inode *inode)
|
||||
INIT_LIST_HEAD(&inode->i_io_list);
|
||||
INIT_LIST_HEAD(&inode->i_wb_list);
|
||||
INIT_LIST_HEAD(&inode->i_lru);
|
||||
INIT_LIST_HEAD(&inode->i_sb_list);
|
||||
__address_space_init_once(&inode->i_data);
|
||||
i_size_ordered_init(inode);
|
||||
}
|
||||
@ -1021,7 +1022,6 @@ struct inode *new_inode_pseudo(struct super_block *sb)
|
||||
spin_lock(&inode->i_lock);
|
||||
inode->i_state = 0;
|
||||
spin_unlock(&inode->i_lock);
|
||||
INIT_LIST_HEAD(&inode->i_sb_list);
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
@ -1165,7 +1165,6 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval,
|
||||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval);
|
||||
struct inode *old;
|
||||
bool creating = inode->i_state & I_CREATING;
|
||||
|
||||
again:
|
||||
spin_lock(&inode_hash_lock);
|
||||
@ -1199,7 +1198,12 @@ again:
|
||||
inode->i_state |= I_NEW;
|
||||
hlist_add_head_rcu(&inode->i_hash, head);
|
||||
spin_unlock(&inode->i_lock);
|
||||
if (!creating)
|
||||
|
||||
/*
|
||||
* Add inode to the sb list if it's not already. It has I_NEW at this
|
||||
* point, so it should be safe to test i_sb_list locklessly.
|
||||
*/
|
||||
if (list_empty(&inode->i_sb_list))
|
||||
inode_sb_list_add(inode);
|
||||
unlock:
|
||||
spin_unlock(&inode_hash_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user