btrfs: factor out common part of btrfs_{mknod,create,mkdir}()
authorOmar Sandoval <osandov@fb.com>
Tue, 15 Mar 2022 01:12:33 +0000 (18:12 -0700)
committerDavid Sterba <dsterba@suse.com>
Mon, 16 May 2022 15:03:08 +0000 (17:03 +0200)
btrfs_{mknod,create,mkdir}() are now identical other than the inode
initialization and some inconsequential function call order differences.
Factor out the common code to reduce code duplication.

Reviewed-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index db79315..ad446bb 100644 (file)
@@ -6326,23 +6326,15 @@ fail_dir_item:
        return ret;
 }
 
-static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
-                      struct dentry *dentry, umode_t mode, dev_t rdev)
+static int btrfs_create_common(struct inode *dir, struct dentry *dentry,
+                              struct inode *inode)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
-       struct btrfs_trans_handle *trans;
        struct btrfs_root *root = BTRFS_I(dir)->root;
-       struct inode *inode;
+       struct btrfs_trans_handle *trans;
        int err;
        u64 index = 0;
 
-       inode = new_inode(dir->i_sb);
-       if (!inode)
-               return -ENOMEM;
-       inode_init_owner(mnt_userns, inode, dir, mode);
-       inode->i_op = &btrfs_special_inode_operations;
-       init_special_inode(inode, inode->i_mode, rdev);
-
        /*
         * 2 for inode item and ref
         * 2 for dir items
@@ -6366,33 +6358,45 @@ static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
        if (err)
                goto out_unlock;
 
+       err = btrfs_update_inode(trans, root, BTRFS_I(inode));
+       if (err)
+               goto out_unlock;
+
        err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode),
                             dentry->d_name.name, dentry->d_name.len, 0, index);
        if (err)
                goto out_unlock;
 
-       btrfs_update_inode(trans, root, BTRFS_I(inode));
        d_instantiate_new(dentry, inode);
 
 out_unlock:
        btrfs_end_transaction(trans);
-       btrfs_btree_balance_dirty(fs_info);
        if (err && inode) {
                inode_dec_link_count(inode);
                discard_new_inode(inode);
        }
+       btrfs_btree_balance_dirty(fs_info);
        return err;
 }
 
+static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+                      struct dentry *dentry, umode_t mode, dev_t rdev)
+{
+       struct inode *inode;
+
+       inode = new_inode(dir->i_sb);
+       if (!inode)
+               return -ENOMEM;
+       inode_init_owner(mnt_userns, inode, dir, mode);
+       inode->i_op = &btrfs_special_inode_operations;
+       init_special_inode(inode, inode->i_mode, rdev);
+       return btrfs_create_common(dir, dentry, inode);
+}
+
 static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir,
                        struct dentry *dentry, umode_t mode, bool excl)
 {
-       struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
-       struct btrfs_trans_handle *trans;
-       struct btrfs_root *root = BTRFS_I(dir)->root;
        struct inode *inode;
-       int err;
-       u64 index = 0;
 
        inode = new_inode(dir->i_sb);
        if (!inode)
@@ -6401,49 +6405,7 @@ static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir,
        inode->i_fop = &btrfs_file_operations;
        inode->i_op = &btrfs_file_inode_operations;
        inode->i_mapping->a_ops = &btrfs_aops;
-
-       /*
-        * 2 for inode item and ref
-        * 2 for dir items
-        * 1 for xattr if selinux is on
-        */
-       trans = btrfs_start_transaction(root, 5);
-       if (IS_ERR(trans)) {
-               iput(inode);
-               return PTR_ERR(trans);
-       }
-
-       err = btrfs_new_inode(trans, root, inode, dir, dentry->d_name.name,
-                             dentry->d_name.len, &index);
-       if (err) {
-               iput(inode);
-               inode = NULL;
-               goto out_unlock;
-       }
-
-       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
-       if (err)
-               goto out_unlock;
-
-       err = btrfs_update_inode(trans, root, BTRFS_I(inode));
-       if (err)
-               goto out_unlock;
-
-       err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode),
-                            dentry->d_name.name, dentry->d_name.len, 0, index);
-       if (err)
-               goto out_unlock;
-
-       d_instantiate_new(dentry, inode);
-
-out_unlock:
-       btrfs_end_transaction(trans);
-       if (err && inode) {
-               inode_dec_link_count(inode);
-               discard_new_inode(inode);
-       }
-       btrfs_btree_balance_dirty(fs_info);
-       return err;
+       return btrfs_create_common(dir, dentry, inode);
 }
 
 static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
@@ -6527,12 +6489,7 @@ fail:
 static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
                       struct dentry *dentry, umode_t mode)
 {
-       struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
        struct inode *inode;
-       struct btrfs_trans_handle *trans;
-       struct btrfs_root *root = BTRFS_I(dir)->root;
-       int err;
-       u64 index = 0;
 
        inode = new_inode(dir->i_sb);
        if (!inode)
@@ -6540,50 +6497,7 @@ static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
        inode_init_owner(mnt_userns, inode, dir, S_IFDIR | mode);
        inode->i_op = &btrfs_dir_inode_operations;
        inode->i_fop = &btrfs_dir_file_operations;
-
-       /*
-        * 2 items for inode and ref
-        * 2 items for dir items
-        * 1 for xattr if selinux is on
-        */
-       trans = btrfs_start_transaction(root, 5);
-       if (IS_ERR(trans)) {
-               iput(inode);
-               return PTR_ERR(trans);
-       }
-
-       err = btrfs_new_inode(trans, root, inode, dir, dentry->d_name.name,
-                             dentry->d_name.len, &index);
-       if (err) {
-               iput(inode);
-               inode = NULL;
-               goto out_fail;
-       }
-
-       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
-       if (err)
-               goto out_fail;
-
-       err = btrfs_update_inode(trans, root, BTRFS_I(inode));
-       if (err)
-               goto out_fail;
-
-       err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode),
-                       dentry->d_name.name,
-                       dentry->d_name.len, 0, index);
-       if (err)
-               goto out_fail;
-
-       d_instantiate_new(dentry, inode);
-
-out_fail:
-       btrfs_end_transaction(trans);
-       if (err && inode) {
-               inode_dec_link_count(inode);
-               discard_new_inode(inode);
-       }
-       btrfs_btree_balance_dirty(fs_info);
-       return err;
+       return btrfs_create_common(dir, dentry, inode);
 }
 
 static noinline int uncompress_inline(struct btrfs_path *path,