aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 177b73179590..c50a85e0d08f 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2177,6 +2177,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
2177 int num_stripes = 1; 2177 int num_stripes = 1;
2178 int min_stripes = 1; 2178 int min_stripes = 1;
2179 int sub_stripes = 0; 2179 int sub_stripes = 0;
2180 int ncopies = 1;
2180 int looped = 0; 2181 int looped = 0;
2181 int ret; 2182 int ret;
2182 int index; 2183 int index;
@@ -2197,12 +2198,14 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
2197 if (type & (BTRFS_BLOCK_GROUP_DUP)) { 2198 if (type & (BTRFS_BLOCK_GROUP_DUP)) {
2198 num_stripes = 2; 2199 num_stripes = 2;
2199 min_stripes = 2; 2200 min_stripes = 2;
2201 ncopies = 2;
2200 } 2202 }
2201 if (type & (BTRFS_BLOCK_GROUP_RAID1)) { 2203 if (type & (BTRFS_BLOCK_GROUP_RAID1)) {
2202 if (fs_devices->rw_devices < 2) 2204 if (fs_devices->rw_devices < 2)
2203 return -ENOSPC; 2205 return -ENOSPC;
2204 num_stripes = 2; 2206 num_stripes = 2;
2205 min_stripes = 2; 2207 min_stripes = 2;
2208 ncopies = 2;
2206 } 2209 }
2207 if (type & (BTRFS_BLOCK_GROUP_RAID10)) { 2210 if (type & (BTRFS_BLOCK_GROUP_RAID10)) {
2208 num_stripes = fs_devices->rw_devices; 2211 num_stripes = fs_devices->rw_devices;
@@ -2210,6 +2213,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
2210 return -ENOSPC; 2213 return -ENOSPC;
2211 num_stripes &= ~(u32)1; 2214 num_stripes &= ~(u32)1;
2212 sub_stripes = 2; 2215 sub_stripes = 2;
2216 ncopies = 2;
2213 min_stripes = 4; 2217 min_stripes = 4;
2214 } 2218 }
2215 2219
@@ -2239,8 +2243,8 @@ again:
2239 map->num_stripes = num_stripes; 2243 map->num_stripes = num_stripes;
2240 } 2244 }
2241 2245
2242 if (calc_size * num_stripes > max_chunk_size) { 2246 if (calc_size * num_stripes > max_chunk_size * ncopies) {
2243 calc_size = max_chunk_size; 2247 calc_size = max_chunk_size * ncopies;
2244 do_div(calc_size, num_stripes); 2248 do_div(calc_size, num_stripes);
2245 do_div(calc_size, stripe_len); 2249 do_div(calc_size, stripe_len);
2246 calc_size *= stripe_len; 2250 calc_size *= stripe_len;
@@ -2321,6 +2325,8 @@ again:
2321 if (!looped && max_avail > 0) { 2325 if (!looped && max_avail > 0) {
2322 looped = 1; 2326 looped = 1;
2323 calc_size = max_avail; 2327 calc_size = max_avail;
2328 if (type & BTRFS_BLOCK_GROUP_DUP)
2329 do_div(calc_size, 2);
2324 goto again; 2330 goto again;
2325 } 2331 }
2326 kfree(map); 2332 kfree(map);