Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

md: raid1/raid10: initialize bvec table via bio_add_page()

We will support multipage bvec soon, so initialize bvec
table using the standardy way instead of writing the
talbe directly. Otherwise it won't work any more once
multipage bvec is enabled.

Acked-by: Guoqing Jiang <gqjiang@suse.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Shaohua Li <shli@fb.com>

authored by

Ming Lei and committed by
Shaohua Li
fb0eb5df 022e510f

+27 -16
+19
drivers/md/raid1-10.c
··· 1 + /* generally called after bio_reset() for reseting bvec */ 2 + static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp, 3 + int size) 4 + { 5 + int idx = 0; 6 + 7 + /* initialize bvec table again */ 8 + do { 9 + struct page *page = resync_fetch_page(rp, idx); 10 + int len = min_t(int, size, PAGE_SIZE); 11 + 12 + /* 13 + * won't fail because the vec table is big 14 + * enough to hold all these pages 15 + */ 16 + bio_add_page(bio, page, len, 0); 17 + size -= len; 18 + } while (idx++ < RESYNC_PAGES && size > 0); 19 + }
+4 -14
drivers/md/raid1.c
··· 81 81 #define raid1_log(md, fmt, args...) \ 82 82 do { if ((md)->queue) blk_add_trace_msg((md)->queue, "raid1 " fmt, ##args); } while (0) 83 83 84 + #include "raid1-10.c" 85 + 84 86 /* 85 87 * 'strct resync_pages' stores actual pages used for doing the resync 86 88 * IO, and it is per-bio, so make .bi_private points to it. ··· 2087 2085 /* Fix variable parts of all bios */ 2088 2086 vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9); 2089 2087 for (i = 0; i < conf->raid_disks * 2; i++) { 2090 - int j; 2091 - int size; 2092 2088 blk_status_t status; 2093 - struct bio_vec *bi; 2094 2089 struct bio *b = r1_bio->bios[i]; 2095 2090 struct resync_pages *rp = get_resync_pages(b); 2096 2091 if (b->bi_end_io != end_sync_read) ··· 2096 2097 status = b->bi_status; 2097 2098 bio_reset(b); 2098 2099 b->bi_status = status; 2099 - b->bi_vcnt = vcnt; 2100 - b->bi_iter.bi_size = r1_bio->sectors << 9; 2101 2100 b->bi_iter.bi_sector = r1_bio->sector + 2102 2101 conf->mirrors[i].rdev->data_offset; 2103 2102 b->bi_bdev = conf->mirrors[i].rdev->bdev; ··· 2103 2106 rp->raid_bio = r1_bio; 2104 2107 b->bi_private = rp; 2105 2108 2106 - size = b->bi_iter.bi_size; 2107 - bio_for_each_segment_all(bi, b, j) { 2108 - bi->bv_offset = 0; 2109 - if (size > PAGE_SIZE) 2110 - bi->bv_len = PAGE_SIZE; 2111 - else 2112 - bi->bv_len = size; 2113 - size -= PAGE_SIZE; 2114 - } 2109 + /* initialize bvec table again */ 2110 + md_bio_reset_resync_pages(b, rp, r1_bio->sectors << 9); 2115 2111 } 2116 2112 for (primary = 0; primary < conf->raid_disks * 2; primary++) 2117 2113 if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
+4 -2
drivers/md/raid10.c
··· 110 110 #define raid10_log(md, fmt, args...) \ 111 111 do { if ((md)->queue) blk_add_trace_msg((md)->queue, "raid10 " fmt, ##args); } while (0) 112 112 113 + #include "raid1-10.c" 114 + 113 115 /* 114 116 * 'strct resync_pages' stores actual pages used for doing the resync 115 117 * IO, and it is per-bio, so make .bi_private points to it. ··· 2088 2086 rp = get_resync_pages(tbio); 2089 2087 bio_reset(tbio); 2090 2088 2091 - tbio->bi_vcnt = vcnt; 2092 - tbio->bi_iter.bi_size = fbio->bi_iter.bi_size; 2089 + md_bio_reset_resync_pages(tbio, rp, fbio->bi_iter.bi_size); 2090 + 2093 2091 rp->raid_bio = r10_bio; 2094 2092 tbio->bi_private = rp; 2095 2093 tbio->bi_iter.bi_sector = r10_bio->devs[i].addr;