aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2012-01-16 15:04:48 -0500
committerIlya Dryomov <idryomov@gmail.com>2012-01-16 15:04:48 -0500
commite4d8ec0f65b91bfb4984a4927632ded95f9825ad (patch)
tree4727c977803093ec5cdf93da4fcab34cc8de8ecf /fs/btrfs/volumes.c
parent70922617b0099f420deceb53d5dc7f4fb30d08d0 (diff)
Btrfs: implement online profile changing
Profile changing is done by launching a balance with BTRFS_BALANCE_CONVERT bits set and target fields of respective btrfs_balance_args structs initialized. Profile reducing code in this case will pick restriper's target profile if it's available instead of doing a blind reduce. If target profile is not yet available it goes back to a plain reduce. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e86c9e4fe51e..f08210e83339 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2438,6 +2438,75 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
2438 } 2438 }
2439 } 2439 }
2440 2440
2441 /*
2442 * Profile changing sanity checks. Skip them if a simple
2443 * balance is requested.
2444 */
2445 if (!((bctl->data.flags | bctl->sys.flags | bctl->meta.flags) &
2446 BTRFS_BALANCE_ARGS_CONVERT))
2447 goto do_balance;
2448
2449 allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE;
2450 if (fs_info->fs_devices->num_devices == 1)
2451 allowed |= BTRFS_BLOCK_GROUP_DUP;
2452 else if (fs_info->fs_devices->num_devices < 4)
2453 allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1);
2454 else
2455 allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 |
2456 BTRFS_BLOCK_GROUP_RAID10);
2457
2458 if (!profile_is_valid(bctl->data.target, 1) ||
2459 bctl->data.target & ~allowed) {
2460 printk(KERN_ERR "btrfs: unable to start balance with target "
2461 "data profile %llu\n",
2462 (unsigned long long)bctl->data.target);
2463 ret = -EINVAL;
2464 goto out;
2465 }
2466 if (!profile_is_valid(bctl->meta.target, 1) ||
2467 bctl->meta.target & ~allowed) {
2468 printk(KERN_ERR "btrfs: unable to start balance with target "
2469 "metadata profile %llu\n",
2470 (unsigned long long)bctl->meta.target);
2471 ret = -EINVAL;
2472 goto out;
2473 }
2474 if (!profile_is_valid(bctl->sys.target, 1) ||
2475 bctl->sys.target & ~allowed) {
2476 printk(KERN_ERR "btrfs: unable to start balance with target "
2477 "system profile %llu\n",
2478 (unsigned long long)bctl->sys.target);
2479 ret = -EINVAL;
2480 goto out;
2481 }
2482
2483 if (bctl->data.target & BTRFS_BLOCK_GROUP_DUP) {
2484 printk(KERN_ERR "btrfs: dup for data is not allowed\n");
2485 ret = -EINVAL;
2486 goto out;
2487 }
2488
2489 /* allow to reduce meta or sys integrity only if force set */
2490 allowed = BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1 |
2491 BTRFS_BLOCK_GROUP_RAID10;
2492 if (((bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) &&
2493 (fs_info->avail_system_alloc_bits & allowed) &&
2494 !(bctl->sys.target & allowed)) ||
2495 ((bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT) &&
2496 (fs_info->avail_metadata_alloc_bits & allowed) &&
2497 !(bctl->meta.target & allowed))) {
2498 if (bctl->flags & BTRFS_BALANCE_FORCE) {
2499 printk(KERN_INFO "btrfs: force reducing metadata "
2500 "integrity\n");
2501 } else {
2502 printk(KERN_ERR "btrfs: balance will reduce metadata "
2503 "integrity, use force if you want this\n");
2504 ret = -EINVAL;
2505 goto out;
2506 }
2507 }
2508
2509do_balance:
2441 set_balance_control(bctl); 2510 set_balance_control(bctl);
2442 2511
2443 mutex_unlock(&fs_info->balance_mutex); 2512 mutex_unlock(&fs_info->balance_mutex);