@@ -1481,10 +1481,16 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
num_stripes = nr_devices;
} else if (type & BTRFS_BLOCK_GROUP_RAID1) {
min_stripes = 2;
- num_stripes = 2;
+ num_stripes = nr_devices & ~1llu;
} else if (type & BTRFS_BLOCK_GROUP_RAID10) {
min_stripes = 4;
- num_stripes = 4;
+ num_stripes = nr_devices & ~1llu;
+ } else if (type & BTRFS_BLOCK_GROUP_RAID5) {
+ min_stripes = 3;
+ num_stripes = nr_devices;
+ } else if (type & BTRFS_BLOCK_GROUP_RAID6) {
+ min_stripes = 4;
+ num_stripes = nr_devices;
}
if (type & BTRFS_BLOCK_GROUP_DUP)
@@ -1561,8 +1567,30 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
if (devices_info[i].max_avail >= min_stripe_size) {
int j;
u64 alloc_size;
+ int k;
- avail_space += devices_info[i].max_avail * num_stripes;
+ /*
+ * Depending by the RAID profile, we use some
+ * disk space as redundancy:
+ * RAID1, RAID10, DUP -> half of space used as redundancy
+ * RAID5 -> 1 stripe used as redundancy
+ * RAID6 -> 2 stripes used as redundancy
+ * RAID0,LINEAR -> no redundancy
+ */
+ if (type & BTRFS_BLOCK_GROUP_RAID1) {
+ k = num_stripes >> 1;
+ } else if (type & BTRFS_BLOCK_GROUP_DUP) {
+ k = num_stripes >> 1;
+ } else if (type & BTRFS_BLOCK_GROUP_RAID10) {
+ k = num_stripes >> 1;
+ } else if (type & BTRFS_BLOCK_GROUP_RAID5) {
+ k = num_stripes-1;
+ } else if (type & BTRFS_BLOCK_GROUP_RAID6) {
+ k = num_stripes-2;
+ } else { /* RAID0/LINEAR */
+ k = num_stripes;
+ }
+ avail_space += devices_info[i].max_avail * k;
alloc_size = devices_info[i].max_avail;
for (j = i + 1 - num_stripes; j <= i; j++)
devices_info[j].max_avail -= alloc_size;