Skip to content

Commit ebd873a

Browse files
YuKuai-huaweiharshimogalapalli
authored andcommitted
md/raid1,raid10: don't handle IO error for REQ_RAHEAD and REQ_NOWAIT
commit 9f346f7 upstream. IO with REQ_RAHEAD or REQ_NOWAIT can fail early, even if the storage medium is fine, hence record badblocks or remove the disk from array does not make sense. This problem if found by lvm2 test lvcreate-large-raid, where dm-zero will fail read ahead IO directly. Fixes: e879a0d ("md/raid1,raid10: don't ignore IO flags") Reported-and-tested-by: Mikulas Patocka <mpatocka@redhat.com> Closes: https://lore.kernel.org/all/34fa755d-62c8-4588-8ee1-33cb1249bdf2@redhat.com/ Link: https://lore.kernel.org/linux-raid/20250527081407.3004055-1-yukuai1@huaweicloud.com Signed-off-by: Yu Kuai <yukuai3@huawei.com> Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> (cherry picked from commit ed6aac13dd9d6d5169bd1f6edb50f5f8318d69c7) Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
1 parent c749435 commit ebd873a

File tree

3 files changed

+26
-14
lines changed

3 files changed

+26
-14
lines changed

drivers/md/raid1-10.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,13 @@ static inline bool raid1_should_read_first(struct mddev *mddev,
293293

294294
return false;
295295
}
296+
297+
/*
298+
* bio with REQ_RAHEAD or REQ_NOWAIT can fail at anytime, before such IO is
299+
* submitted to the underlying disks, hence don't record badblocks or retry
300+
* in this case.
301+
*/
302+
static inline bool raid1_should_handle_error(struct bio *bio)
303+
{
304+
return !(bio->bi_opf & (REQ_RAHEAD | REQ_NOWAIT));
305+
}

drivers/md/raid1.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -371,14 +371,16 @@ static void raid1_end_read_request(struct bio *bio)
371371
*/
372372
update_head_pos(r1_bio->read_disk, r1_bio);
373373

374-
if (uptodate)
374+
if (uptodate) {
375375
set_bit(R1BIO_Uptodate, &r1_bio->state);
376-
else if (test_bit(FailFast, &rdev->flags) &&
377-
test_bit(R1BIO_FailFast, &r1_bio->state))
376+
} else if (test_bit(FailFast, &rdev->flags) &&
377+
test_bit(R1BIO_FailFast, &r1_bio->state)) {
378378
/* This was a fail-fast read so we definitely
379379
* want to retry */
380380
;
381-
else {
381+
} else if (!raid1_should_handle_error(bio)) {
382+
uptodate = 1;
383+
} else {
382384
/* If all other devices have failed, we want to return
383385
* the error upwards rather than fail the last device.
384386
* Here we redefine "uptodate" to mean "Don't want to retry"
@@ -449,16 +451,15 @@ static void raid1_end_write_request(struct bio *bio)
449451
struct bio *to_put = NULL;
450452
int mirror = find_bio_disk(r1_bio, bio);
451453
struct md_rdev *rdev = conf->mirrors[mirror].rdev;
452-
bool discard_error;
453454
sector_t lo = r1_bio->sector;
454455
sector_t hi = r1_bio->sector + r1_bio->sectors;
455-
456-
discard_error = bio->bi_status && bio_op(bio) == REQ_OP_DISCARD;
456+
bool ignore_error = !raid1_should_handle_error(bio) ||
457+
(bio->bi_status && bio_op(bio) == REQ_OP_DISCARD);
457458

458459
/*
459460
* 'one mirror IO has finished' event handler:
460461
*/
461-
if (bio->bi_status && !discard_error) {
462+
if (bio->bi_status && !ignore_error) {
462463
set_bit(WriteErrorSeen, &rdev->flags);
463464
if (!test_and_set_bit(WantReplacement, &rdev->flags))
464465
set_bit(MD_RECOVERY_NEEDED, &
@@ -509,7 +510,7 @@ static void raid1_end_write_request(struct bio *bio)
509510

510511
/* Maybe we can clear some bad blocks. */
511512
if (rdev_has_badblock(rdev, r1_bio->sector, r1_bio->sectors) &&
512-
!discard_error) {
513+
!ignore_error) {
513514
r1_bio->bios[mirror] = IO_MADE_GOOD;
514515
set_bit(R1BIO_MadeGood, &r1_bio->state);
515516
}

drivers/md/raid10.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ static void raid10_end_read_request(struct bio *bio)
398398
* wait for the 'master' bio.
399399
*/
400400
set_bit(R10BIO_Uptodate, &r10_bio->state);
401+
} else if (!raid1_should_handle_error(bio)) {
402+
uptodate = 1;
401403
} else {
402404
/* If all other devices that store this block have
403405
* failed, we want to return the error upwards rather
@@ -455,9 +457,8 @@ static void raid10_end_write_request(struct bio *bio)
455457
int slot, repl;
456458
struct md_rdev *rdev = NULL;
457459
struct bio *to_put = NULL;
458-
bool discard_error;
459-
460-
discard_error = bio->bi_status && bio_op(bio) == REQ_OP_DISCARD;
460+
bool ignore_error = !raid1_should_handle_error(bio) ||
461+
(bio->bi_status && bio_op(bio) == REQ_OP_DISCARD);
461462

462463
dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl);
463464

@@ -471,7 +472,7 @@ static void raid10_end_write_request(struct bio *bio)
471472
/*
472473
* this branch is our 'one mirror IO has finished' event handler:
473474
*/
474-
if (bio->bi_status && !discard_error) {
475+
if (bio->bi_status && !ignore_error) {
475476
if (repl)
476477
/* Never record new bad blocks to replacement,
477478
* just fail it.
@@ -526,7 +527,7 @@ static void raid10_end_write_request(struct bio *bio)
526527
/* Maybe we can clear some bad blocks. */
527528
if (rdev_has_badblock(rdev, r10_bio->devs[slot].addr,
528529
r10_bio->sectors) &&
529-
!discard_error) {
530+
!ignore_error) {
530531
bio_put(bio);
531532
if (repl)
532533
r10_bio->devs[slot].repl_bio = IO_MADE_GOOD;

0 commit comments

Comments
 (0)