]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/revert-btrfs-honour-fitrim-range-constraints-during-free-space-trim.patch
4.19-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.19 / revert-btrfs-honour-fitrim-range-constraints-during-free-space-trim.patch
1 From dsterba@suse.com Wed May 29 11:30:42 2019
2 From: David Sterba <dsterba@suse.com>
3 Date: Wed, 29 May 2019 19:25:44 +0200
4 Subject: Revert "btrfs: Honour FITRIM range constraints during free space trim"
5 To: stable@vger.kernel.org
6 Cc: David Sterba <dsterba@suse.com>
7 Message-ID: <20190529172547.30563-2-dsterba@suse.com>
8
9 From: David Sterba <dsterba@suse.com>
10
11 This reverts commit 8b13bb911f0c0c77d41e5ddc41ad3c127c356b8a.
12
13 There is currently no corresponding patch in master due to additional
14 changes that would be significantly different from plain revert in the
15 respective stable branch.
16
17 The range argument was not handled correctly and could cause trim to
18 overlap allocated areas or reach beyond the end of the device. The
19 address space that fitrim normally operates on is in logical
20 coordinates, while the discards are done on the physical device extents.
21 This distinction cannot be made with the current ioctl interface and
22 caused the confusion.
23
24 The bug depends on the layout of block groups and does not always
25 happen. The whole-fs trim (run by default by the fstrim tool) is not
26 affected.
27
28 Signed-off-by: David Sterba <dsterba@suse.com>
29 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30 ---
31 fs/btrfs/extent-tree.c | 25 ++++++-------------------
32 1 file changed, 6 insertions(+), 19 deletions(-)
33
34 --- a/fs/btrfs/extent-tree.c
35 +++ b/fs/btrfs/extent-tree.c
36 @@ -10788,9 +10788,9 @@ int btrfs_error_unpin_extent_range(struc
37 * held back allocations.
38 */
39 static int btrfs_trim_free_extents(struct btrfs_device *device,
40 - struct fstrim_range *range, u64 *trimmed)
41 + u64 minlen, u64 *trimmed)
42 {
43 - u64 start = range->start, len = 0;
44 + u64 start = 0, len = 0;
45 int ret;
46
47 *trimmed = 0;
48 @@ -10833,8 +10833,8 @@ static int btrfs_trim_free_extents(struc
49 if (!trans)
50 up_read(&fs_info->commit_root_sem);
51
52 - ret = find_free_dev_extent_start(trans, device, range->minlen,
53 - start, &start, &len);
54 + ret = find_free_dev_extent_start(trans, device, minlen, start,
55 + &start, &len);
56 if (trans) {
57 up_read(&fs_info->commit_root_sem);
58 btrfs_put_transaction(trans);
59 @@ -10847,16 +10847,6 @@ static int btrfs_trim_free_extents(struc
60 break;
61 }
62
63 - /* If we are out of the passed range break */
64 - if (start > range->start + range->len - 1) {
65 - mutex_unlock(&fs_info->chunk_mutex);
66 - ret = 0;
67 - break;
68 - }
69 -
70 - start = max(range->start, start);
71 - len = min(range->len, len);
72 -
73 ret = btrfs_issue_discard(device->bdev, start, len, &bytes);
74 mutex_unlock(&fs_info->chunk_mutex);
75
76 @@ -10866,10 +10856,6 @@ static int btrfs_trim_free_extents(struc
77 start += len;
78 *trimmed += bytes;
79
80 - /* We've trimmed enough */
81 - if (*trimmed >= range->len)
82 - break;
83 -
84 if (fatal_signal_pending(current)) {
85 ret = -ERESTARTSYS;
86 break;
87 @@ -10953,7 +10939,8 @@ int btrfs_trim_fs(struct btrfs_fs_info *
88 mutex_lock(&fs_info->fs_devices->device_list_mutex);
89 devices = &fs_info->fs_devices->devices;
90 list_for_each_entry(device, devices, dev_list) {
91 - ret = btrfs_trim_free_extents(device, range, &group_trimmed);
92 + ret = btrfs_trim_free_extents(device, range->minlen,
93 + &group_trimmed);
94 if (ret) {
95 dev_failed++;
96 dev_ret = ret;