diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-19 10:47:01 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-19 10:47:01 -0400 |
| commit | 63d871cb0b9e4207044ced0322aa34d859fa463d (patch) | |
| tree | 4bd71a2c1fd5151c7d7186aaabaa410b9d786929 | |
| parent | f17a6f78595e52761b7b2dece8c11b04b65f19dd (diff) | |
| parent | cb8b12b5d81cf8522076f99a90bc3b795825c3b3 (diff) | |
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.
| -rw-r--r-- | drivers/md/raid10.c | 7 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 4 |
2 files changed, 9 insertions, 2 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b08c18871323..6703751d87d7 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -2953,6 +2953,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
| 2953 | */ | 2953 | */ |
| 2954 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { | 2954 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { |
| 2955 | end_reshape(conf); | 2955 | end_reshape(conf); |
| 2956 | close_sync(conf); | ||
| 2956 | return 0; | 2957 | return 0; |
| 2957 | } | 2958 | } |
| 2958 | 2959 | ||
| @@ -3081,6 +3082,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
| 3081 | } | 3082 | } |
| 3082 | 3083 | ||
| 3083 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); | 3084 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); |
| 3085 | r10_bio->state = 0; | ||
| 3084 | raise_barrier(conf, rb2 != NULL); | 3086 | raise_barrier(conf, rb2 != NULL); |
| 3085 | atomic_set(&r10_bio->remaining, 0); | 3087 | atomic_set(&r10_bio->remaining, 0); |
| 3086 | 3088 | ||
| @@ -3269,6 +3271,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
| 3269 | if (sync_blocks < max_sync) | 3271 | if (sync_blocks < max_sync) |
| 3270 | max_sync = sync_blocks; | 3272 | max_sync = sync_blocks; |
| 3271 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); | 3273 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); |
| 3274 | r10_bio->state = 0; | ||
| 3272 | 3275 | ||
| 3273 | r10_bio->mddev = mddev; | 3276 | r10_bio->mddev = mddev; |
| 3274 | atomic_set(&r10_bio->remaining, 0); | 3277 | atomic_set(&r10_bio->remaining, 0); |
| @@ -4384,6 +4387,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, | |||
| 4384 | read_more: | 4387 | read_more: |
| 4385 | /* Now schedule reads for blocks from sector_nr to last */ | 4388 | /* Now schedule reads for blocks from sector_nr to last */ |
| 4386 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); | 4389 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); |
| 4390 | r10_bio->state = 0; | ||
| 4387 | raise_barrier(conf, sectors_done != 0); | 4391 | raise_barrier(conf, sectors_done != 0); |
| 4388 | atomic_set(&r10_bio->remaining, 0); | 4392 | atomic_set(&r10_bio->remaining, 0); |
| 4389 | r10_bio->mddev = mddev; | 4393 | r10_bio->mddev = mddev; |
| @@ -4398,6 +4402,7 @@ read_more: | |||
| 4398 | * on all the target devices. | 4402 | * on all the target devices. |
| 4399 | */ | 4403 | */ |
| 4400 | // FIXME | 4404 | // FIXME |
| 4405 | mempool_free(r10_bio, conf->r10buf_pool); | ||
| 4401 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 4406 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 4402 | return sectors_done; | 4407 | return sectors_done; |
| 4403 | } | 4408 | } |
| @@ -4410,7 +4415,7 @@ read_more: | |||
| 4410 | read_bio->bi_private = r10_bio; | 4415 | read_bio->bi_private = r10_bio; |
| 4411 | read_bio->bi_end_io = end_sync_read; | 4416 | read_bio->bi_end_io = end_sync_read; |
| 4412 | read_bio->bi_rw = READ; | 4417 | read_bio->bi_rw = READ; |
| 4413 | read_bio->bi_flags &= ~(BIO_POOL_MASK - 1); | 4418 | read_bio->bi_flags &= (~0UL << BIO_RESET_BITS); |
| 4414 | read_bio->bi_flags |= 1 << BIO_UPTODATE; | 4419 | read_bio->bi_flags |= 1 << BIO_UPTODATE; |
| 4415 | read_bio->bi_vcnt = 0; | 4420 | read_bio->bi_vcnt = 0; |
| 4416 | read_bio->bi_iter.bi_size = 0; | 4421 | read_bio->bi_iter.bi_size = 0; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 6234b2e84587..183588b11fc1 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -2922,7 +2922,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s, | |||
| 2922 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) && | 2922 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) && |
| 2923 | !test_bit(R5_OVERWRITE, &fdev[0]->flags)) || | 2923 | !test_bit(R5_OVERWRITE, &fdev[0]->flags)) || |
| 2924 | (sh->raid_conf->level == 6 && s->failed && s->to_write && | 2924 | (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 && |
| 2926 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) { | 2926 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) { |
| 2927 | /* we would like to get this block, possibly by computing it, | 2927 | /* we would like to get this block, possibly by computing it, |
| 2928 | * otherwise read it if the backing disk is insync | 2928 | * otherwise read it if the backing disk is insync |
| @@ -3817,6 +3817,8 @@ static void handle_stripe(struct stripe_head *sh) | |||
| 3817 | set_bit(R5_Wantwrite, &dev->flags); | 3817 | set_bit(R5_Wantwrite, &dev->flags); |
| 3818 | if (prexor) | 3818 | if (prexor) |
| 3819 | continue; | 3819 | continue; |
| 3820 | if (s.failed > 1) | ||
| 3821 | continue; | ||
| 3820 | if (!test_bit(R5_Insync, &dev->flags) || | 3822 | if (!test_bit(R5_Insync, &dev->flags) || |
| 3821 | ((i == sh->pd_idx || i == sh->qd_idx) && | 3823 | ((i == sh->pd_idx || i == sh->qd_idx) && |
| 3822 | s.failed == 0)) | 3824 | s.failed == 0)) |
