diff options
author | Qu Wenruo <wqu@suse.com> | 2022-06-17 12:04:06 +0200 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2022-06-22 20:30:58 +0200 |
commit | a8aa67e6507575b2ea27e9dcd1bcd70fbe65ac1f (patch) | |
tree | 42165f60e21b043de4439caff377243122021cbb /fs/btrfs | |
parent | 6a45cb21d292696e41d6ca0f97608bc4d7442442 (diff) | |
download | linux-next-a8aa67e6507575b2ea27e9dcd1bcd70fbe65ac1f.tar.gz |
btrfs: return proper mapped length for RAID56 profiles in __btrfs_map_block()
For profiles other than RAID56, __btrfs_map_block() returns @map_length
as min(stripe_end, logical + *length), which is also the same result
from btrfs_get_io_geometry().
But for RAID56, __btrfs_map_block() returns @map_length as stripe_len.
This strange behavior is going to hurt incoming bio split at
btrfs_map_bio() time, as we will use @map_length as bio split size.
Fix this behavior by returning @map_length by the same calculation as
for other profiles.
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Tested-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/volumes.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 1c4d3eac5b59..6bfb662f3ad3 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -6471,7 +6471,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, num_stripes = map->num_stripes; max_errors = btrfs_chunk_max_errors(map); - *length = map->stripe_len; + /* Return the length to the full stripe end */ + *length = min(logical + *length, + raid56_full_stripe_start + em->start + + data_stripes * stripe_len) - logical; stripe_index = 0; stripe_offset = 0; } else { |