Commit bb27051f authored by NeilBrown's avatar NeilBrown

md/raid5: fix handling of degraded stripes in batches.

There is no need for special handling of stripe-batches when the array
is degraded.

There may be if there is a failure in the batch, but STRIPE_DEGRADED
does not imply an error.

So don't set STRIPE_BATCH_ERR in ops_run_io just because the array is
degraded.
This actually causes a bug: the STRIPE_DEGRADED flag gets cleared in
check_break_stripe_batch_list() and so the bitmap bit gets cleared
when it shouldn't.

So in check_break_stripe_batch_list(), split the batch up completely -
again STRIPE_DEGRADED isn't meaningful.

Also don't set STRIPE_BATCH_ERR when there is a write error to a
replacement device.  This simply removes the replacement device and
requires no extra handling.
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 738a2738
...@@ -1078,9 +1078,6 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) ...@@ -1078,9 +1078,6 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
pr_debug("skip op %ld on disc %d for sector %llu\n", pr_debug("skip op %ld on disc %d for sector %llu\n",
bi->bi_rw, i, (unsigned long long)sh->sector); bi->bi_rw, i, (unsigned long long)sh->sector);
clear_bit(R5_LOCKED, &sh->dev[i].flags); clear_bit(R5_LOCKED, &sh->dev[i].flags);
if (sh->batch_head)
set_bit(STRIPE_BATCH_ERR,
&sh->batch_head->state);
set_bit(STRIPE_HANDLE, &sh->state); set_bit(STRIPE_HANDLE, &sh->state);
} }
...@@ -2448,7 +2445,7 @@ static void raid5_end_write_request(struct bio *bi, int error) ...@@ -2448,7 +2445,7 @@ static void raid5_end_write_request(struct bio *bi, int error)
} }
rdev_dec_pending(rdev, conf->mddev); rdev_dec_pending(rdev, conf->mddev);
if (sh->batch_head && !uptodate) if (sh->batch_head && !uptodate && !replacement)
set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state); set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state);
if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags)) if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags))
...@@ -4214,15 +4211,9 @@ static void check_break_stripe_batch_list(struct stripe_head *sh) ...@@ -4214,15 +4211,9 @@ static void check_break_stripe_batch_list(struct stripe_head *sh)
return; return;
head_sh = sh; head_sh = sh;
do {
sh = list_first_entry(&sh->batch_list,
struct stripe_head, batch_list);
BUG_ON(sh == head_sh);
} while (!test_bit(STRIPE_DEGRADED, &sh->state));
while (sh != head_sh) { list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) {
next = list_first_entry(&sh->batch_list,
struct stripe_head, batch_list);
list_del_init(&sh->batch_list); list_del_init(&sh->batch_list);
set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG, set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
...@@ -4242,8 +4233,6 @@ static void check_break_stripe_batch_list(struct stripe_head *sh) ...@@ -4242,8 +4233,6 @@ static void check_break_stripe_batch_list(struct stripe_head *sh)
set_bit(STRIPE_HANDLE, &sh->state); set_bit(STRIPE_HANDLE, &sh->state);
release_stripe(sh); release_stripe(sh);
sh = next;
} }
} }
......
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