Commit 6fa425a2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-5.2-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fix from David Sterba:
 "One regression fix to TRIM ioctl.

  The range cannot be used as its meaning can be confusing regarding
  physical and logical addresses. This confusion in code led to
  potential corruptions when the range overlapped data.

  The original patch made it to several stable kernels and was promptly
  reverted, the version for master branch is different due to additional
  changes but the change is effectively the same"

* tag 'for-5.2-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: Always trim all unallocated space in btrfs_trim_free_extents
parents 01ccc3ad 8103d10b
...@@ -11137,13 +11137,11 @@ int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, ...@@ -11137,13 +11137,11 @@ int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info,
* it while performing the free space search since we have already * it while performing the free space search since we have already
* held back allocations. * held back allocations.
*/ */
static int btrfs_trim_free_extents(struct btrfs_device *device, static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
struct fstrim_range *range, u64 *trimmed)
{ {
u64 start, len = 0, end = 0; u64 start = SZ_1M, len = 0, end = 0;
int ret; int ret;
start = max_t(u64, range->start, SZ_1M);
*trimmed = 0; *trimmed = 0;
/* Discard not supported = nothing to do. */ /* Discard not supported = nothing to do. */
...@@ -11186,22 +11184,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, ...@@ -11186,22 +11184,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
break; break;
} }
/* Keep going until we satisfy minlen or reach end of space */
if (len < range->minlen) {
mutex_unlock(&fs_info->chunk_mutex);
start += len;
continue;
}
/* If we are out of the passed range break */
if (start > range->start + range->len - 1) {
mutex_unlock(&fs_info->chunk_mutex);
break;
}
start = max(range->start, start);
len = min(range->len, len);
ret = btrfs_issue_discard(device->bdev, start, len, ret = btrfs_issue_discard(device->bdev, start, len,
&bytes); &bytes);
if (!ret) if (!ret)
...@@ -11216,10 +11198,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, ...@@ -11216,10 +11198,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
start += len; start += len;
*trimmed += bytes; *trimmed += bytes;
/* We've trimmed enough */
if (*trimmed >= range->len)
break;
if (fatal_signal_pending(current)) { if (fatal_signal_pending(current)) {
ret = -ERESTARTSYS; ret = -ERESTARTSYS;
break; break;
...@@ -11303,7 +11281,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) ...@@ -11303,7 +11281,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
mutex_lock(&fs_info->fs_devices->device_list_mutex); mutex_lock(&fs_info->fs_devices->device_list_mutex);
devices = &fs_info->fs_devices->devices; devices = &fs_info->fs_devices->devices;
list_for_each_entry(device, devices, dev_list) { list_for_each_entry(device, devices, dev_list) {
ret = btrfs_trim_free_extents(device, range, &group_trimmed); ret = btrfs_trim_free_extents(device, &group_trimmed);
if (ret) { if (ret) {
dev_failed++; dev_failed++;
dev_ret = ret; dev_ret = ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment