aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c1
-rw-r--r--fs/btrfs/ioctl.c4
-rw-r--r--fs/btrfs/ioctl.h2
-rw-r--r--fs/btrfs/volumes.c47
-rw-r--r--fs/btrfs/volumes.h1
6 files changed, 53 insertions, 3 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 1afda75d5414..dfc136cc07d7 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1216,6 +1216,7 @@ struct btrfs_fs_info {
1216 struct mutex balance_mutex; 1216 struct mutex balance_mutex;
1217 atomic_t balance_running; 1217 atomic_t balance_running;
1218 atomic_t balance_pause_req; 1218 atomic_t balance_pause_req;
1219 atomic_t balance_cancel_req;
1219 struct btrfs_balance_control *balance_ctl; 1220 struct btrfs_balance_control *balance_ctl;
1220 wait_queue_head_t balance_wait_q; 1221 wait_queue_head_t balance_wait_q;
1221 1222
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 8ce837407800..c23b82d8ec08 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2006,6 +2006,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
2006 mutex_init(&fs_info->balance_mutex); 2006 mutex_init(&fs_info->balance_mutex);
2007 atomic_set(&fs_info->balance_running, 0); 2007 atomic_set(&fs_info->balance_running, 0);
2008 atomic_set(&fs_info->balance_pause_req, 0); 2008 atomic_set(&fs_info->balance_pause_req, 0);
2009 atomic_set(&fs_info->balance_cancel_req, 0);
2009 fs_info->balance_ctl = NULL; 2010 fs_info->balance_ctl = NULL;
2010 init_waitqueue_head(&fs_info->balance_wait_q); 2011 init_waitqueue_head(&fs_info->balance_wait_q);
2011 2012
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f572c53dda4f..60852217ce9a 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3076,6 +3076,8 @@ void update_ioctl_balance_args(struct btrfs_fs_info *fs_info,
3076 bargs->state |= BTRFS_BALANCE_STATE_RUNNING; 3076 bargs->state |= BTRFS_BALANCE_STATE_RUNNING;
3077 if (atomic_read(&fs_info->balance_pause_req)) 3077 if (atomic_read(&fs_info->balance_pause_req))
3078 bargs->state |= BTRFS_BALANCE_STATE_PAUSE_REQ; 3078 bargs->state |= BTRFS_BALANCE_STATE_PAUSE_REQ;
3079 if (atomic_read(&fs_info->balance_cancel_req))
3080 bargs->state |= BTRFS_BALANCE_STATE_CANCEL_REQ;
3079 3081
3080 memcpy(&bargs->data, &bctl->data, sizeof(bargs->data)); 3082 memcpy(&bargs->data, &bctl->data, sizeof(bargs->data));
3081 memcpy(&bargs->meta, &bctl->meta, sizeof(bargs->meta)); 3083 memcpy(&bargs->meta, &bctl->meta, sizeof(bargs->meta));
@@ -3157,6 +3159,8 @@ static long btrfs_ioctl_balance_ctl(struct btrfs_root *root, int cmd)
3157 switch (cmd) { 3159 switch (cmd) {
3158 case BTRFS_BALANCE_CTL_PAUSE: 3160 case BTRFS_BALANCE_CTL_PAUSE:
3159 return btrfs_pause_balance(root->fs_info); 3161 return btrfs_pause_balance(root->fs_info);
3162 case BTRFS_BALANCE_CTL_CANCEL:
3163 return btrfs_cancel_balance(root->fs_info);
3160 } 3164 }
3161 3165
3162 return -EINVAL; 3166 return -EINVAL;
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index e972e11a8d77..cd19d10794b9 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -111,6 +111,7 @@ struct btrfs_ioctl_fs_info_args {
111 111
112/* balance control ioctl modes */ 112/* balance control ioctl modes */
113#define BTRFS_BALANCE_CTL_PAUSE 1 113#define BTRFS_BALANCE_CTL_PAUSE 1
114#define BTRFS_BALANCE_CTL_CANCEL 2
114 115
115/* 116/*
116 * this is packed, because it should be exactly the same as its disk 117 * this is packed, because it should be exactly the same as its disk
@@ -142,6 +143,7 @@ struct btrfs_balance_progress {
142 143
143#define BTRFS_BALANCE_STATE_RUNNING (1ULL << 0) 144#define BTRFS_BALANCE_STATE_RUNNING (1ULL << 0)
144#define BTRFS_BALANCE_STATE_PAUSE_REQ (1ULL << 1) 145#define BTRFS_BALANCE_STATE_PAUSE_REQ (1ULL << 1)
146#define BTRFS_BALANCE_STATE_CANCEL_REQ (1ULL << 2)
145 147
146struct btrfs_ioctl_balance_args { 148struct btrfs_ioctl_balance_args {
147 __u64 flags; /* in/out */ 149 __u64 flags; /* in/out */
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.
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 80953afb12b9..caa9abd218ef 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -274,6 +274,7 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
274 struct btrfs_ioctl_balance_args *bargs); 274 struct btrfs_ioctl_balance_args *bargs);
275int btrfs_recover_balance(struct btrfs_root *tree_root); 275int btrfs_recover_balance(struct btrfs_root *tree_root);
276int btrfs_pause_balance(struct btrfs_fs_info *fs_info); 276int btrfs_pause_balance(struct btrfs_fs_info *fs_info);
277int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);
277int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); 278int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);
278int find_free_dev_extent(struct btrfs_trans_handle *trans, 279int find_free_dev_extent(struct btrfs_trans_handle *trans,
279 struct btrfs_device *device, u64 num_bytes, 280 struct btrfs_device *device, u64 num_bytes,