瀏覽代碼

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>
Miao Xie 10 年之前
父節點
當前提交
7603597690
共有 2 個文件被更改,包括 24 次插入1 次删除
  1. 23 0
      fs/btrfs/raid56.c
  2. 1 1
      fs/btrfs/scrub.c

+ 23 - 0
fs/btrfs/raid56.c

@@ -2318,7 +2318,9 @@ static void raid_write_parity_end_io(struct bio *bio, int err)
 static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
 static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
 					 int need_check)
 					 int need_check)
 {
 {
+	struct btrfs_bio *bbio = rbio->bbio;
 	void *pointers[rbio->real_stripes];
 	void *pointers[rbio->real_stripes];
+	DECLARE_BITMAP(pbitmap, rbio->stripe_npages);
 	int nr_data = rbio->nr_data;
 	int nr_data = rbio->nr_data;
 	int stripe;
 	int stripe;
 	int pagenr;
 	int pagenr;
@@ -2328,6 +2330,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
 	struct page *q_page = NULL;
 	struct page *q_page = NULL;
 	struct bio_list bio_list;
 	struct bio_list bio_list;
 	struct bio *bio;
 	struct bio *bio;
+	int is_replace = 0;
 	int ret;
 	int ret;
 
 
 	bio_list_init(&bio_list);
 	bio_list_init(&bio_list);
@@ -2341,6 +2344,11 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
 		BUG();
 		BUG();
 	}
 	}
 
 
+	if (bbio->num_tgtdevs && bbio->tgtdev_map[rbio->scrubp]) {
+		is_replace = 1;
+		bitmap_copy(pbitmap, rbio->dbitmap, rbio->stripe_npages);
+	}
+
 	/*
 	/*
 	 * Because the higher layers(scrubber) are unlikely to
 	 * Because the higher layers(scrubber) are unlikely to
 	 * use this area of the disk again soon, so don't cache
 	 * use this area of the disk again soon, so don't cache
@@ -2429,6 +2437,21 @@ writeback:
 			goto cleanup;
 			goto cleanup;
 	}
 	}
 
 
+	if (!is_replace)
+		goto submit_write;
+
+	for_each_set_bit(pagenr, pbitmap, rbio->stripe_npages) {
+		struct page *page;
+
+		page = rbio_stripe_page(rbio, rbio->scrubp, pagenr);
+		ret = rbio_add_io_page(rbio, &bio_list, page,
+				       bbio->tgtdev_map[rbio->scrubp],
+				       pagenr, rbio->stripe_len);
+		if (ret)
+			goto cleanup;
+	}
+
+submit_write:
 	nr_data = bio_list_size(&bio_list);
 	nr_data = bio_list_size(&bio_list);
 	if (!nr_data) {
 	if (!nr_data) {
 		/* Every parity is right */
 		/* Every parity is right */

+ 1 - 1
fs/btrfs/scrub.c

@@ -2714,7 +2714,7 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
 		goto out;
 		goto out;
 
 
 	length = sparity->logic_end - sparity->logic_start + 1;
 	length = sparity->logic_end - sparity->logic_start + 1;
-	ret = btrfs_map_sblock(sctx->dev_root->fs_info, REQ_GET_READ_MIRRORS,
+	ret = btrfs_map_sblock(sctx->dev_root->fs_info, WRITE,
 			       sparity->logic_start,
 			       sparity->logic_start,
 			       &length, &bbio, 0, &raid_map);
 			       &length, &bbio, 0, &raid_map);
 	if (ret || !bbio || !raid_map)
 	if (ret || !bbio || !raid_map)