Use the newly introduced file_operation callback for FITRIM ioctl. This removes some common code, eg. permission check, buffer copying, which is now done by generic vfs code. --- fs/btrfs/ctree.h | 1 + fs/btrfs/inode.c | 1 + fs/btrfs/ioctl.c | 26 +++++++------------------- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 9fb76829a281..0361d95fe690 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3206,6 +3206,7 @@ void btrfs_update_inode_bytes(struct btrfs_inode *inode, /* ioctl.c */ long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +long btrfs_ioctl_fitrim(struct file *file, struct fstrim_range *range); long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); int btrfs_fileattr_get(struct dentry *dentry, struct fileattr *fa); int btrfs_fileattr_set(struct user_namespace *mnt_userns, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 46f392943f4d..5f0d1032c890 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10640,6 +10640,7 @@ static const struct file_operations btrfs_dir_file_operations = { #endif .release = btrfs_release_file, .fsync = btrfs_sync_file, + .fitrim = btrfs_ioctl_fitrim, }; /* diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 5dc2fd843ae3..38b1de381836 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -372,19 +372,16 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg) return put_user(inode->i_generation, arg); } -static noinline int btrfs_ioctl_fitrim(struct btrfs_fs_info *fs_info, - void __user *arg) +long btrfs_ioctl_fitrim(struct file *file, struct fstrim_range *range) { + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_device *device; struct request_queue *q; - struct fstrim_range range; u64 minlen = ULLONG_MAX; u64 num_devices = 0; int ret; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - /* * btrfs_trim_block_group() depends on space cache, which is not * available in zoned filesystem. So, disallow fitrim on a zoned @@ -419,26 +416,19 @@ static noinline int btrfs_ioctl_fitrim(struct btrfs_fs_info *fs_info, if (!num_devices) return -EOPNOTSUPP; - if (copy_from_user(&range, arg, sizeof(range))) - return -EFAULT; /* * NOTE: Don't truncate the range using super->total_bytes. Bytenr of * block group is in the logical address space, which can be any * sectorsize aligned bytenr in the range [0, U64_MAX]. */ - if (range.len < fs_info->sb->s_blocksize) + if (range->len < fs_info->sb->s_blocksize) return -EINVAL; - range.minlen = max(range.minlen, minlen); - ret = btrfs_trim_fs(fs_info, &range); - if (ret < 0) - return ret; - - if (copy_to_user(arg, &range, sizeof(range))) - return -EFAULT; + range->minlen = max(range->minlen, minlen); + ret = btrfs_trim_fs(fs_info, range); - return 0; + return ret; } int __pure btrfs_is_empty_uuid(u8 *uuid) @@ -4796,8 +4786,6 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_get_fslabel(fs_info, argp); case FS_IOC_SETFSLABEL: return btrfs_ioctl_set_fslabel(file, argp); - case FITRIM: - return btrfs_ioctl_fitrim(fs_info, argp); case BTRFS_IOC_SNAP_CREATE: return btrfs_ioctl_snap_create(file, argp, 0); case BTRFS_IOC_SNAP_CREATE_V2: -- 2.20.1