diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-11-05 14:11:11 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2020-12-07 11:50:45 -0500 |
commit | 3edaf23c570d6c6cec459e0f6a40cdb590f3365d (patch) | |
tree | 24f7d1783b28d1c415a572148358c479c1816dd1 | |
parent | e50d674107bab424d1cc964cb116abcd9fbf79a3 (diff) |
fs: move inode init from new_inode_pseudo to inode_init_always
- there's no reason to be taking i_lock to set i_state here, the inode
isn't visible to anything else yet
- we need i_sb_list to be always initialized for the next patch that
kills I_CREATING.
And, while we're at it, delete new_inode_pseudo then rename alloc_inode
to new_inode_pseudo.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/inode.c | 59 |
1 files changed, 24 insertions, 35 deletions
diff --git a/fs/inode.c b/fs/inode.c index 845d831168d0..818296c50f80 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -135,6 +135,8 @@ int inode_init_always(struct super_block *sb, struct inode *inode) static const struct file_operations no_open_fops = {.open = no_open}; struct address_space *const mapping = &inode->i_data; + inode->i_state = 0; + INIT_LIST_HEAD(&inode->i_sb_list); inode->i_sb = sb; inode->i_blkbits = sb->s_blocksize_bits; inode->i_flags = 0; @@ -223,33 +225,6 @@ static void i_callback(struct rcu_head *head) free_inode_nonrcu(inode); } -static struct inode *alloc_inode(struct super_block *sb) -{ - const struct super_operations *ops = sb->s_op; - struct inode *inode; - - if (ops->alloc_inode) - inode = ops->alloc_inode(sb); - else - inode = kmem_cache_alloc(inode_cachep, GFP_KERNEL); - - if (!inode) - return NULL; - - if (unlikely(inode_init_always(sb, inode))) { - if (ops->destroy_inode) { - ops->destroy_inode(inode); - if (!ops->free_inode) - return NULL; - } - inode->free_inode = ops->free_inode; - i_callback(&inode->i_rcu); - return NULL; - } - - return inode; -} - void __destroy_inode(struct inode *inode) { BUG_ON(inode_has_buffers(inode)); @@ -925,14 +900,28 @@ EXPORT_SYMBOL(get_next_ino); */ struct inode *new_inode_pseudo(struct super_block *sb) { - struct inode *inode = alloc_inode(sb); + const struct super_operations *ops = sb->s_op; + struct inode *inode; - if (inode) { - spin_lock(&inode->i_lock); - inode->i_state = 0; - spin_unlock(&inode->i_lock); - INIT_LIST_HEAD(&inode->i_sb_list); + if (ops->alloc_inode) + inode = ops->alloc_inode(sb); + else + inode = kmem_cache_alloc(inode_cachep, GFP_KERNEL); + + if (!inode) + return NULL; + + if (unlikely(inode_init_always(sb, inode))) { + if (ops->destroy_inode) { + ops->destroy_inode(inode); + if (!ops->free_inode) + return NULL; + } + inode->free_inode = ops->free_inode; + i_callback(&inode->i_rcu); + return NULL; } + return inode; } @@ -1145,7 +1134,7 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval, struct inode *inode = ilookup5(sb, hashval, test, data); if (!inode) { - struct inode *new = alloc_inode(sb); + struct inode *new = new_inode_pseudo(sb); if (new) { new->i_state = 0; @@ -1190,7 +1179,7 @@ again: return inode; } - inode = alloc_inode(sb); + inode = new_inode_pseudo(sb); if (inode) { struct inode *old; |