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
commita7e99c691af553fc15ac46a51f130b7c59a65f76 (patch)
tree55491f285683951d509819a66e614ac6f12659dd /fs/btrfs/volumes.c
parent837d5b6e46d1a4af5b6cc8f2fe83cb5de79a2961 (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.c47
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
2561static inline int balance_need_close(struct btrfs_fs_info *fs_info) 2562static 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
2566static void __cancel_balance(struct btrfs_fs_info *fs_info) 2570static 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
2840int 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.