summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-11-05 14:11:11 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2020-12-07 11:50:45 -0500
commit3edaf23c570d6c6cec459e0f6a40cdb590f3365d (patch)
tree24f7d1783b28d1c415a572148358c479c1816dd1
parente50d674107bab424d1cc964cb116abcd9fbf79a3 (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.c59
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;