|
@@ -3822,7 +3822,8 @@ static u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
|
|
|
{
|
|
|
u64 num_devices = root->fs_info->fs_devices->rw_devices;
|
|
|
u64 target;
|
|
|
- u64 tmp;
|
|
|
+ u64 raid_type;
|
|
|
+ u64 allowed = 0;
|
|
|
|
|
|
/*
|
|
|
* see if restripe for this chunk_type is in progress, if so
|
|
@@ -3840,31 +3841,26 @@ static u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
|
|
|
spin_unlock(&root->fs_info->balance_lock);
|
|
|
|
|
|
/* First, mask out the RAID levels which aren't possible */
|
|
|
- if (num_devices == 1)
|
|
|
- flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0 |
|
|
|
- BTRFS_BLOCK_GROUP_RAID5);
|
|
|
- if (num_devices < 3)
|
|
|
- flags &= ~BTRFS_BLOCK_GROUP_RAID6;
|
|
|
- if (num_devices < 4)
|
|
|
- flags &= ~BTRFS_BLOCK_GROUP_RAID10;
|
|
|
-
|
|
|
- tmp = flags & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID0 |
|
|
|
- BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID5 |
|
|
|
- BTRFS_BLOCK_GROUP_RAID6 | BTRFS_BLOCK_GROUP_RAID10);
|
|
|
- flags &= ~tmp;
|
|
|
-
|
|
|
- if (tmp & BTRFS_BLOCK_GROUP_RAID6)
|
|
|
- tmp = BTRFS_BLOCK_GROUP_RAID6;
|
|
|
- else if (tmp & BTRFS_BLOCK_GROUP_RAID5)
|
|
|
- tmp = BTRFS_BLOCK_GROUP_RAID5;
|
|
|
- else if (tmp & BTRFS_BLOCK_GROUP_RAID10)
|
|
|
- tmp = BTRFS_BLOCK_GROUP_RAID10;
|
|
|
- else if (tmp & BTRFS_BLOCK_GROUP_RAID1)
|
|
|
- tmp = BTRFS_BLOCK_GROUP_RAID1;
|
|
|
- else if (tmp & BTRFS_BLOCK_GROUP_RAID0)
|
|
|
- tmp = BTRFS_BLOCK_GROUP_RAID0;
|
|
|
-
|
|
|
- return extended_to_chunk(flags | tmp);
|
|
|
+ for (raid_type = 0; raid_type < BTRFS_NR_RAID_TYPES; raid_type++) {
|
|
|
+ if (num_devices >= btrfs_raid_array[raid_type].devs_min)
|
|
|
+ allowed |= btrfs_raid_group[raid_type];
|
|
|
+ }
|
|
|
+ allowed &= flags;
|
|
|
+
|
|
|
+ if (allowed & BTRFS_BLOCK_GROUP_RAID6)
|
|
|
+ allowed = BTRFS_BLOCK_GROUP_RAID6;
|
|
|
+ else if (allowed & BTRFS_BLOCK_GROUP_RAID5)
|
|
|
+ allowed = BTRFS_BLOCK_GROUP_RAID5;
|
|
|
+ else if (allowed & BTRFS_BLOCK_GROUP_RAID10)
|
|
|
+ allowed = BTRFS_BLOCK_GROUP_RAID10;
|
|
|
+ else if (allowed & BTRFS_BLOCK_GROUP_RAID1)
|
|
|
+ allowed = BTRFS_BLOCK_GROUP_RAID1;
|
|
|
+ else if (allowed & BTRFS_BLOCK_GROUP_RAID0)
|
|
|
+ allowed = BTRFS_BLOCK_GROUP_RAID0;
|
|
|
+
|
|
|
+ flags &= ~BTRFS_BLOCK_GROUP_PROFILE_MASK;
|
|
|
+
|
|
|
+ return extended_to_chunk(flags | allowed);
|
|
|
}
|
|
|
|
|
|
static u64 get_alloc_profile(struct btrfs_root *root, u64 orig_flags)
|