Skip to content

Commit 63d871c

Browse files
committed
Merge tag 'md/3.17-fixes' of git://neil.brown.name/md
Pull md bugfixes from Neil Brown: "Here are the bug-fixes I promised :-) Funny how you start looking for one and other start appearing. - raid6 data corruption during recovery - raid6 livelock - raid10 memory leaks" * tag 'md/3.17-fixes' of git://neil.brown.name/md: md/raid10: always initialise ->state on newly allocated r10_bio md/raid10: avoid memory leak on error path during reshape. md/raid10: Fix memory leak when raid10 reshape completes. md/raid10: fix memory leak when reshaping a RAID10. md/raid6: avoid data corruption during recovery of double-degraded RAID6 md/raid5: avoid livelock caused by non-aligned writes.
2 parents f17a6f7 + cb8b12b commit 63d871c

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

drivers/md/raid10.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2953,6 +2953,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
29532953
*/
29542954
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
29552955
end_reshape(conf);
2956+
close_sync(conf);
29562957
return 0;
29572958
}
29582959

@@ -3081,6 +3082,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
30813082
}
30823083

30833084
r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
3085+
r10_bio->state = 0;
30843086
raise_barrier(conf, rb2 != NULL);
30853087
atomic_set(&r10_bio->remaining, 0);
30863088

@@ -3269,6 +3271,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
32693271
if (sync_blocks < max_sync)
32703272
max_sync = sync_blocks;
32713273
r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
3274+
r10_bio->state = 0;
32723275

32733276
r10_bio->mddev = mddev;
32743277
atomic_set(&r10_bio->remaining, 0);
@@ -4384,6 +4387,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
43844387
read_more:
43854388
/* Now schedule reads for blocks from sector_nr to last */
43864389
r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
4390+
r10_bio->state = 0;
43874391
raise_barrier(conf, sectors_done != 0);
43884392
atomic_set(&r10_bio->remaining, 0);
43894393
r10_bio->mddev = mddev;
@@ -4398,6 +4402,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
43984402
* on all the target devices.
43994403
*/
44004404
// FIXME
4405+
mempool_free(r10_bio, conf->r10buf_pool);
44014406
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
44024407
return sectors_done;
44034408
}
@@ -4410,7 +4415,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
44104415
read_bio->bi_private = r10_bio;
44114416
read_bio->bi_end_io = end_sync_read;
44124417
read_bio->bi_rw = READ;
4413-
read_bio->bi_flags &= ~(BIO_POOL_MASK - 1);
4418+
read_bio->bi_flags &= (~0UL << BIO_RESET_BITS);
44144419
read_bio->bi_flags |= 1 << BIO_UPTODATE;
44154420
read_bio->bi_vcnt = 0;
44164421
read_bio->bi_iter.bi_size = 0;

drivers/md/raid5.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2922,7 +2922,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s,
29222922
(!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) &&
29232923
!test_bit(R5_OVERWRITE, &fdev[0]->flags)) ||
29242924
(sh->raid_conf->level == 6 && s->failed && s->to_write &&
2925-
s->to_write < sh->raid_conf->raid_disks - 2 &&
2925+
s->to_write - s->non_overwrite < sh->raid_conf->raid_disks - 2 &&
29262926
(!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) {
29272927
/* we would like to get this block, possibly by computing it,
29282928
* otherwise read it if the backing disk is insync
@@ -3817,6 +3817,8 @@ static void handle_stripe(struct stripe_head *sh)
38173817
set_bit(R5_Wantwrite, &dev->flags);
38183818
if (prexor)
38193819
continue;
3820+
if (s.failed > 1)
3821+
continue;
38203822
if (!test_bit(R5_Insync, &dev->flags) ||
38213823
((i == sh->pd_idx || i == sh->qd_idx) &&
38223824
s.failed == 0))

0 commit comments

Comments
 (0)