Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7449f699 authored by Tomasz Majchrzak's avatar Tomasz Majchrzak Committed by Shaohua Li
Browse files

raid1: handle read error also in readonly mode



If write is the first operation on a disk and it happens not to be
aligned to page size, block layer sends read request first. If read
operation fails, the disk is set as failed as no attempt to fix the
error is made because array is in auto-readonly mode. Similarily, the
disk is set as failed for read-only array.

Take the same approach as in raid10. Don't fail the disk if array is in
readonly or auto-readonly mode. Try to redirect the request first and if
unsuccessful, return a read error.

Signed-off-by: default avatarTomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: default avatarShaohua Li <shli@fb.com>
parent 9a8b27fa
Loading
Loading
Loading
Loading
+10 −9
Original line number Original line Diff line number Diff line
@@ -2297,17 +2297,23 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
	 * This is all done synchronously while the array is
	 * This is all done synchronously while the array is
	 * frozen
	 * frozen
	 */
	 */

	bio = r1_bio->bios[r1_bio->read_disk];
	bdevname(bio->bi_bdev, b);
	bio_put(bio);
	r1_bio->bios[r1_bio->read_disk] = NULL;

	if (mddev->ro == 0) {
	if (mddev->ro == 0) {
		freeze_array(conf, 1);
		freeze_array(conf, 1);
		fix_read_error(conf, r1_bio->read_disk,
		fix_read_error(conf, r1_bio->read_disk,
			       r1_bio->sector, r1_bio->sectors);
			       r1_bio->sector, r1_bio->sectors);
		unfreeze_array(conf);
		unfreeze_array(conf);
	} else
	} else {
		md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
		r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED;
	}

	rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);
	rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);


	bio = r1_bio->bios[r1_bio->read_disk];
	bdevname(bio->bi_bdev, b);
read_more:
read_more:
	disk = read_balance(conf, r1_bio, &max_sectors);
	disk = read_balance(conf, r1_bio, &max_sectors);
	if (disk == -1) {
	if (disk == -1) {
@@ -2318,11 +2324,6 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
	} else {
	} else {
		const unsigned long do_sync
		const unsigned long do_sync
			= r1_bio->master_bio->bi_opf & REQ_SYNC;
			= r1_bio->master_bio->bi_opf & REQ_SYNC;
		if (bio) {
			r1_bio->bios[r1_bio->read_disk] =
				mddev->ro ? IO_BLOCKED : NULL;
			bio_put(bio);
		}
		r1_bio->read_disk = disk;
		r1_bio->read_disk = disk;
		bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
		bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
		bio_trim(bio, r1_bio->sector - bio->bi_iter.bi_sector,
		bio_trim(bio, r1_bio->sector - bio->bi_iter.bi_sector,