Re: [PATCH 2/4] btrfs: Always trim all unallocated space in btrfs_trim_free_extents

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2019/6/3 下午6:06, Nikolay Borisov wrote:
> This patch removes support for range parameters of FITRIM ioctl when
> trimming unallocated space on devices. This is necessary since ranges
> passed from user space are generally interpreted as logical addresses,
> whereas btrfs_trim_free_extents used to interpret them as device
> physical extents. This could result in counter-intuitive behavior for
> users so it's best to remove that support altogether.
>
> Additionally, the existing range support had a bug where if an offset
> was passed to FITRIM which overflows u64 e.g. -1 (parsed as u64
> 18446744073709551615) then wrong data was fed into btrfs_issue_discard,
> which in turn leads to wrap-around when aligning the passed range and
> results in wrong regions being discarded which leads to data corruption.
>
> Signed-off-by: Nikolay Borisov <nborisov@xxxxxxxx>

Reveiwed-by: Qu Wenruo <wqu@xxxxxxxx>

Thanks,
Qu

> ---
>  fs/btrfs/extent-tree.c | 28 +++-------------------------
>  1 file changed, 3 insertions(+), 25 deletions(-)
>
> diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
> index 96628eb4b389..d8c5febf7636 100644
> --- a/fs/btrfs/extent-tree.c
> +++ b/fs/btrfs/extent-tree.c
> @@ -11145,13 +11145,11 @@ int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info,
>   * it while performing the free space search since we have already
>   * held back allocations.
>   */
> -static int btrfs_trim_free_extents(struct btrfs_device *device,
> -				   struct fstrim_range *range, u64 *trimmed)
> +static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
>  {
> -	u64 start, len = 0, end = 0;
> +	u64 start = SZ_1M, len = 0, end = 0;
>  	int ret;
>
> -	start = max_t(u64, range->start, SZ_1M);
>  	*trimmed = 0;
>
>  	/* Discard not supported = nothing to do. */
> @@ -11194,22 +11192,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
>  			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,
>  					  &bytes);
>  		if (!ret)
> @@ -11224,10 +11206,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
>  		start += len;
>  		*trimmed += bytes;
>
> -		/* We've trimmed enough */
> -		if (*trimmed >= range->len)
> -			break;
> -
>  		if (fatal_signal_pending(current)) {
>  			ret = -ERESTARTSYS;
>  			break;
> @@ -11311,7 +11289,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
>  	mutex_lock(&fs_info->fs_devices->device_list_mutex);
>  	devices = &fs_info->fs_devices->devices;
>  	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) {
>  			dev_failed++;
>  			dev_ret = ret;
>




[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux