|
@@ -3462,6 +3462,7 @@ static void handle_stripe(struct stripe_head *sh)
|
|
|
test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
|
|
|
set_bit(STRIPE_SYNCING, &sh->state);
|
|
|
clear_bit(STRIPE_INSYNC, &sh->state);
|
|
|
+ clear_bit(STRIPE_REPLACED, &sh->state);
|
|
|
}
|
|
|
spin_unlock(&sh->stripe_lock);
|
|
|
}
|
|
@@ -3607,19 +3608,23 @@ static void handle_stripe(struct stripe_head *sh)
|
|
|
handle_parity_checks5(conf, sh, &s, disks);
|
|
|
}
|
|
|
|
|
|
- if (s.replacing && s.locked == 0
|
|
|
- && !test_bit(STRIPE_INSYNC, &sh->state)) {
|
|
|
+ if ((s.replacing || s.syncing) && s.locked == 0
|
|
|
+ && !test_bit(STRIPE_COMPUTE_RUN, &sh->state)
|
|
|
+ && !test_bit(STRIPE_REPLACED, &sh->state)) {
|
|
|
/* Write out to replacement devices where possible */
|
|
|
for (i = 0; i < conf->raid_disks; i++)
|
|
|
- if (test_bit(R5_UPTODATE, &sh->dev[i].flags) &&
|
|
|
- test_bit(R5_NeedReplace, &sh->dev[i].flags)) {
|
|
|
+ if (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_LOCKED, &sh->dev[i].flags);
|
|
|
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 &&
|
|
|
+ !test_bit(STRIPE_COMPUTE_RUN, &sh->state) &&
|
|
|
test_bit(STRIPE_INSYNC, &sh->state)) {
|
|
|
md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
|
|
|
clear_bit(STRIPE_SYNCING, &sh->state);
|