diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index d524b6697ad9..136a2f980e21 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -282,6 +282,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
282 | struct fstrim_range range; | 282 | struct fstrim_range range; |
283 | u64 minlen = ULLONG_MAX; | 283 | u64 minlen = ULLONG_MAX; |
284 | u64 num_devices = 0; | 284 | u64 num_devices = 0; |
285 | u64 total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); | ||
285 | int ret; | 286 | int ret; |
286 | 287 | ||
287 | if (!capable(CAP_SYS_ADMIN)) | 288 | if (!capable(CAP_SYS_ADMIN)) |
@@ -300,12 +301,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
300 | } | 301 | } |
301 | } | 302 | } |
302 | rcu_read_unlock(); | 303 | rcu_read_unlock(); |
304 | |||
303 | if (!num_devices) | 305 | if (!num_devices) |
304 | return -EOPNOTSUPP; | 306 | return -EOPNOTSUPP; |
305 | |||
306 | if (copy_from_user(&range, arg, sizeof(range))) | 307 | if (copy_from_user(&range, arg, sizeof(range))) |
307 | return -EFAULT; | 308 | return -EFAULT; |
309 | if (range.start > total_bytes) | ||
310 | return -EINVAL; | ||
308 | 311 | ||
312 | range.len = min(range.len, total_bytes - range.start); | ||
309 | range.minlen = max(range.minlen, minlen); | 313 | range.minlen = max(range.minlen, minlen); |
310 | ret = btrfs_trim_fs(root, &range); | 314 | ret = btrfs_trim_fs(root, &range); |
311 | if (ret < 0) | 315 | if (ret < 0) |