diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2012-01-16 15:04:49 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2012-01-16 15:04:49 -0500 |
commit | 19a39dce3b9bf0244d19a446718ad6f7605ff099 (patch) | |
tree | 4834e177b8b64405aa858bfdcfbabd890277102b /fs/btrfs/volumes.c | |
parent | de322263d3a6d4ffd4ed7c4d0c6536e9497aec9b (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.c | 39 |
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 | ||
2442 | static int __btrfs_balance(struct btrfs_fs_info *fs_info) | 2442 | static 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); | ||
2497 | again: | ||
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 | } | ||
2546 | loop: | 2572 | loop: |
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 | } | ||
2550 | error: | 2581 | error: |
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 | ||
2579 | void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, | 2610 | void 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) || |