diff options
author | Omar Sandoval <osandov@fb.com> | 2022-03-15 04:12:32 +0300 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2022-05-16 18:03:08 +0300 |
commit | a1fd0c35ffe349a7bbca27dae362932895ee8c4d (patch) | |
tree | d34501f25dd57b749816ee121a018b260f00ee58 /fs/btrfs/ioctl.c | |
parent | b95b78e628d56c6d3d7912e264d9745777b2d800 (diff) | |
download | linux-a1fd0c35ffe349a7bbca27dae362932895ee8c4d.tar.xz |
btrfs: allocate inode outside of btrfs_new_inode()
Instead of calling new_inode() and inode_init_owner() inside of
btrfs_new_inode(), do it in the callers. This allows us to pass in just
the inode instead of the mnt_userns and mode and removes the need for
memalloc_nofs_{save,restores}() since we do it before starting a
transaction. In create_subvol(), it also means we no longer have to look
up the inode again to instantiate it. This also paves the way for some
more cleanups in later patches.
This also removes the comments about Smack checking i_op, which are no
longer true since commit 5d6c31910bc0 ("xattr: Add
__vfs_{get,set,remove}xattr helpers"). Now it checks inode->i_opflags &
IOP_XATTR, which is set based on sb->s_xattr.
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4a015579a46e..4b903517fdc3 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -587,6 +587,12 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, if (ret < 0) goto out_root_item; + inode = btrfs_new_subvol_inode(mnt_userns, dir); + if (!inode) { + ret = -ENOMEM; + goto out_anon_dev; + } + btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP); /* * The same as the snapshot creation, please see the comment @@ -594,13 +600,13 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, */ ret = btrfs_subvolume_reserve_metadata(root, &block_rsv, 8, false); if (ret) - goto out_anon_dev; + goto out_inode; trans = btrfs_start_transaction(root, 0); if (IS_ERR(trans)) { ret = PTR_ERR(trans); btrfs_subvolume_release_metadata(root, &block_rsv); - goto out_anon_dev; + goto out_inode; } trans->block_rsv = &block_rsv; trans->bytes_reserved = block_rsv.size; @@ -683,16 +689,16 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, } /* anon_dev is owned by new_root now. */ anon_dev = 0; + BTRFS_I(inode)->root = new_root; + /* ... and new_root is owned by inode now. */ ret = btrfs_record_root_in_trans(trans, new_root); if (ret) { - btrfs_put_root(new_root); btrfs_abort_transaction(trans, ret); goto out; } - ret = btrfs_create_subvol_root(trans, new_root, root, mnt_userns); - btrfs_put_root(new_root); + ret = btrfs_create_subvol_root(trans, root, inode); if (ret) { /* We potentially lose an unused inode item here */ btrfs_abort_transaction(trans, ret); @@ -745,11 +751,11 @@ out: ret = btrfs_commit_transaction(trans); if (!ret) { - inode = btrfs_lookup_dentry(dir, dentry); - if (IS_ERR(inode)) - return PTR_ERR(inode); d_instantiate(dentry, inode); + inode = NULL; } +out_inode: + iput(inode); out_anon_dev: if (anon_dev) free_anon_bdev(anon_dev); |