FAILED: patch "[PATCH] btrfs: Ensure btrfs_trim_fs can trim the whole filesystem" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
6ba9fc8e628becf0e3ec94083450d089b0dec5f5Mon Sep 17 00:00:00 2001
From: Qu Wenruo <[email protected]>
Date: Fri, 7 Sep 2018 14:16:24 +0800
Subject: [PATCH] btrfs: Ensure btrfs_trim_fs can trim the whole filesystem
[BUG]
fstrim on some btrfs only trims the unallocated space, not trimming any space in existing block groups.
[CAUSE]
Before fstrim_range passed to btrfs_trim_fs(), it gets truncated to range [0, super->total_bytes). So later btrfs_trim_fs() will only be able to trim block groups in range [0, super->total_bytes).
While for btrfs, any bytenr aligned to sectorsize is valid, since btrfs uses its logical address space, there is nothing limiting the location where we put block groups.
For filesystem with frequent balance, it's quite easy to relocate all block groups and bytenr of block groups will start beyond super->total_bytes.
In that case, btrfs will not trim existing block groups.
[FIX]
Just remove the truncation in btrfs_ioctl_fitrim(), so btrfs_trim_fs() can get the unmodified range, which is normally set to [0, U64_MAX].
fs/btrfs/extent-tree.c +1 -9
@@ -10851,21 +10851,13 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)u64 start;u64 end;u64 trimmed =0 ; -u64 total_bytes =btrfs_super_total_bytes (fs_info->super_copy);u64 bg_failed =0 ;u64 dev_failed =0 ;int bg_ret =0 ;int dev_ret =0 ;int ret =0 ; -/* -* try to trim all FS space, our block group may start from non-zero. -*/ -if (range->len == total_bytes) - cache =btrfs_lookup_first_block_group (fs_info, range->start); -else - cache =btrfs_lookup_block_group (fs_info, range->start); - + cache =btrfs_lookup_first_block_group (fs_info, range->start);for (; cache; cache =next_block_group (fs_info, cache)) {if (cache->key.objectid >= (range->start + range->len)) {btrfs_put_block_group (cache);
fs/btrfs/ioctl.c +7 -4
@@ -491,7 +491,6 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)struct fstrim_range range;u64 minlen =ULLONG_MAX ;u64 num_devices =0 ; -u64 total_bytes =btrfs_super_total_bytes (fs_info->super_copy);int ret;if (!capable (CAP_SYS_ADMIN ))
@@ -515,11 +514,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)return -EOPNOTSUPP ;if (copy_from_user (&range, arg,sizeof (range)))return -EFAULT ; -if (range.start > total_bytes || - range.len < fs_info->sb->s_blocksize) + +/* +* NOTE: Don't truncate the range using super->total_bytes. Bytenr of +* block group is in the logical address space, which can be any +* sectorsize aligned bytenr in the range [0, U64_MAX]. +*/ +if (range.len < fs_info->sb->s_blocksize)return -EINVAL ; - range.len =min (range.len, total_bytes - range.start); range.minlen =max (range.minlen, minlen); ret =btrfs_trim_fs (fs_info, &range);if (ret <0 )
PATCH 3/3 btrfs: Ensure btrfs_trim_fs can trim the whole filesystem
From: Qu Wenruo <[email protected]>
[BUG]
fstrim on some btrfs only trims the unallocated space, not trimming any space in existing block groups.
[CAUSE]
Before fstrim_range passed to btrfs_trim_fs(), it gets truncated to range [0, super->total_bytes). So later btrfs_trim_fs() will only be able to trim block groups in range [0, super->total_bytes).
While for btrfs, any bytenr aligned to sectorsize is valid, since btrfs uses its logical address space, there is nothing limiting the location where we put block groups.
For filesystem with frequent balance, it's quite easy to relocate all block groups and bytenr of block groups will start beyond super->total_bytes.
In that case, btrfs will not trim existing block groups.
[FIX]
Just remove the truncation in btrfs_ioctl_fitrim(), so btrfs_trim_fs() can get the unmodified range, which is normally set to [0, U64_MAX].
---
Hello Greg,
Please apply upstream commit 6ba9fc8e628becf0e3ec94083450d089b0dec5f5 to 4.4.y and 4.9.y. This backport should apply cleanly to both trees.
fs/btrfs/extent-tree.c | 10 +--------- fs/btrfs/ioctl.c | 11 +++++++---- 2 files changed, 8 insertions(+), 13 deletions(-)
fs/btrfs/extent-tree.c +1 -9
@@ -10680,17 +10680,9 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)u64 start;u64 end;u64 trimmed =0 ; -u64 total_bytes =btrfs_super_total_bytes (fs_info->super_copy);int ret =0 ; -/* -* try to trim all FS space, our block group may start from non-zero. -*/ -if (range->len == total_bytes) - cache =btrfs_lookup_first_block_group (fs_info, range->start); -else - cache =btrfs_lookup_block_group (fs_info, range->start); - + cache =btrfs_lookup_first_block_group (fs_info, range->start);while (cache) {if (cache->key.objectid >= (range->start + range->len)) {btrfs_put_block_group (cache);
fs/btrfs/ioctl.c +7 -4
@@ -378,7 +378,6 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)struct fstrim_range range;u64 minlen =ULLONG_MAX ;u64 num_devices =0 ; -u64 total_bytes =btrfs_super_total_bytes (fs_info->super_copy);int ret;if (!capable (CAP_SYS_ADMIN ))
@@ -402,11 +401,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)return -EOPNOTSUPP ;if (copy_from_user (&range, arg,sizeof (range)))return -EFAULT ; -if (range.start > total_bytes || - range.len < fs_info->sb->s_blocksize) + +/* +* NOTE: Don't truncate the range using super->total_bytes. Bytenr of +* block group is in the logical address space, which can be any +* sectorsize aligned bytenr in the range [0, U64_MAX]. +*/ +if (range.len < fs_info->sb->s_blocksize)return -EINVAL ; - range.len =min (range.len, total_bytes - range.start); range.minlen =max (range.minlen, minlen); ret =btrfs_trim_fs (fs_info->tree_root, &range);if (ret <0 )
Signature · 1 line
2.17.1
Re: [PATCH 3/3] btrfs: Ensure btrfs_trim_fs can trim the whole filesystem
Quoted 32 lines · Nikolay Borisov
From: Qu Wenruo <[email protected]>
[BUG]
fstrim on some btrfs only trims the unallocated space, not trimming any space in existing block groups.[CAUSE]
Beforefstrim_rangepassed tobtrfs_trim_fs(), it gets truncated to range [0,super->total_bytes). So laterbtrfs_trim_fs()will only be able to trim block groups in range [0,super->total_bytes).While for btrfs, any bytenr aligned to sectorsize is valid, since btrfs uses its logical address space, there is nothing limiting the location where we put block groups.
For filesystem with frequent balance, it's quite easy to relocate all block groups and bytenr of block groups will start beyond
super->total_bytes.In that case, btrfs will not trim existing block groups.
[FIX]
Just remove the truncation inbtrfs_ioctl_fitrim(), sobtrfs_trim_fs()can get the unmodified range, which is normally set to [0,U64_MAX].Reported-by Chris Murphy <[email protected]>Fixes f4c697e6406d ("btrfs: return EINVAL if start > total_bytes in fitrim ioctl")CC <[email protected]> # v4.4+Signed-off-by Qu Wenruo <[email protected]>Reviewed-by Nikolay Borisov <[email protected]>Reviewed-by David Sterba <[email protected]>Signed-off-by David Sterba <[email protected]>
Quoted 6 lines
---
Hello Greg,
Please apply upstream commit
6ba9fc8e628becf0e3ec94083450d089b0dec5f5to 4.4.y and 4.9.y. This backport should apply cleanly to both trees.
This is already in 4.9.141, so I only applied it to 4.4.y
thanks,
greg k-h