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 | a7e99c691af553fc15ac46a51f130b7c59a65f76 (patch) | |
tree | 55491f285683951d509819a66e614ac6f12659dd /fs/btrfs/volumes.c | |
parent | 837d5b6e46d1a4af5b6cc8f2fe83cb5de79a2961 (diff) |
Btrfs: allow for canceling restriper
Implement an ioctl for canceling restriper. Currently we wait until
relocation of the current block group is finished, in future this can be
done by triggering a commit. Balance item is deleted and no memory
about the interrupted balance is kept.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index d32660ce753d..c32667318ae4 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -2492,7 +2492,8 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info) | |||
2492 | key.type = BTRFS_CHUNK_ITEM_KEY; | 2492 | key.type = BTRFS_CHUNK_ITEM_KEY; |
2493 | 2493 | ||
2494 | while (1) { | 2494 | while (1) { |
2495 | if (atomic_read(&fs_info->balance_pause_req)) { | 2495 | if (atomic_read(&fs_info->balance_pause_req) || |
2496 | atomic_read(&fs_info->balance_cancel_req)) { | ||
2496 | ret = -ECANCELED; | 2497 | ret = -ECANCELED; |
2497 | goto error; | 2498 | goto error; |
2498 | } | 2499 | } |
@@ -2560,7 +2561,10 @@ error: | |||
2560 | 2561 | ||
2561 | static inline int balance_need_close(struct btrfs_fs_info *fs_info) | 2562 | static inline int balance_need_close(struct btrfs_fs_info *fs_info) |
2562 | { | 2563 | { |
2563 | return atomic_read(&fs_info->balance_pause_req) == 0; | 2564 | /* cancel requested || normal exit path */ |
2565 | return atomic_read(&fs_info->balance_cancel_req) || | ||
2566 | (atomic_read(&fs_info->balance_pause_req) == 0 && | ||
2567 | atomic_read(&fs_info->balance_cancel_req) == 0); | ||
2564 | } | 2568 | } |
2565 | 2569 | ||
2566 | static void __cancel_balance(struct btrfs_fs_info *fs_info) | 2570 | static void __cancel_balance(struct btrfs_fs_info *fs_info) |
@@ -2586,7 +2590,8 @@ int btrfs_balance(struct btrfs_balance_control *bctl, | |||
2586 | int ret; | 2590 | int ret; |
2587 | 2591 | ||
2588 | if (btrfs_fs_closing(fs_info) || | 2592 | if (btrfs_fs_closing(fs_info) || |
2589 | atomic_read(&fs_info->balance_pause_req)) { | 2593 | atomic_read(&fs_info->balance_pause_req) || |
2594 | atomic_read(&fs_info->balance_cancel_req)) { | ||
2590 | ret = -EINVAL; | 2595 | ret = -EINVAL; |
2591 | goto out; | 2596 | goto out; |
2592 | } | 2597 | } |
@@ -2832,6 +2837,42 @@ int btrfs_pause_balance(struct btrfs_fs_info *fs_info) | |||
2832 | return ret; | 2837 | return ret; |
2833 | } | 2838 | } |
2834 | 2839 | ||
2840 | int btrfs_cancel_balance(struct btrfs_fs_info *fs_info) | ||
2841 | { | ||
2842 | mutex_lock(&fs_info->balance_mutex); | ||
2843 | if (!fs_info->balance_ctl) { | ||
2844 | mutex_unlock(&fs_info->balance_mutex); | ||
2845 | return -ENOTCONN; | ||
2846 | } | ||
2847 | |||
2848 | atomic_inc(&fs_info->balance_cancel_req); | ||
2849 | /* | ||
2850 | * if we are running just wait and return, balance item is | ||
2851 | * deleted in btrfs_balance in this case | ||
2852 | */ | ||
2853 | if (atomic_read(&fs_info->balance_running)) { | ||
2854 | mutex_unlock(&fs_info->balance_mutex); | ||
2855 | wait_event(fs_info->balance_wait_q, | ||
2856 | atomic_read(&fs_info->balance_running) == 0); | ||
2857 | mutex_lock(&fs_info->balance_mutex); | ||
2858 | } else { | ||
2859 | /* __cancel_balance needs volume_mutex */ | ||
2860 | mutex_unlock(&fs_info->balance_mutex); | ||
2861 | mutex_lock(&fs_info->volume_mutex); | ||
2862 | mutex_lock(&fs_info->balance_mutex); | ||
2863 | |||
2864 | if (fs_info->balance_ctl) | ||
2865 | __cancel_balance(fs_info); | ||
2866 | |||
2867 | mutex_unlock(&fs_info->volume_mutex); | ||
2868 | } | ||
2869 | |||
2870 | BUG_ON(fs_info->balance_ctl || atomic_read(&fs_info->balance_running)); | ||
2871 | atomic_dec(&fs_info->balance_cancel_req); | ||
2872 | mutex_unlock(&fs_info->balance_mutex); | ||
2873 | return 0; | ||
2874 | } | ||
2875 | |||
2835 | /* | 2876 | /* |
2836 | * shrinking a device means finding all of the device extents past | 2877 | * shrinking a device means finding all of the device extents past |
2837 | * the new size, and then following the back refs to the chunks. | 2878 | * the new size, and then following the back refs to the chunks. |