aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2012-01-16 15:04:49 -0500
committerIlya Dryomov <idryomov@gmail.com>2012-01-16 15:04:49 -0500
commit19a39dce3b9bf0244d19a446718ad6f7605ff099 (patch)
tree4834e177b8b64405aa858bfdcfbabd890277102b /fs/btrfs/volumes.c
parentde322263d3a6d4ffd4ed7c4d0c6536e9497aec9b (diff)
Btrfs: add balance progress reporting
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index c32667318ae4..d73439b4d7da 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2441,6 +2441,7 @@ static u64 div_factor(u64 num, int factor)
2441 2441
2442static int __btrfs_balance(struct btrfs_fs_info *fs_info) 2442static int __btrfs_balance(struct btrfs_fs_info *fs_info)
2443{ 2443{
2444 struct btrfs_balance_control *bctl = fs_info->balance_ctl;
2444 struct btrfs_root *chunk_root = fs_info->chunk_root; 2445 struct btrfs_root *chunk_root = fs_info->chunk_root;
2445 struct btrfs_root *dev_root = fs_info->dev_root; 2446 struct btrfs_root *dev_root = fs_info->dev_root;
2446 struct list_head *devices; 2447 struct list_head *devices;
@@ -2456,6 +2457,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
2456 int slot; 2457 int slot;
2457 int ret; 2458 int ret;
2458 int enospc_errors = 0; 2459 int enospc_errors = 0;
2460 bool counting = true;
2459 2461
2460 /* step one make some room on all the devices */ 2462 /* step one make some room on all the devices */
2461 devices = &fs_info->fs_devices->devices; 2463 devices = &fs_info->fs_devices->devices;
@@ -2487,12 +2489,18 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
2487 ret = -ENOMEM; 2489 ret = -ENOMEM;
2488 goto error; 2490 goto error;
2489 } 2491 }
2492
2493 /* zero out stat counters */
2494 spin_lock(&fs_info->balance_lock);
2495 memset(&bctl->stat, 0, sizeof(bctl->stat));
2496 spin_unlock(&fs_info->balance_lock);
2497again:
2490 key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID; 2498 key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
2491 key.offset = (u64)-1; 2499 key.offset = (u64)-1;
2492 key.type = BTRFS_CHUNK_ITEM_KEY; 2500 key.type = BTRFS_CHUNK_ITEM_KEY;
2493 2501
2494 while (1) { 2502 while (1) {
2495 if (atomic_read(&fs_info->balance_pause_req) || 2503 if ((!counting && atomic_read(&fs_info->balance_pause_req)) ||
2496 atomic_read(&fs_info->balance_cancel_req)) { 2504 atomic_read(&fs_info->balance_cancel_req)) {
2497 ret = -ECANCELED; 2505 ret = -ECANCELED;
2498 goto error; 2506 goto error;
@@ -2529,24 +2537,47 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
2529 2537
2530 chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk); 2538 chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
2531 2539
2540 if (!counting) {
2541 spin_lock(&fs_info->balance_lock);
2542 bctl->stat.considered++;
2543 spin_unlock(&fs_info->balance_lock);
2544 }
2545
2532 ret = should_balance_chunk(chunk_root, leaf, chunk, 2546 ret = should_balance_chunk(chunk_root, leaf, chunk,
2533 found_key.offset); 2547 found_key.offset);
2534 btrfs_release_path(path); 2548 btrfs_release_path(path);
2535 if (!ret) 2549 if (!ret)
2536 goto loop; 2550 goto loop;
2537 2551
2552 if (counting) {
2553 spin_lock(&fs_info->balance_lock);
2554 bctl->stat.expected++;
2555 spin_unlock(&fs_info->balance_lock);
2556 goto loop;
2557 }
2558
2538 ret = btrfs_relocate_chunk(chunk_root, 2559 ret = btrfs_relocate_chunk(chunk_root,
2539 chunk_root->root_key.objectid, 2560 chunk_root->root_key.objectid,
2540 found_key.objectid, 2561 found_key.objectid,
2541 found_key.offset); 2562 found_key.offset);
2542 if (ret && ret != -ENOSPC) 2563 if (ret && ret != -ENOSPC)
2543 goto error; 2564 goto error;
2544 if (ret == -ENOSPC) 2565 if (ret == -ENOSPC) {
2545 enospc_errors++; 2566 enospc_errors++;
2567 } else {
2568 spin_lock(&fs_info->balance_lock);
2569 bctl->stat.completed++;
2570 spin_unlock(&fs_info->balance_lock);
2571 }
2546loop: 2572loop:
2547 key.offset = found_key.offset - 1; 2573 key.offset = found_key.offset - 1;
2548 } 2574 }
2549 2575
2576 if (counting) {
2577 btrfs_release_path(path);
2578 counting = false;
2579 goto again;
2580 }
2550error: 2581error:
2551 btrfs_free_path(path); 2582 btrfs_free_path(path);
2552 if (enospc_errors) { 2583 if (enospc_errors) {
@@ -2576,7 +2607,7 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info)
2576 BUG_ON(ret); 2607 BUG_ON(ret);
2577} 2608}
2578 2609
2579void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, 2610void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, int lock,
2580 struct btrfs_ioctl_balance_args *bargs); 2611 struct btrfs_ioctl_balance_args *bargs);
2581 2612
2582/* 2613/*
@@ -2706,7 +2737,7 @@ do_balance:
2706 2737
2707 if (bargs) { 2738 if (bargs) {
2708 memset(bargs, 0, sizeof(*bargs)); 2739 memset(bargs, 0, sizeof(*bargs));
2709 update_ioctl_balance_args(fs_info, bargs); 2740 update_ioctl_balance_args(fs_info, 0, bargs);
2710 } 2741 }
2711 2742
2712 if ((ret && ret != -ECANCELED && ret != -ENOSPC) || 2743 if ((ret && ret != -ECANCELED && ret != -ENOSPC) ||