mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
Btrfs: fix max chunk size on raid5/6
We try to limit the size of a chunk to 10GB, which keeps the unit of work reasonable during balance and resize operations. The limit checks were taking into account the number of copies of the data we had but what they really should be doing is comparing against the logical size of the chunk we're creating. This moves the code around a little to use the count of data stripes from raid5/6. Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
parent
24542bf7ea
commit
86db25785a
@ -3837,10 +3837,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
|
|||||||
*/
|
*/
|
||||||
data_stripes = num_stripes / ncopies;
|
data_stripes = num_stripes / ncopies;
|
||||||
|
|
||||||
if (stripe_size * ndevs > max_chunk_size * ncopies) {
|
|
||||||
stripe_size = max_chunk_size * ncopies;
|
|
||||||
do_div(stripe_size, ndevs);
|
|
||||||
}
|
|
||||||
if (type & BTRFS_BLOCK_GROUP_RAID5) {
|
if (type & BTRFS_BLOCK_GROUP_RAID5) {
|
||||||
raid_stripe_len = find_raid56_stripe_len(ndevs - 1,
|
raid_stripe_len = find_raid56_stripe_len(ndevs - 1,
|
||||||
btrfs_super_stripesize(info->super_copy));
|
btrfs_super_stripesize(info->super_copy));
|
||||||
@ -3851,6 +3847,27 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
|
|||||||
btrfs_super_stripesize(info->super_copy));
|
btrfs_super_stripesize(info->super_copy));
|
||||||
data_stripes = num_stripes - 2;
|
data_stripes = num_stripes - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use the number of data stripes to figure out how big this chunk
|
||||||
|
* is really going to be in terms of logical address space,
|
||||||
|
* and compare that answer with the max chunk size
|
||||||
|
*/
|
||||||
|
if (stripe_size * data_stripes > max_chunk_size) {
|
||||||
|
u64 mask = (1ULL << 24) - 1;
|
||||||
|
stripe_size = max_chunk_size;
|
||||||
|
do_div(stripe_size, data_stripes);
|
||||||
|
|
||||||
|
/* bump the answer up to a 16MB boundary */
|
||||||
|
stripe_size = (stripe_size + mask) & ~mask;
|
||||||
|
|
||||||
|
/* but don't go higher than the limits we found
|
||||||
|
* while searching for free extents
|
||||||
|
*/
|
||||||
|
if (stripe_size > devices_info[ndevs-1].max_avail)
|
||||||
|
stripe_size = devices_info[ndevs-1].max_avail;
|
||||||
|
}
|
||||||
|
|
||||||
do_div(stripe_size, dev_stripes);
|
do_div(stripe_size, dev_stripes);
|
||||||
|
|
||||||
/* align to BTRFS_STRIPE_LEN */
|
/* align to BTRFS_STRIPE_LEN */
|
||||||
|
Loading…
Reference in New Issue
Block a user