Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jeff Layton and committed by
Ilya Dryomov
18cc912b 3d7cb6b0

+7 -3
+7 -3
fs/inode.c
··· 422 422 INIT_LIST_HEAD(&inode->i_io_list); 423 423 INIT_LIST_HEAD(&inode->i_wb_list); 424 424 INIT_LIST_HEAD(&inode->i_lru); 425 + INIT_LIST_HEAD(&inode->i_sb_list); 425 426 __address_space_init_once(&inode->i_data); 426 427 i_size_ordered_init(inode); 427 428 } ··· 1022 1021 spin_lock(&inode->i_lock); 1023 1022 inode->i_state = 0; 1024 1023 spin_unlock(&inode->i_lock); 1025 - INIT_LIST_HEAD(&inode->i_sb_list); 1026 1024 } 1027 1025 return inode; 1028 1026 } ··· 1165 1165 { 1166 1166 struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval); 1167 1167 struct inode *old; 1168 - bool creating = inode->i_state & I_CREATING; 1169 1168 1170 1169 again: 1171 1170 spin_lock(&inode_hash_lock); ··· 1198 1199 inode->i_state |= I_NEW; 1199 1200 hlist_add_head_rcu(&inode->i_hash, head); 1200 1201 spin_unlock(&inode->i_lock); 1201 - if (!creating) 1202 + 1203 + /* 1204 + * Add inode to the sb list if it's not already. It has I_NEW at this 1205 + * point, so it should be safe to test i_sb_list locklessly. 1206 + */ 1207 + if (list_empty(&inode->i_sb_list)) 1202 1208 inode_sb_list_add(inode); 1203 1209 unlock: 1204 1210 spin_unlock(&inode_hash_lock);