Commit 5f465bf1 authored by Omar Sandoval's avatar Omar Sandoval Committed by David Sterba
Browse files

btrfs: factor out common part of btrfs_{mknod,create,mkdir}()



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: default avatarSweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent a1fd0c35
Loading
Loading
Loading
Loading
+24 −110
Original line number Diff line number Diff line
@@ -6326,23 +6326,15 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
	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 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
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,