aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-11-14 04:45:42 -0500
committerMiao Xie <miaox@cn.fujitsu.com>2014-12-02 21:18:46 -0500
commit7603597690147a16b5cc77047d7570fa22a22673 (patch)
tree6fc1618acba90230ea06986eee104c962475795a
parent2c8cdd6ee4e7f637b0486c6798117e7859dee586 (diff)
Btrfs, replace: write raid56 parity into the replace target device
This function reused the code of parity scrub, and we just write the right parity or corrected parity into the target device before the parity scrub end. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
-rw-r--r--fs/btrfs/raid56.c23
-rw-r--r--fs/btrfs/scrub.c2
2 files changed, 24 insertions, 1 deletions
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index 89a8486c34b3..5ece565bc5f0 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -2318,7 +2318,9 @@ static void raid_write_parity_end_io(struct bio *bio, int err)
2318static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, 2318static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
2319 int need_check) 2319 int need_check)
2320{ 2320{
2321 struct btrfs_bio *bbio = rbio->bbio;
2321 void *pointers[rbio->real_stripes]; 2322 void *pointers[rbio->real_stripes];
2323 DECLARE_BITMAP(pbitmap, rbio->stripe_npages);
2322 int nr_data = rbio->nr_data; 2324 int nr_data = rbio->nr_data;
2323 int stripe; 2325 int stripe;
2324 int pagenr; 2326 int pagenr;
@@ -2328,6 +2330,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
2328 struct page *q_page = NULL; 2330 struct page *q_page = NULL;
2329 struct bio_list bio_list; 2331 struct bio_list bio_list;
2330 struct bio *bio; 2332 struct bio *bio;
2333 int is_replace = 0;
2331 int ret; 2334 int ret;
2332 2335
2333 bio_list_init(&bio_list); 2336 bio_list_init(&bio_list);
@@ -2341,6 +2344,11 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
2341 BUG(); 2344 BUG();
2342 } 2345 }
2343 2346
2347 if (bbio->num_tgtdevs && bbio->tgtdev_map[rbio->scrubp]) {
2348 is_replace = 1;
2349 bitmap_copy(pbitmap, rbio->dbitmap, rbio->stripe_npages);
2350 }
2351
2344 /* 2352 /*
2345 * Because the higher layers(scrubber) are unlikely to 2353 * Because the higher layers(scrubber) are unlikely to
2346 * use this area of the disk again soon, so don't cache 2354 * use this area of the disk again soon, so don't cache
@@ -2429,6 +2437,21 @@ writeback:
2429 goto cleanup; 2437 goto cleanup;
2430 } 2438 }
2431 2439
2440 if (!is_replace)
2441 goto submit_write;
2442
2443 for_each_set_bit(pagenr, pbitmap, rbio->stripe_npages) {
2444 struct page *page;
2445
2446 page = rbio_stripe_page(rbio, rbio->scrubp, pagenr);
2447 ret = rbio_add_io_page(rbio, &bio_list, page,
2448 bbio->tgtdev_map[rbio->scrubp],
2449 pagenr, rbio->stripe_len);
2450 if (ret)
2451 goto cleanup;
2452 }
2453
2454submit_write:
2432 nr_data = bio_list_size(&bio_list); 2455 nr_data = bio_list_size(&bio_list);
2433 if (!nr_data) { 2456 if (!nr_data) {
2434 /* Every parity is right */ 2457 /* Every parity is right */
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 7f95afcf9fd3..0ae837fd676d 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -2714,7 +2714,7 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
2714 goto out; 2714 goto out;
2715 2715
2716 length = sparity->logic_end - sparity->logic_start + 1; 2716 length = sparity->logic_end - sparity->logic_start + 1;
2717 ret = btrfs_map_sblock(sctx->dev_root->fs_info, REQ_GET_READ_MIRRORS, 2717 ret = btrfs_map_sblock(sctx->dev_root->fs_info, WRITE,
2718 sparity->logic_start, 2718 sparity->logic_start,
2719 &length, &bbio, 0, &raid_map); 2719 &length, &bbio, 0, &raid_map);
2720 if (ret || !bbio || !raid_map) 2720 if (ret || !bbio || !raid_map)