diff options
-rw-r--r-- | fs/btrfs/volumes.c | 481 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 1 |
2 files changed, 177 insertions, 305 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 45c592a7335e..ab55bfc31a06 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -2268,262 +2268,204 @@ static int btrfs_add_system_chunk(struct btrfs_trans_handle *trans, | |||
2268 | return 0; | 2268 | return 0; |
2269 | } | 2269 | } |
2270 | 2270 | ||
2271 | static noinline u64 chunk_bytes_by_type(u64 type, u64 calc_size, | 2271 | /* |
2272 | int num_stripes, int sub_stripes) | 2272 | * sort the devices in descending order by max_avail, total_avail |
2273 | */ | ||
2274 | static int btrfs_cmp_device_info(const void *a, const void *b) | ||
2273 | { | 2275 | { |
2274 | if (type & (BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_DUP)) | 2276 | const struct btrfs_device_info *di_a = a; |
2275 | return calc_size; | 2277 | const struct btrfs_device_info *di_b = b; |
2276 | else if (type & BTRFS_BLOCK_GROUP_RAID10) | 2278 | |
2277 | return calc_size * (num_stripes / sub_stripes); | 2279 | if (di_a->max_avail > di_b->max_avail) |
2278 | else | 2280 | return -1; |
2279 | return calc_size * num_stripes; | 2281 | if (di_a->max_avail < di_b->max_avail) |
2282 | return 1; | ||
2283 | if (di_a->total_avail > di_b->total_avail) | ||
2284 | return -1; | ||
2285 | if (di_a->total_avail < di_b->total_avail) | ||
2286 | return 1; | ||
2287 | return 0; | ||
2280 | } | 2288 | } |
2281 | 2289 | ||
2282 | static int __btrfs_calc_nstripes(struct btrfs_fs_devices *fs_devices, u64 type, | 2290 | static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, |
2283 | int *num_stripes, int *min_stripes, | 2291 | struct btrfs_root *extent_root, |
2284 | int *sub_stripes) | 2292 | struct map_lookup **map_ret, |
2293 | u64 *num_bytes_out, u64 *stripe_size_out, | ||
2294 | u64 start, u64 type) | ||
2285 | { | 2295 | { |
2286 | *num_stripes = 1; | 2296 | struct btrfs_fs_info *info = extent_root->fs_info; |
2287 | *min_stripes = 1; | 2297 | struct btrfs_fs_devices *fs_devices = info->fs_devices; |
2288 | *sub_stripes = 0; | 2298 | struct list_head *cur; |
2299 | struct map_lookup *map = NULL; | ||
2300 | struct extent_map_tree *em_tree; | ||
2301 | struct extent_map *em; | ||
2302 | struct btrfs_device_info *devices_info = NULL; | ||
2303 | u64 total_avail; | ||
2304 | int num_stripes; /* total number of stripes to allocate */ | ||
2305 | int sub_stripes; /* sub_stripes info for map */ | ||
2306 | int dev_stripes; /* stripes per dev */ | ||
2307 | int devs_max; /* max devs to use */ | ||
2308 | int devs_min; /* min devs needed */ | ||
2309 | int devs_increment; /* ndevs has to be a multiple of this */ | ||
2310 | int ncopies; /* how many copies to data has */ | ||
2311 | int ret; | ||
2312 | u64 max_stripe_size; | ||
2313 | u64 max_chunk_size; | ||
2314 | u64 stripe_size; | ||
2315 | u64 num_bytes; | ||
2316 | int ndevs; | ||
2317 | int i; | ||
2318 | int j; | ||
2289 | 2319 | ||
2290 | if (type & (BTRFS_BLOCK_GROUP_RAID0)) { | 2320 | if ((type & BTRFS_BLOCK_GROUP_RAID1) && |
2291 | *num_stripes = fs_devices->rw_devices; | 2321 | (type & BTRFS_BLOCK_GROUP_DUP)) { |
2292 | *min_stripes = 2; | 2322 | WARN_ON(1); |
2293 | } | 2323 | type &= ~BTRFS_BLOCK_GROUP_DUP; |
2294 | if (type & (BTRFS_BLOCK_GROUP_DUP)) { | ||
2295 | *num_stripes = 2; | ||
2296 | *min_stripes = 2; | ||
2297 | } | ||
2298 | if (type & (BTRFS_BLOCK_GROUP_RAID1)) { | ||
2299 | if (fs_devices->rw_devices < 2) | ||
2300 | return -ENOSPC; | ||
2301 | *num_stripes = 2; | ||
2302 | *min_stripes = 2; | ||
2303 | } | ||
2304 | if (type & (BTRFS_BLOCK_GROUP_RAID10)) { | ||
2305 | *num_stripes = fs_devices->rw_devices; | ||
2306 | if (*num_stripes < 4) | ||
2307 | return -ENOSPC; | ||
2308 | *num_stripes &= ~(u32)1; | ||
2309 | *sub_stripes = 2; | ||
2310 | *min_stripes = 4; | ||
2311 | } | 2324 | } |
2312 | 2325 | ||
2313 | return 0; | 2326 | if (list_empty(&fs_devices->alloc_list)) |
2314 | } | 2327 | return -ENOSPC; |
2315 | 2328 | ||
2316 | static u64 __btrfs_calc_stripe_size(struct btrfs_fs_devices *fs_devices, | 2329 | sub_stripes = 1; |
2317 | u64 proposed_size, u64 type, | 2330 | dev_stripes = 1; |
2318 | int num_stripes, int small_stripe) | 2331 | devs_increment = 1; |
2319 | { | 2332 | ncopies = 1; |
2320 | int min_stripe_size = 1 * 1024 * 1024; | 2333 | devs_max = 0; /* 0 == as many as possible */ |
2321 | u64 calc_size = proposed_size; | 2334 | devs_min = 1; |
2322 | u64 max_chunk_size = calc_size; | ||
2323 | int ncopies = 1; | ||
2324 | 2335 | ||
2325 | if (type & (BTRFS_BLOCK_GROUP_RAID1 | | 2336 | /* |
2326 | BTRFS_BLOCK_GROUP_DUP | | 2337 | * define the properties of each RAID type. |
2327 | BTRFS_BLOCK_GROUP_RAID10)) | 2338 | * FIXME: move this to a global table and use it in all RAID |
2339 | * calculation code | ||
2340 | */ | ||
2341 | if (type & (BTRFS_BLOCK_GROUP_DUP)) { | ||
2342 | dev_stripes = 2; | ||
2328 | ncopies = 2; | 2343 | ncopies = 2; |
2344 | devs_max = 1; | ||
2345 | } else if (type & (BTRFS_BLOCK_GROUP_RAID0)) { | ||
2346 | devs_min = 2; | ||
2347 | } else if (type & (BTRFS_BLOCK_GROUP_RAID1)) { | ||
2348 | devs_increment = 2; | ||
2349 | ncopies = 2; | ||
2350 | devs_max = 2; | ||
2351 | devs_min = 2; | ||
2352 | } else if (type & (BTRFS_BLOCK_GROUP_RAID10)) { | ||
2353 | sub_stripes = 2; | ||
2354 | devs_increment = 2; | ||
2355 | ncopies = 2; | ||
2356 | devs_min = 4; | ||
2357 | } else { | ||
2358 | devs_max = 1; | ||
2359 | } | ||
2329 | 2360 | ||
2330 | if (type & BTRFS_BLOCK_GROUP_DATA) { | 2361 | if (type & BTRFS_BLOCK_GROUP_DATA) { |
2331 | max_chunk_size = 10 * calc_size; | 2362 | max_stripe_size = 1024 * 1024 * 1024; |
2332 | min_stripe_size = 64 * 1024 * 1024; | 2363 | max_chunk_size = 10 * max_stripe_size; |
2333 | } else if (type & BTRFS_BLOCK_GROUP_METADATA) { | 2364 | } else if (type & BTRFS_BLOCK_GROUP_METADATA) { |
2334 | max_chunk_size = 256 * 1024 * 1024; | 2365 | max_stripe_size = 256 * 1024 * 1024; |
2335 | min_stripe_size = 32 * 1024 * 1024; | 2366 | max_chunk_size = max_stripe_size; |
2336 | } else if (type & BTRFS_BLOCK_GROUP_SYSTEM) { | 2367 | } else if (type & BTRFS_BLOCK_GROUP_SYSTEM) { |
2337 | calc_size = 8 * 1024 * 1024; | 2368 | max_stripe_size = 8 * 1024 * 1024; |
2338 | max_chunk_size = calc_size * 2; | 2369 | max_chunk_size = 2 * max_stripe_size; |
2339 | min_stripe_size = 1 * 1024 * 1024; | 2370 | } else { |
2371 | printk(KERN_ERR "btrfs: invalid chunk type 0x%llx requested\n", | ||
2372 | type); | ||
2373 | BUG_ON(1); | ||
2340 | } | 2374 | } |
2341 | 2375 | ||
2342 | /* we don't want a chunk larger than 10% of writeable space */ | 2376 | /* we don't want a chunk larger than 10% of writeable space */ |
2343 | max_chunk_size = min(div_factor(fs_devices->total_rw_bytes, 1), | 2377 | max_chunk_size = min(div_factor(fs_devices->total_rw_bytes, 1), |
2344 | max_chunk_size); | 2378 | max_chunk_size); |
2345 | 2379 | ||
2346 | if (calc_size * num_stripes > max_chunk_size * ncopies) { | 2380 | devices_info = kzalloc(sizeof(*devices_info) * fs_devices->rw_devices, |
2347 | calc_size = max_chunk_size * ncopies; | 2381 | GFP_NOFS); |
2348 | do_div(calc_size, num_stripes); | 2382 | if (!devices_info) |
2349 | do_div(calc_size, BTRFS_STRIPE_LEN); | 2383 | return -ENOMEM; |
2350 | calc_size *= BTRFS_STRIPE_LEN; | ||
2351 | } | ||
2352 | 2384 | ||
2353 | /* we don't want tiny stripes */ | 2385 | cur = fs_devices->alloc_list.next; |
2354 | if (!small_stripe) | ||
2355 | calc_size = max_t(u64, min_stripe_size, calc_size); | ||
2356 | 2386 | ||
2357 | /* | 2387 | /* |
2358 | * we're about to do_div by the BTRFS_STRIPE_LEN so lets make sure | 2388 | * in the first pass through the devices list, we gather information |
2359 | * we end up with something bigger than a stripe | 2389 | * about the available holes on each device. |
2360 | */ | 2390 | */ |
2361 | calc_size = max_t(u64, calc_size, BTRFS_STRIPE_LEN); | 2391 | ndevs = 0; |
2362 | 2392 | while (cur != &fs_devices->alloc_list) { | |
2363 | do_div(calc_size, BTRFS_STRIPE_LEN); | 2393 | struct btrfs_device *device; |
2364 | calc_size *= BTRFS_STRIPE_LEN; | 2394 | u64 max_avail; |
2365 | 2395 | u64 dev_offset; | |
2366 | return calc_size; | ||
2367 | } | ||
2368 | 2396 | ||
2369 | static struct map_lookup *__shrink_map_lookup_stripes(struct map_lookup *map, | 2397 | device = list_entry(cur, struct btrfs_device, dev_alloc_list); |
2370 | int num_stripes) | ||
2371 | { | ||
2372 | struct map_lookup *new; | ||
2373 | size_t len = map_lookup_size(num_stripes); | ||
2374 | |||
2375 | BUG_ON(map->num_stripes < num_stripes); | ||
2376 | |||
2377 | if (map->num_stripes == num_stripes) | ||
2378 | return map; | ||
2379 | |||
2380 | new = kmalloc(len, GFP_NOFS); | ||
2381 | if (!new) { | ||
2382 | /* just change map->num_stripes */ | ||
2383 | map->num_stripes = num_stripes; | ||
2384 | return map; | ||
2385 | } | ||
2386 | |||
2387 | memcpy(new, map, len); | ||
2388 | new->num_stripes = num_stripes; | ||
2389 | kfree(map); | ||
2390 | return new; | ||
2391 | } | ||
2392 | |||
2393 | /* | ||
2394 | * helper to allocate device space from btrfs_device_info, in which we stored | ||
2395 | * max free space information of every device. It is used when we can not | ||
2396 | * allocate chunks by default size. | ||
2397 | * | ||
2398 | * By this helper, we can allocate a new chunk as larger as possible. | ||
2399 | */ | ||
2400 | static int __btrfs_alloc_tiny_space(struct btrfs_trans_handle *trans, | ||
2401 | struct btrfs_fs_devices *fs_devices, | ||
2402 | struct btrfs_device_info *devices, | ||
2403 | int nr_device, u64 type, | ||
2404 | struct map_lookup **map_lookup, | ||
2405 | int min_stripes, u64 *stripe_size) | ||
2406 | { | ||
2407 | int i, index, sort_again = 0; | ||
2408 | int min_devices = min_stripes; | ||
2409 | u64 max_avail, min_free; | ||
2410 | struct map_lookup *map = *map_lookup; | ||
2411 | int ret; | ||
2412 | 2398 | ||
2413 | if (nr_device < min_stripes) | 2399 | cur = cur->next; |
2414 | return -ENOSPC; | ||
2415 | 2400 | ||
2416 | btrfs_descending_sort_devices(devices, nr_device); | 2401 | if (!device->writeable) { |
2402 | printk(KERN_ERR | ||
2403 | "btrfs: read-only device in alloc_list\n"); | ||
2404 | WARN_ON(1); | ||
2405 | continue; | ||
2406 | } | ||
2417 | 2407 | ||
2418 | max_avail = devices[0].max_avail; | 2408 | if (!device->in_fs_metadata) |
2419 | if (!max_avail) | 2409 | continue; |
2420 | return -ENOSPC; | ||
2421 | 2410 | ||
2422 | for (i = 0; i < nr_device; i++) { | 2411 | if (device->total_bytes > device->bytes_used) |
2423 | /* | 2412 | total_avail = device->total_bytes - device->bytes_used; |
2424 | * if dev_offset = 0, it means the free space of this device | 2413 | else |
2425 | * is less than what we need, and we didn't search max avail | 2414 | total_avail = 0; |
2426 | * extent on this device, so do it now. | 2415 | /* avail is off by max(alloc_start, 1MB), but that is the same |
2416 | * for all devices, so it doesn't hurt the sorting later on | ||
2427 | */ | 2417 | */ |
2428 | if (!devices[i].dev_offset) { | ||
2429 | ret = find_free_dev_extent(trans, devices[i].dev, | ||
2430 | max_avail, | ||
2431 | &devices[i].dev_offset, | ||
2432 | &devices[i].max_avail); | ||
2433 | if (ret != 0 && ret != -ENOSPC) | ||
2434 | return ret; | ||
2435 | sort_again = 1; | ||
2436 | } | ||
2437 | } | ||
2438 | 2418 | ||
2439 | /* we update the max avail free extent of each devices, sort again */ | 2419 | ret = find_free_dev_extent(trans, device, |
2440 | if (sort_again) | 2420 | max_stripe_size * dev_stripes, |
2441 | btrfs_descending_sort_devices(devices, nr_device); | 2421 | &dev_offset, &max_avail); |
2442 | 2422 | if (ret && ret != -ENOSPC) | |
2443 | if (type & BTRFS_BLOCK_GROUP_DUP) | 2423 | goto error; |
2444 | min_devices = 1; | ||
2445 | 2424 | ||
2446 | if (!devices[min_devices - 1].max_avail) | 2425 | if (ret == 0) |
2447 | return -ENOSPC; | 2426 | max_avail = max_stripe_size * dev_stripes; |
2448 | 2427 | ||
2449 | max_avail = devices[min_devices - 1].max_avail; | 2428 | if (max_avail < BTRFS_STRIPE_LEN * dev_stripes) |
2450 | if (type & BTRFS_BLOCK_GROUP_DUP) | 2429 | continue; |
2451 | do_div(max_avail, 2); | ||
2452 | 2430 | ||
2453 | max_avail = __btrfs_calc_stripe_size(fs_devices, max_avail, type, | 2431 | devices_info[ndevs].dev_offset = dev_offset; |
2454 | min_stripes, 1); | 2432 | devices_info[ndevs].max_avail = max_avail; |
2455 | if (type & BTRFS_BLOCK_GROUP_DUP) | 2433 | devices_info[ndevs].total_avail = total_avail; |
2456 | min_free = max_avail * 2; | 2434 | devices_info[ndevs].dev = device; |
2457 | else | 2435 | ++ndevs; |
2458 | min_free = max_avail; | 2436 | } |
2459 | 2437 | ||
2460 | if (min_free > devices[min_devices - 1].max_avail) | 2438 | /* |
2461 | return -ENOSPC; | 2439 | * now sort the devices by hole size / available space |
2440 | */ | ||
2441 | sort(devices_info, ndevs, sizeof(struct btrfs_device_info), | ||
2442 | btrfs_cmp_device_info, NULL); | ||
2462 | 2443 | ||
2463 | map = __shrink_map_lookup_stripes(map, min_stripes); | 2444 | /* round down to number of usable stripes */ |
2464 | *stripe_size = max_avail; | 2445 | ndevs -= ndevs % devs_increment; |
2465 | 2446 | ||
2466 | index = 0; | 2447 | if (ndevs < devs_increment * sub_stripes || ndevs < devs_min) { |
2467 | for (i = 0; i < min_stripes; i++) { | 2448 | ret = -ENOSPC; |
2468 | map->stripes[i].dev = devices[index].dev; | 2449 | goto error; |
2469 | map->stripes[i].physical = devices[index].dev_offset; | ||
2470 | if (type & BTRFS_BLOCK_GROUP_DUP) { | ||
2471 | i++; | ||
2472 | map->stripes[i].dev = devices[index].dev; | ||
2473 | map->stripes[i].physical = devices[index].dev_offset + | ||
2474 | max_avail; | ||
2475 | } | ||
2476 | index++; | ||
2477 | } | 2450 | } |
2478 | *map_lookup = map; | ||
2479 | |||
2480 | return 0; | ||
2481 | } | ||
2482 | 2451 | ||
2483 | static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | 2452 | if (devs_max && ndevs > devs_max) |
2484 | struct btrfs_root *extent_root, | 2453 | ndevs = devs_max; |
2485 | struct map_lookup **map_ret, | 2454 | /* |
2486 | u64 *num_bytes, u64 *stripe_size, | 2455 | * the primary goal is to maximize the number of stripes, so use as many |
2487 | u64 start, u64 type) | 2456 | * devices as possible, even if the stripes are not maximum sized. |
2488 | { | 2457 | */ |
2489 | struct btrfs_fs_info *info = extent_root->fs_info; | 2458 | stripe_size = devices_info[ndevs-1].max_avail; |
2490 | struct btrfs_device *device = NULL; | 2459 | num_stripes = ndevs * dev_stripes; |
2491 | struct btrfs_fs_devices *fs_devices = info->fs_devices; | ||
2492 | struct list_head *cur; | ||
2493 | struct map_lookup *map; | ||
2494 | struct extent_map_tree *em_tree; | ||
2495 | struct extent_map *em; | ||
2496 | struct btrfs_device_info *devices_info; | ||
2497 | struct list_head private_devs; | ||
2498 | u64 calc_size = 1024 * 1024 * 1024; | ||
2499 | u64 min_free; | ||
2500 | u64 avail; | ||
2501 | u64 dev_offset; | ||
2502 | int num_stripes; | ||
2503 | int min_stripes; | ||
2504 | int sub_stripes; | ||
2505 | int min_devices; /* the min number of devices we need */ | ||
2506 | int i; | ||
2507 | int ret; | ||
2508 | int index; | ||
2509 | 2460 | ||
2510 | if ((type & BTRFS_BLOCK_GROUP_RAID1) && | 2461 | if (stripe_size * num_stripes > max_chunk_size * ncopies) { |
2511 | (type & BTRFS_BLOCK_GROUP_DUP)) { | 2462 | stripe_size = max_chunk_size * ncopies; |
2512 | WARN_ON(1); | 2463 | do_div(stripe_size, num_stripes); |
2513 | type &= ~BTRFS_BLOCK_GROUP_DUP; | ||
2514 | } | 2464 | } |
2515 | if (list_empty(&fs_devices->alloc_list)) | ||
2516 | return -ENOSPC; | ||
2517 | |||
2518 | ret = __btrfs_calc_nstripes(fs_devices, type, &num_stripes, | ||
2519 | &min_stripes, &sub_stripes); | ||
2520 | if (ret) | ||
2521 | return ret; | ||
2522 | 2465 | ||
2523 | devices_info = kzalloc(sizeof(*devices_info) * fs_devices->rw_devices, | 2466 | do_div(stripe_size, dev_stripes); |
2524 | GFP_NOFS); | 2467 | do_div(stripe_size, BTRFS_STRIPE_LEN); |
2525 | if (!devices_info) | 2468 | stripe_size *= BTRFS_STRIPE_LEN; |
2526 | return -ENOMEM; | ||
2527 | 2469 | ||
2528 | map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS); | 2470 | map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS); |
2529 | if (!map) { | 2471 | if (!map) { |
@@ -2532,85 +2474,12 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
2532 | } | 2474 | } |
2533 | map->num_stripes = num_stripes; | 2475 | map->num_stripes = num_stripes; |
2534 | 2476 | ||
2535 | cur = fs_devices->alloc_list.next; | 2477 | for (i = 0; i < ndevs; ++i) { |
2536 | index = 0; | 2478 | for (j = 0; j < dev_stripes; ++j) { |
2537 | i = 0; | 2479 | int s = i * dev_stripes + j; |
2538 | 2480 | map->stripes[s].dev = devices_info[i].dev; | |
2539 | calc_size = __btrfs_calc_stripe_size(fs_devices, calc_size, type, | 2481 | map->stripes[s].physical = devices_info[i].dev_offset + |
2540 | num_stripes, 0); | 2482 | j * stripe_size; |
2541 | |||
2542 | if (type & BTRFS_BLOCK_GROUP_DUP) { | ||
2543 | min_free = calc_size * 2; | ||
2544 | min_devices = 1; | ||
2545 | } else { | ||
2546 | min_free = calc_size; | ||
2547 | min_devices = min_stripes; | ||
2548 | } | ||
2549 | |||
2550 | INIT_LIST_HEAD(&private_devs); | ||
2551 | while (index < num_stripes) { | ||
2552 | device = list_entry(cur, struct btrfs_device, dev_alloc_list); | ||
2553 | BUG_ON(!device->writeable); | ||
2554 | if (device->total_bytes > device->bytes_used) | ||
2555 | avail = device->total_bytes - device->bytes_used; | ||
2556 | else | ||
2557 | avail = 0; | ||
2558 | cur = cur->next; | ||
2559 | |||
2560 | if (device->in_fs_metadata && avail >= min_free) { | ||
2561 | ret = find_free_dev_extent(trans, device, min_free, | ||
2562 | &devices_info[i].dev_offset, | ||
2563 | &devices_info[i].max_avail); | ||
2564 | if (ret == 0) { | ||
2565 | list_move_tail(&device->dev_alloc_list, | ||
2566 | &private_devs); | ||
2567 | map->stripes[index].dev = device; | ||
2568 | map->stripes[index].physical = | ||
2569 | devices_info[i].dev_offset; | ||
2570 | index++; | ||
2571 | if (type & BTRFS_BLOCK_GROUP_DUP) { | ||
2572 | map->stripes[index].dev = device; | ||
2573 | map->stripes[index].physical = | ||
2574 | devices_info[i].dev_offset + | ||
2575 | calc_size; | ||
2576 | index++; | ||
2577 | } | ||
2578 | } else if (ret != -ENOSPC) | ||
2579 | goto error; | ||
2580 | |||
2581 | devices_info[i].dev = device; | ||
2582 | i++; | ||
2583 | } else if (device->in_fs_metadata && | ||
2584 | avail >= BTRFS_STRIPE_LEN) { | ||
2585 | devices_info[i].dev = device; | ||
2586 | devices_info[i].max_avail = avail; | ||
2587 | i++; | ||
2588 | } | ||
2589 | |||
2590 | if (cur == &fs_devices->alloc_list) | ||
2591 | break; | ||
2592 | } | ||
2593 | |||
2594 | list_splice(&private_devs, &fs_devices->alloc_list); | ||
2595 | if (index < num_stripes) { | ||
2596 | if (index >= min_stripes) { | ||
2597 | num_stripes = index; | ||
2598 | if (type & (BTRFS_BLOCK_GROUP_RAID10)) { | ||
2599 | num_stripes /= sub_stripes; | ||
2600 | num_stripes *= sub_stripes; | ||
2601 | } | ||
2602 | |||
2603 | map = __shrink_map_lookup_stripes(map, num_stripes); | ||
2604 | } else if (i >= min_devices) { | ||
2605 | ret = __btrfs_alloc_tiny_space(trans, fs_devices, | ||
2606 | devices_info, i, type, | ||
2607 | &map, min_stripes, | ||
2608 | &calc_size); | ||
2609 | if (ret) | ||
2610 | goto error; | ||
2611 | } else { | ||
2612 | ret = -ENOSPC; | ||
2613 | goto error; | ||
2614 | } | 2483 | } |
2615 | } | 2484 | } |
2616 | map->sector_size = extent_root->sectorsize; | 2485 | map->sector_size = extent_root->sectorsize; |
@@ -2621,11 +2490,12 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
2621 | map->sub_stripes = sub_stripes; | 2490 | map->sub_stripes = sub_stripes; |
2622 | 2491 | ||
2623 | *map_ret = map; | 2492 | *map_ret = map; |
2624 | *stripe_size = calc_size; | 2493 | num_bytes = stripe_size * (num_stripes / ncopies); |
2625 | *num_bytes = chunk_bytes_by_type(type, calc_size, | 2494 | |
2626 | map->num_stripes, sub_stripes); | 2495 | *stripe_size_out = stripe_size; |
2496 | *num_bytes_out = num_bytes; | ||
2627 | 2497 | ||
2628 | trace_btrfs_chunk_alloc(info->chunk_root, map, start, *num_bytes); | 2498 | trace_btrfs_chunk_alloc(info->chunk_root, map, start, num_bytes); |
2629 | 2499 | ||
2630 | em = alloc_extent_map(GFP_NOFS); | 2500 | em = alloc_extent_map(GFP_NOFS); |
2631 | if (!em) { | 2501 | if (!em) { |
@@ -2634,7 +2504,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
2634 | } | 2504 | } |
2635 | em->bdev = (struct block_device *)map; | 2505 | em->bdev = (struct block_device *)map; |
2636 | em->start = start; | 2506 | em->start = start; |
2637 | em->len = *num_bytes; | 2507 | em->len = num_bytes; |
2638 | em->block_start = 0; | 2508 | em->block_start = 0; |
2639 | em->block_len = em->len; | 2509 | em->block_len = em->len; |
2640 | 2510 | ||
@@ -2647,20 +2517,21 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
2647 | 2517 | ||
2648 | ret = btrfs_make_block_group(trans, extent_root, 0, type, | 2518 | ret = btrfs_make_block_group(trans, extent_root, 0, type, |
2649 | BTRFS_FIRST_CHUNK_TREE_OBJECTID, | 2519 | BTRFS_FIRST_CHUNK_TREE_OBJECTID, |
2650 | start, *num_bytes); | 2520 | start, num_bytes); |
2651 | BUG_ON(ret); | 2521 | BUG_ON(ret); |
2652 | 2522 | ||
2653 | index = 0; | 2523 | for (i = 0; i < map->num_stripes; ++i) { |
2654 | while (index < map->num_stripes) { | 2524 | struct btrfs_device *device; |
2655 | device = map->stripes[index].dev; | 2525 | u64 dev_offset; |
2656 | dev_offset = map->stripes[index].physical; | 2526 | |
2527 | device = map->stripes[i].dev; | ||
2528 | dev_offset = map->stripes[i].physical; | ||
2657 | 2529 | ||
2658 | ret = btrfs_alloc_dev_extent(trans, device, | 2530 | ret = btrfs_alloc_dev_extent(trans, device, |
2659 | info->chunk_root->root_key.objectid, | 2531 | info->chunk_root->root_key.objectid, |
2660 | BTRFS_FIRST_CHUNK_TREE_OBJECTID, | 2532 | BTRFS_FIRST_CHUNK_TREE_OBJECTID, |
2661 | start, dev_offset, calc_size); | 2533 | start, dev_offset, stripe_size); |
2662 | BUG_ON(ret); | 2534 | BUG_ON(ret); |
2663 | index++; | ||
2664 | } | 2535 | } |
2665 | 2536 | ||
2666 | kfree(devices_info); | 2537 | kfree(devices_info); |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index b502f01f79ed..37ae6e2126a1 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -144,6 +144,7 @@ struct btrfs_device_info { | |||
144 | struct btrfs_device *dev; | 144 | struct btrfs_device *dev; |
145 | u64 dev_offset; | 145 | u64 dev_offset; |
146 | u64 max_avail; | 146 | u64 max_avail; |
147 | u64 total_avail; | ||
147 | }; | 148 | }; |
148 | 149 | ||
149 | struct map_lookup { | 150 | struct map_lookup { |