Commit 93d91ef8 authored by David Sterba's avatar David Sterba Committed by Greg Kroah-Hartman

Revert "btrfs: Honour FITRIM range constraints during free space trim"

This reverts commit eb432217.

There is currently no corresponding patch in master due to additional
changes that would be significantly different from plain revert in the
respective stable branch.

The range argument was not handled correctly and could cause trim to
overlap allocated areas or reach beyond the end of the device. The
address space that fitrim normally operates on is in logical
coordinates, while the discards are done on the physical device extents.
This distinction cannot be made with the current ioctl interface and
caused the confusion.

The bug depends on the layout of block groups and does not always
happen. The whole-fs trim (run by default by the fstrim tool) is not
affected.
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent dc9ddd15
...@@ -11314,9 +11314,9 @@ int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, ...@@ -11314,9 +11314,9 @@ int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info,
* 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,
struct fstrim_range *range, u64 *trimmed) u64 minlen, u64 *trimmed)
{ {
u64 start = range->start, len = 0; u64 start = 0, len = 0;
int ret; int ret;
*trimmed = 0; *trimmed = 0;
...@@ -11359,8 +11359,8 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, ...@@ -11359,8 +11359,8 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
if (!trans) if (!trans)
up_read(&fs_info->commit_root_sem); up_read(&fs_info->commit_root_sem);
ret = find_free_dev_extent_start(trans, device, range->minlen, ret = find_free_dev_extent_start(trans, device, minlen, start,
start, &start, &len); &start, &len);
if (trans) { if (trans) {
up_read(&fs_info->commit_root_sem); up_read(&fs_info->commit_root_sem);
btrfs_put_transaction(trans); btrfs_put_transaction(trans);
...@@ -11373,16 +11373,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, ...@@ -11373,16 +11373,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
break; break;
} }
/* If we are out of the passed range break */
if (start > range->start + range->len - 1) {
mutex_unlock(&fs_info->chunk_mutex);
ret = 0;
break;
}
start = max(range->start, start);
len = min(range->len, len);
ret = btrfs_issue_discard(device->bdev, start, len, &bytes); ret = btrfs_issue_discard(device->bdev, start, len, &bytes);
mutex_unlock(&fs_info->chunk_mutex); mutex_unlock(&fs_info->chunk_mutex);
...@@ -11392,10 +11382,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, ...@@ -11392,10 +11382,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;
...@@ -11479,7 +11465,8 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) ...@@ -11479,7 +11465,8 @@ 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, range->minlen,
&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