aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-11-14 03:06:25 -0500
committerMiao Xie <miaox@cn.fujitsu.com>2014-12-02 21:18:46 -0500
commit2c8cdd6ee4e7f637b0486c6798117e7859dee586 (patch)
treeae10c7af5f98e4b60d55676b8d59b8b543980ae8 /fs/btrfs/volumes.c
parent5a6ac9eacb49143cbad3bbfda72263101cb1f3df (diff)
Btrfs, replace: write dirty pages into the replace target device
The implementation is simple: - In order to avoid changing the code logic of btrfs_map_bio and RAID56, we add the stripes of the replace target devices at the end of the stripe array in btrfs bio, and we sort those target device stripes in the array. And we keep the number of the target device stripes in the btrfs bio. - Except write operation on RAID56, all the other operation don't take the target device stripes into account. - When we do write operation, we read the data from the common devices and calculate the parity. Then write the dirty data and new parity out, at this time, we will find the relative replace target stripes and wirte the relative data into it. Note: The function that copying old data on the source device to the target device was implemented in the past, it is similar to the other RAID type. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 217c42ea90b0..6d8a5e8d8c39 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4881,13 +4881,15 @@ static inline int parity_smaller(u64 a, u64 b)
4881static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map) 4881static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map)
4882{ 4882{
4883 struct btrfs_bio_stripe s; 4883 struct btrfs_bio_stripe s;
4884 int real_stripes = bbio->num_stripes - bbio->num_tgtdevs;
4884 int i; 4885 int i;
4885 u64 l; 4886 u64 l;
4886 int again = 1; 4887 int again = 1;
4888 int m;
4887 4889
4888 while (again) { 4890 while (again) {
4889 again = 0; 4891 again = 0;
4890 for (i = 0; i < bbio->num_stripes - 1; i++) { 4892 for (i = 0; i < real_stripes - 1; i++) {
4891 if (parity_smaller(raid_map[i], raid_map[i+1])) { 4893 if (parity_smaller(raid_map[i], raid_map[i+1])) {
4892 s = bbio->stripes[i]; 4894 s = bbio->stripes[i];
4893 l = raid_map[i]; 4895 l = raid_map[i];
@@ -4895,6 +4897,14 @@ static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map)
4895 raid_map[i] = raid_map[i+1]; 4897 raid_map[i] = raid_map[i+1];
4896 bbio->stripes[i+1] = s; 4898 bbio->stripes[i+1] = s;
4897 raid_map[i+1] = l; 4899 raid_map[i+1] = l;
4900
4901 if (bbio->tgtdev_map) {
4902 m = bbio->tgtdev_map[i];
4903 bbio->tgtdev_map[i] =
4904 bbio->tgtdev_map[i + 1];
4905 bbio->tgtdev_map[i + 1] = m;
4906 }
4907
4898 again = 1; 4908 again = 1;
4899 } 4909 }
4900 } 4910 }
@@ -4923,6 +4933,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4923 int ret = 0; 4933 int ret = 0;
4924 int num_stripes; 4934 int num_stripes;
4925 int max_errors = 0; 4935 int max_errors = 0;
4936 int tgtdev_indexes = 0;
4926 struct btrfs_bio *bbio = NULL; 4937 struct btrfs_bio *bbio = NULL;
4927 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; 4938 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
4928 int dev_replace_is_ongoing = 0; 4939 int dev_replace_is_ongoing = 0;
@@ -5234,14 +5245,19 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5234 num_alloc_stripes <<= 1; 5245 num_alloc_stripes <<= 1;
5235 if (rw & REQ_GET_READ_MIRRORS) 5246 if (rw & REQ_GET_READ_MIRRORS)
5236 num_alloc_stripes++; 5247 num_alloc_stripes++;
5248 tgtdev_indexes = num_stripes;
5237 } 5249 }
5238 bbio = kzalloc(btrfs_bio_size(num_alloc_stripes), GFP_NOFS); 5250
5251 bbio = kzalloc(btrfs_bio_size(num_alloc_stripes, tgtdev_indexes),
5252 GFP_NOFS);
5239 if (!bbio) { 5253 if (!bbio) {
5240 kfree(raid_map); 5254 kfree(raid_map);
5241 ret = -ENOMEM; 5255 ret = -ENOMEM;
5242 goto out; 5256 goto out;
5243 } 5257 }
5244 atomic_set(&bbio->error, 0); 5258 atomic_set(&bbio->error, 0);
5259 if (dev_replace_is_ongoing)
5260 bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes);
5245 5261
5246 if (rw & REQ_DISCARD) { 5262 if (rw & REQ_DISCARD) {
5247 int factor = 0; 5263 int factor = 0;
@@ -5326,6 +5342,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5326 if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) 5342 if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS))
5327 max_errors = btrfs_chunk_max_errors(map); 5343 max_errors = btrfs_chunk_max_errors(map);
5328 5344
5345 tgtdev_indexes = 0;
5329 if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) && 5346 if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) &&
5330 dev_replace->tgtdev != NULL) { 5347 dev_replace->tgtdev != NULL) {
5331 int index_where_to_add; 5348 int index_where_to_add;
@@ -5354,8 +5371,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5354 new->physical = old->physical; 5371 new->physical = old->physical;
5355 new->length = old->length; 5372 new->length = old->length;
5356 new->dev = dev_replace->tgtdev; 5373 new->dev = dev_replace->tgtdev;
5374 bbio->tgtdev_map[i] = index_where_to_add;
5357 index_where_to_add++; 5375 index_where_to_add++;
5358 max_errors++; 5376 max_errors++;
5377 tgtdev_indexes++;
5359 } 5378 }
5360 } 5379 }
5361 num_stripes = index_where_to_add; 5380 num_stripes = index_where_to_add;
@@ -5401,7 +5420,9 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5401 tgtdev_stripe->length = 5420 tgtdev_stripe->length =
5402 bbio->stripes[index_srcdev].length; 5421 bbio->stripes[index_srcdev].length;
5403 tgtdev_stripe->dev = dev_replace->tgtdev; 5422 tgtdev_stripe->dev = dev_replace->tgtdev;
5423 bbio->tgtdev_map[index_srcdev] = num_stripes;
5404 5424
5425 tgtdev_indexes++;
5405 num_stripes++; 5426 num_stripes++;
5406 } 5427 }
5407 } 5428 }
@@ -5411,6 +5432,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5411 bbio->num_stripes = num_stripes; 5432 bbio->num_stripes = num_stripes;
5412 bbio->max_errors = max_errors; 5433 bbio->max_errors = max_errors;
5413 bbio->mirror_num = mirror_num; 5434 bbio->mirror_num = mirror_num;
5435 bbio->num_tgtdevs = tgtdev_indexes;
5414 5436
5415 /* 5437 /*
5416 * this is the case that REQ_READ && dev_replace_is_ongoing && 5438 * this is the case that REQ_READ && dev_replace_is_ongoing &&