--- fs/ext4/ext4.h | 1 + fs/ext4/file.c | 1 + fs/ext4/ioctl.c | 60 ++++++++++++++++++++----------------------------- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 37002663d521..2770f8f5da95 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1272,6 +1272,7 @@ struct ext4_inode_info { #define ext4_find_next_bit find_next_bit_le extern void ext4_set_bits(void *bm, int cur, int len); +extern long ext4_fitrim(struct file *filp, struct fstrim_range *range); /* * Maximal mount counts between two filesystem checks diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 816dedcbd541..07bf5a0d10f2 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -927,6 +927,7 @@ const struct file_operations ext4_file_operations = { .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, .fallocate = ext4_fallocate, + .fitrim = ext4_fitrim, }; const struct inode_operations ext4_file_inode_operations = { diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 31627f7dc5cd..138e6128cb0c 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -800,6 +800,30 @@ static int ext4_ioctl_get_es_cache(struct file *filp, unsigned long arg) return error; } +long ext4_fitrim(struct file *filp, struct fstrim_range *range) +{ + struct request_queue *q = bdev_get_queue(sb->s_bdev); + int ret = 0; + + if (!blk_queue_discard(q)) + return -EOPNOTSUPP; + + /* + * We haven't replayed the journal, so we cannot use our + * block-bitmap-guided storage zapping commands. + */ + if (test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) + return -EROFS; + + range->minlen = max((unsigned int)range->minlen, + q->limits.discard_granularity); + ret = ext4_trim_fs(sb, range); + if (ret < 0) + return ret; + + return 0; +} + static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(filp); @@ -1044,41 +1068,6 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return err; } - case FITRIM: - { - struct request_queue *q = bdev_get_queue(sb->s_bdev); - struct fstrim_range range; - int ret = 0; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (!blk_queue_discard(q)) - return -EOPNOTSUPP; - - /* - * We haven't replayed the journal, so we cannot use our - * block-bitmap-guided storage zapping commands. - */ - if (test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) - return -EROFS; - - if (copy_from_user(&range, (struct fstrim_range __user *)arg, - sizeof(range))) - return -EFAULT; - - range.minlen = max((unsigned int)range.minlen, - q->limits.discard_granularity); - ret = ext4_trim_fs(sb, &range); - if (ret < 0) - return ret; - - if (copy_to_user((struct fstrim_range __user *)arg, &range, - sizeof(range))) - return -EFAULT; - - return 0; - } case EXT4_IOC_PRECACHE_EXTENTS: return ext4_ext_precache(inode); @@ -1272,7 +1261,6 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } case EXT4_IOC_MOVE_EXT: case EXT4_IOC_RESIZE_FS: - case FITRIM: case EXT4_IOC_PRECACHE_EXTENTS: case FS_IOC_SET_ENCRYPTION_POLICY: case FS_IOC_GET_ENCRYPTION_PWSALT: -- 2.20.1