Skip to content

Commit 208410b

Browse files
committed
md/raid1/10: reset bio allocated from mempool
Data allocated from mempool doesn't always get initialized, this happens when the data is reused instead of fresh allocation. In the raid1/10 case, we must reinitialize the bios. Reported-by: Jonathan G. Underwood <[email protected]> Fixes: f025061(md: raid10: don't use bio's vec table to manage resync pages) Fixes: 98d30c5(md: raid1: don't use bio's vec table to manage resync pages) Cc: [email protected] (4.12+) Cc: Ming Lei <[email protected]> Signed-off-by: Shaohua Li <[email protected]>
1 parent 9c72a18 commit 208410b

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

drivers/md/raid1.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2564,6 +2564,23 @@ static int init_resync(struct r1conf *conf)
25642564
return 0;
25652565
}
25662566

2567+
static struct r1bio *raid1_alloc_init_r1buf(struct r1conf *conf)
2568+
{
2569+
struct r1bio *r1bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO);
2570+
struct resync_pages *rps;
2571+
struct bio *bio;
2572+
int i;
2573+
2574+
for (i = conf->poolinfo->raid_disks; i--; ) {
2575+
bio = r1bio->bios[i];
2576+
rps = bio->bi_private;
2577+
bio_reset(bio);
2578+
bio->bi_private = rps;
2579+
}
2580+
r1bio->master_bio = NULL;
2581+
return r1bio;
2582+
}
2583+
25672584
/*
25682585
* perform a "sync" on one "block"
25692586
*
@@ -2649,7 +2666,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
26492666

26502667
bitmap_cond_end_sync(mddev->bitmap, sector_nr,
26512668
mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
2652-
r1_bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO);
2669+
r1_bio = raid1_alloc_init_r1buf(conf);
26532670

26542671
raise_barrier(conf, sector_nr);
26552672

drivers/md/raid10.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,6 +2798,35 @@ static int init_resync(struct r10conf *conf)
27982798
return 0;
27992799
}
28002800

2801+
static struct r10bio *raid10_alloc_init_r10buf(struct r10conf *conf)
2802+
{
2803+
struct r10bio *r10bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
2804+
struct rsync_pages *rp;
2805+
struct bio *bio;
2806+
int nalloc;
2807+
int i;
2808+
2809+
if (test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery) ||
2810+
test_bit(MD_RECOVERY_RESHAPE, &conf->mddev->recovery))
2811+
nalloc = conf->copies; /* resync */
2812+
else
2813+
nalloc = 2; /* recovery */
2814+
2815+
for (i = 0; i < nalloc; i++) {
2816+
bio = r10bio->devs[i].bio;
2817+
rp = bio->bi_private;
2818+
bio_reset(bio);
2819+
bio->bi_private = rp;
2820+
bio = r10bio->devs[i].repl_bio;
2821+
if (bio) {
2822+
rp = bio->bi_private;
2823+
bio_reset(bio);
2824+
bio->bi_private = rp;
2825+
}
2826+
}
2827+
return r10bio;
2828+
}
2829+
28012830
/*
28022831
* perform a "sync" on one "block"
28032832
*
@@ -3027,7 +3056,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
30273056
atomic_inc(&mreplace->nr_pending);
30283057
rcu_read_unlock();
30293058

3030-
r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
3059+
r10_bio = raid10_alloc_init_r10buf(conf);
30313060
r10_bio->state = 0;
30323061
raise_barrier(conf, rb2 != NULL);
30333062
atomic_set(&r10_bio->remaining, 0);
@@ -3236,7 +3265,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
32363265
}
32373266
if (sync_blocks < max_sync)
32383267
max_sync = sync_blocks;
3239-
r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
3268+
r10_bio = raid10_alloc_init_r10buf(conf);
32403269
r10_bio->state = 0;
32413270

32423271
r10_bio->mddev = mddev;
@@ -4360,7 +4389,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
43604389

43614390
read_more:
43624391
/* Now schedule reads for blocks from sector_nr to last */
4363-
r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
4392+
r10_bio = raid10_alloc_init_r10buf(conf);
43644393
r10_bio->state = 0;
43654394
raise_barrier(conf, sectors_done != 0);
43664395
atomic_set(&r10_bio->remaining, 0);

0 commit comments

Comments
 (0)