md/raid5. Don't write to known bad block on doubtful devices.
If a device has seen write errors, don't write to any known bad blocks on that device. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
bc2607f393
commit
73e92e51b7
1 changed files with 30 additions and 1 deletions
|
@ -526,6 +526,36 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
|
||||||
atomic_inc(&rdev->nr_pending);
|
atomic_inc(&rdev->nr_pending);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
/* We have already checked bad blocks for reads. Now
|
||||||
|
* need to check for writes.
|
||||||
|
*/
|
||||||
|
while ((rw & WRITE) && rdev &&
|
||||||
|
test_bit(WriteErrorSeen, &rdev->flags)) {
|
||||||
|
sector_t first_bad;
|
||||||
|
int bad_sectors;
|
||||||
|
int bad = is_badblock(rdev, sh->sector, STRIPE_SECTORS,
|
||||||
|
&first_bad, &bad_sectors);
|
||||||
|
if (!bad)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (bad < 0) {
|
||||||
|
set_bit(BlockedBadBlocks, &rdev->flags);
|
||||||
|
if (!conf->mddev->external &&
|
||||||
|
conf->mddev->flags) {
|
||||||
|
/* It is very unlikely, but we might
|
||||||
|
* still need to write out the
|
||||||
|
* bad block log - better give it
|
||||||
|
* a chance*/
|
||||||
|
md_check_recovery(conf->mddev);
|
||||||
|
}
|
||||||
|
md_wait_for_blocked_rdev(rdev, conf->mddev);
|
||||||
|
} else {
|
||||||
|
/* Acknowledged bad block - skip the write */
|
||||||
|
rdev_dec_pending(rdev, conf->mddev);
|
||||||
|
rdev = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rdev) {
|
if (rdev) {
|
||||||
if (s->syncing || s->expanding || s->expanded)
|
if (s->syncing || s->expanding || s->expanded)
|
||||||
md_sync_acct(rdev->bdev, STRIPE_SECTORS);
|
md_sync_acct(rdev->bdev, STRIPE_SECTORS);
|
||||||
|
@ -3317,7 +3347,6 @@ finish:
|
||||||
|
|
||||||
ops_run_io(sh, &s);
|
ops_run_io(sh, &s);
|
||||||
|
|
||||||
|
|
||||||
if (s.dec_preread_active) {
|
if (s.dec_preread_active) {
|
||||||
/* We delay this until after ops_run_io so that if make_request
|
/* We delay this until after ops_run_io so that if make_request
|
||||||
* is waiting on a flush, it won't continue until the writes
|
* is waiting on a flush, it won't continue until the writes
|
||||||
|
|
Loading…
Reference in a new issue