diff options
author | Anand Jain <anand.jain@oracle.com> | 2019-04-20 19:48:53 +0800 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2019-04-29 19:02:53 +0200 |
commit | ff9fef559babe4376dd698ceec3d73d0362e48a0 (patch) | |
tree | 15913c623084cb9ceb1e7daf4a4dab9651752d92 /fs/btrfs | |
parent | cd31af158b324e5a1f03b53fb46a1e10cde238ab (diff) | |
download | linux-stable-ff9fef559babe4376dd698ceec3d73d0362e48a0.tar.gz linux-stable-ff9fef559babe4376dd698ceec3d73d0362e48a0.tar.bz2 linux-stable-ff9fef559babe4376dd698ceec3d73d0362e48a0.zip |
btrfs: start transaction in btrfs_ioctl_setflags()
Inode attribute can be set through the FS_IOC_SETFLAGS ioctl. This
flags also includes compression attribute for which we would set/reset
the compression extended attribute. While doing this there is a bit of
duplicate code, the following things happens twice:
- start/end_transaction
- inode_inc_iversion()
- current_time update to inode->i_ctime
- and btrfs_update_inode()
These are updated both at btrfs_ioctl_setflags() and btrfs_set_props()
as well. This patch merges these two duplicate codes at
btrfs_ioctl_setflags().
Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/ioctl.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3f9263ddeff8..87b473dcdd52 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -192,6 +192,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) u64 old_flags; unsigned int old_i_flags; umode_t mode; + const char *comp = NULL; if (!inode_owner_or_capable(inode)) return -EPERM; @@ -283,14 +284,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) if (fsflags & FS_NOCOMP_FL) { binode->flags &= ~BTRFS_INODE_COMPRESS; binode->flags |= BTRFS_INODE_NOCOMPRESS; - - /* set no-compression no need to validate prop here */ - ret = btrfs_set_prop_trans(inode, "btrfs.compression", NULL, - 0, 0); - if (ret && ret != -ENODATA) - goto out_drop; } else if (fsflags & FS_COMPR_FL) { - const char *comp; if (IS_SWAPFILE(inode)) { ret = -ETXTBSY; @@ -300,36 +294,47 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) binode->flags |= BTRFS_INODE_COMPRESS; binode->flags &= ~BTRFS_INODE_NOCOMPRESS; - /* compress_type is already validated during mount options */ comp = btrfs_compress_type2str(fs_info->compress_type); if (!comp || comp[0] == 0) comp = btrfs_compress_type2str(BTRFS_COMPRESS_ZLIB); - - ret = btrfs_set_prop_trans(inode, "btrfs.compression", comp, - strlen(comp), 0); - if (ret) - goto out_drop; - } else { - /* reset prop, no need of validate prop here */ - ret = btrfs_set_prop_trans(inode, "btrfs.compression", NULL, - 0, 0); - if (ret && ret != -ENODATA) - goto out_drop; binode->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS); } - trans = btrfs_start_transaction(root, 1); + /* + * 1 for inode item + * 2 for properties + */ + trans = btrfs_start_transaction(root, 3); if (IS_ERR(trans)) { ret = PTR_ERR(trans); goto out_drop; } + if (comp) { + ret = btrfs_set_prop(trans, inode, "btrfs.compression", comp, + strlen(comp), 0); + if (ret) { + btrfs_abort_transaction(trans, ret); + goto out_end_trans; + } + set_bit(BTRFS_INODE_COPY_EVERYTHING, + &BTRFS_I(inode)->runtime_flags); + } else { + ret = btrfs_set_prop(trans, inode, "btrfs.compression", NULL, + 0, 0); + if (ret && ret != -ENODATA) { + btrfs_abort_transaction(trans, ret); + goto out_end_trans; + } + } + btrfs_sync_inode_flags_to_i_flags(inode); inode_inc_iversion(inode); inode->i_ctime = current_time(inode); ret = btrfs_update_inode(trans, root, inode); + out_end_trans: btrfs_end_transaction(trans); out_drop: if (ret) { |