Commit c271f5bc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'md/3.11-fixes' of git://neil.brown.name/md

Pull md fixes from Neil Brown:
 "Two more bugfixes for md in 3.11

  Both marked for -stable, both since 3.3.  I guess I should spend more
  time testing..."

* tag 'md/3.11-fixes' of git://neil.brown.name/md:
  md/raid5: fix interaction of 'replace' and 'recovery'.
  md/raid10: remove use-after-free bug.
parents c7dad234 f94c0b66
...@@ -2290,12 +2290,18 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio) ...@@ -2290,12 +2290,18 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
d = r10_bio->devs[1].devnum; d = r10_bio->devs[1].devnum;
wbio = r10_bio->devs[1].bio; wbio = r10_bio->devs[1].bio;
wbio2 = r10_bio->devs[1].repl_bio; wbio2 = r10_bio->devs[1].repl_bio;
/* Need to test wbio2->bi_end_io before we call
* generic_make_request as if the former is NULL,
* the latter is free to free wbio2.
*/
if (wbio2 && !wbio2->bi_end_io)
wbio2 = NULL;
if (wbio->bi_end_io) { if (wbio->bi_end_io) {
atomic_inc(&conf->mirrors[d].rdev->nr_pending); atomic_inc(&conf->mirrors[d].rdev->nr_pending);
md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio)); md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio));
generic_make_request(wbio); generic_make_request(wbio);
} }
if (wbio2 && wbio2->bi_end_io) { if (wbio2) {
atomic_inc(&conf->mirrors[d].replacement->nr_pending); atomic_inc(&conf->mirrors[d].replacement->nr_pending);
md_sync_acct(conf->mirrors[d].replacement->bdev, md_sync_acct(conf->mirrors[d].replacement->bdev,
bio_sectors(wbio2)); bio_sectors(wbio2));
......
...@@ -3462,6 +3462,7 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -3462,6 +3462,7 @@ static void handle_stripe(struct stripe_head *sh)
test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
set_bit(STRIPE_SYNCING, &sh->state); set_bit(STRIPE_SYNCING, &sh->state);
clear_bit(STRIPE_INSYNC, &sh->state); clear_bit(STRIPE_INSYNC, &sh->state);
clear_bit(STRIPE_REPLACED, &sh->state);
} }
spin_unlock(&sh->stripe_lock); spin_unlock(&sh->stripe_lock);
} }
...@@ -3607,19 +3608,23 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -3607,19 +3608,23 @@ static void handle_stripe(struct stripe_head *sh)
handle_parity_checks5(conf, sh, &s, disks); handle_parity_checks5(conf, sh, &s, disks);
} }
if (s.replacing && s.locked == 0 if ((s.replacing || s.syncing) && s.locked == 0
&& !test_bit(STRIPE_INSYNC, &sh->state)) { && !test_bit(STRIPE_COMPUTE_RUN, &sh->state)
&& !test_bit(STRIPE_REPLACED, &sh->state)) {
/* Write out to replacement devices where possible */ /* Write out to replacement devices where possible */
for (i = 0; i < conf->raid_disks; i++) for (i = 0; i < conf->raid_disks; i++)
if (test_bit(R5_UPTODATE, &sh->dev[i].flags) && if (test_bit(R5_NeedReplace, &sh->dev[i].flags)) {
test_bit(R5_NeedReplace, &sh->dev[i].flags)) { WARN_ON(!test_bit(R5_UPTODATE, &sh->dev[i].flags));
set_bit(R5_WantReplace, &sh->dev[i].flags); set_bit(R5_WantReplace, &sh->dev[i].flags);
set_bit(R5_LOCKED, &sh->dev[i].flags); set_bit(R5_LOCKED, &sh->dev[i].flags);
s.locked++; s.locked++;
} }
set_bit(STRIPE_INSYNC, &sh->state); if (s.replacing)
set_bit(STRIPE_INSYNC, &sh->state);
set_bit(STRIPE_REPLACED, &sh->state);
} }
if ((s.syncing || s.replacing) && s.locked == 0 && if ((s.syncing || s.replacing) && s.locked == 0 &&
!test_bit(STRIPE_COMPUTE_RUN, &sh->state) &&
test_bit(STRIPE_INSYNC, &sh->state)) { test_bit(STRIPE_INSYNC, &sh->state)) {
md_done_sync(conf->mddev, STRIPE_SECTORS, 1); md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
clear_bit(STRIPE_SYNCING, &sh->state); clear_bit(STRIPE_SYNCING, &sh->state);
......
...@@ -306,6 +306,7 @@ enum { ...@@ -306,6 +306,7 @@ enum {
STRIPE_SYNC_REQUESTED, STRIPE_SYNC_REQUESTED,
STRIPE_SYNCING, STRIPE_SYNCING,
STRIPE_INSYNC, STRIPE_INSYNC,
STRIPE_REPLACED,
STRIPE_PREREAD_ACTIVE, STRIPE_PREREAD_ACTIVE,
STRIPE_DELAYED, STRIPE_DELAYED,
STRIPE_DEGRADED, STRIPE_DEGRADED,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment