aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid1.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-27 21:32:10 -0400
committerNeilBrown <neilb@suse.de>2011-07-27 21:32:10 -0400
commit2ca68f5ed7383733102ee53cd8fa4021ecc3b275 (patch)
tree29543cff802770d90380b889cf8b0cc01e7d1814 /drivers/md/raid1.c
parent4367af556133723d0f443e14ca8170d9447317cb (diff)
md/raid1: store behind-write pages in bi_vecs.
When performing write-behind we allocate pages to store the data during write. Previously we just keep a list of pages. Now we keep a list of bi_vec which includes offset and size. This means that the r1bio has complete information to create a new bio which will be needed for retrying after write errors. Signed-off-by: NeilBrown <neilb@suse.de> Reviewed-by: Namhyung Kim <namhyung@gmail.com>
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r--drivers/md/raid1.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 141de75a6c7c..b16d2ee5e9dd 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -327,9 +327,9 @@ static void r1_bio_write_done(r1bio_t *r1_bio)
327 /* free extra copy of the data pages */ 327 /* free extra copy of the data pages */
328 int i = r1_bio->behind_page_count; 328 int i = r1_bio->behind_page_count;
329 while (i--) 329 while (i--)
330 safe_put_page(r1_bio->behind_pages[i]); 330 safe_put_page(r1_bio->behind_bvecs[i].bv_page);
331 kfree(r1_bio->behind_pages); 331 kfree(r1_bio->behind_bvecs);
332 r1_bio->behind_pages = NULL; 332 r1_bio->behind_bvecs = NULL;
333 } 333 }
334 /* clear the bitmap if all writes complete successfully */ 334 /* clear the bitmap if all writes complete successfully */
335 bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector, 335 bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
@@ -748,30 +748,31 @@ static void alloc_behind_pages(struct bio *bio, r1bio_t *r1_bio)
748{ 748{
749 int i; 749 int i;
750 struct bio_vec *bvec; 750 struct bio_vec *bvec;
751 struct page **pages = kzalloc(bio->bi_vcnt * sizeof(struct page*), 751 struct bio_vec *bvecs = kzalloc(bio->bi_vcnt * sizeof(struct bio_vec),
752 GFP_NOIO); 752 GFP_NOIO);
753 if (unlikely(!pages)) 753 if (unlikely(!bvecs))
754 return; 754 return;
755 755
756 bio_for_each_segment(bvec, bio, i) { 756 bio_for_each_segment(bvec, bio, i) {
757 pages[i] = alloc_page(GFP_NOIO); 757 bvecs[i] = *bvec;
758 if (unlikely(!pages[i])) 758 bvecs[i].bv_page = alloc_page(GFP_NOIO);
759 if (unlikely(!bvecs[i].bv_page))
759 goto do_sync_io; 760 goto do_sync_io;
760 memcpy(kmap(pages[i]) + bvec->bv_offset, 761 memcpy(kmap(bvecs[i].bv_page) + bvec->bv_offset,
761 kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len); 762 kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len);
762 kunmap(pages[i]); 763 kunmap(bvecs[i].bv_page);
763 kunmap(bvec->bv_page); 764 kunmap(bvec->bv_page);
764 } 765 }
765 r1_bio->behind_pages = pages; 766 r1_bio->behind_bvecs = bvecs;
766 r1_bio->behind_page_count = bio->bi_vcnt; 767 r1_bio->behind_page_count = bio->bi_vcnt;
767 set_bit(R1BIO_BehindIO, &r1_bio->state); 768 set_bit(R1BIO_BehindIO, &r1_bio->state);
768 return; 769 return;
769 770
770do_sync_io: 771do_sync_io:
771 for (i = 0; i < bio->bi_vcnt; i++) 772 for (i = 0; i < bio->bi_vcnt; i++)
772 if (pages[i]) 773 if (bvecs[i].bv_page)
773 put_page(pages[i]); 774 put_page(bvecs[i].bv_page);
774 kfree(pages); 775 kfree(bvecs);
775 PRINTK("%dB behind alloc failed, doing sync I/O\n", bio->bi_size); 776 PRINTK("%dB behind alloc failed, doing sync I/O\n", bio->bi_size);
776} 777}
777 778
@@ -1058,7 +1059,7 @@ read_again:
1058 &r1_bio->state)); 1059 &r1_bio->state));
1059 first_clone = 0; 1060 first_clone = 0;
1060 } 1061 }
1061 if (r1_bio->behind_pages) { 1062 if (r1_bio->behind_bvecs) {
1062 struct bio_vec *bvec; 1063 struct bio_vec *bvec;
1063 int j; 1064 int j;
1064 1065
@@ -1070,7 +1071,7 @@ read_again:
1070 * them all 1071 * them all
1071 */ 1072 */
1072 __bio_for_each_segment(bvec, mbio, j, 0) 1073 __bio_for_each_segment(bvec, mbio, j, 0)
1073 bvec->bv_page = r1_bio->behind_pages[j]; 1074 bvec->bv_page = r1_bio->behind_bvecs[j].bv_page;
1074 if (test_bit(WriteMostly, &conf->mirrors[i].rdev->flags)) 1075 if (test_bit(WriteMostly, &conf->mirrors[i].rdev->flags))
1075 atomic_inc(&r1_bio->behind_remaining); 1076 atomic_inc(&r1_bio->behind_remaining);
1076 } 1077 }