diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 1a3ce9e0b495..41495dce4db0 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1079,7 +1079,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1079 | u64 avail_space; | 1079 | u64 avail_space; |
1080 | u64 used_space; | 1080 | u64 used_space; |
1081 | u64 min_stripe_size; | 1081 | u64 min_stripe_size; |
1082 | int min_stripes = 1; | 1082 | int min_stripes = 1, num_stripes = 1; |
1083 | int i = 0, nr_devices; | 1083 | int i = 0, nr_devices; |
1084 | int ret; | 1084 | int ret; |
1085 | 1085 | ||
@@ -1093,12 +1093,16 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1093 | 1093 | ||
1094 | /* calc min stripe number for data space alloction */ | 1094 | /* calc min stripe number for data space alloction */ |
1095 | type = btrfs_get_alloc_profile(root, 1); | 1095 | type = btrfs_get_alloc_profile(root, 1); |
1096 | if (type & BTRFS_BLOCK_GROUP_RAID0) | 1096 | if (type & BTRFS_BLOCK_GROUP_RAID0) { |
1097 | min_stripes = 2; | 1097 | min_stripes = 2; |
1098 | else if (type & BTRFS_BLOCK_GROUP_RAID1) | 1098 | num_stripes = nr_devices; |
1099 | } else if (type & BTRFS_BLOCK_GROUP_RAID1) { | ||
1099 | min_stripes = 2; | 1100 | min_stripes = 2; |
1100 | else if (type & BTRFS_BLOCK_GROUP_RAID10) | 1101 | num_stripes = 2; |
1102 | } else if (type & BTRFS_BLOCK_GROUP_RAID10) { | ||
1101 | min_stripes = 4; | 1103 | min_stripes = 4; |
1104 | num_stripes = 4; | ||
1105 | } | ||
1102 | 1106 | ||
1103 | if (type & BTRFS_BLOCK_GROUP_DUP) | 1107 | if (type & BTRFS_BLOCK_GROUP_DUP) |
1104 | min_stripe_size = 2 * BTRFS_STRIPE_LEN; | 1108 | min_stripe_size = 2 * BTRFS_STRIPE_LEN; |
@@ -1167,13 +1171,16 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1167 | i = nr_devices - 1; | 1171 | i = nr_devices - 1; |
1168 | avail_space = 0; | 1172 | avail_space = 0; |
1169 | while (nr_devices >= min_stripes) { | 1173 | while (nr_devices >= min_stripes) { |
1174 | if (num_stripes > nr_devices) | ||
1175 | num_stripes = nr_devices; | ||
1176 | |||
1170 | if (devices_info[i].max_avail >= min_stripe_size) { | 1177 | if (devices_info[i].max_avail >= min_stripe_size) { |
1171 | int j; | 1178 | int j; |
1172 | u64 alloc_size; | 1179 | u64 alloc_size; |
1173 | 1180 | ||
1174 | avail_space += devices_info[i].max_avail * min_stripes; | 1181 | avail_space += devices_info[i].max_avail * num_stripes; |
1175 | alloc_size = devices_info[i].max_avail; | 1182 | alloc_size = devices_info[i].max_avail; |
1176 | for (j = i + 1 - min_stripes; j <= i; j++) | 1183 | for (j = i + 1 - num_stripes; j <= i; j++) |
1177 | devices_info[j].max_avail -= alloc_size; | 1184 | devices_info[j].max_avail -= alloc_size; |
1178 | } | 1185 | } |
1179 | i--; | 1186 | i--; |