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

Commit 1877db75 authored by NeilBrown's avatar NeilBrown
Browse files

md/raid1: restore ability for check and repair to fix read errors.



commit 30bc9b53
    md/raid1: fix bio handling problems in process_checks()

Move the bio_reset() to a point before where BIO_UPTODATE is checked,
so that check now always report that the bio is uptodate, even if it is not.

This causes process_check() to sometimes treat read-errors as
successful matches so the good data isn't written out.

This patch preserves the flag until it is needed.

Bug was introduced in 3.11, but backported to 3.10-stable (as it fixed
an even worse bug).  So suitable for any -stable since 3.10.

Reported-and-tested-by: default avatarMichael Tokarev <mjt@tls.msk.ru>
Cc: stable@vger.kernel.org (3.10+)
Fixed: 30bc9b53
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 38dbfb59
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -1953,11 +1953,15 @@ static int process_checks(struct r1bio *r1_bio)
	for (i = 0; i < conf->raid_disks * 2; i++) {
		int j;
		int size;
		int uptodate;
		struct bio *b = r1_bio->bios[i];
		if (b->bi_end_io != end_sync_read)
			continue;
		/* fixup the bio for reuse */
		/* fixup the bio for reuse, but preserve BIO_UPTODATE */
		uptodate = test_bit(BIO_UPTODATE, &b->bi_flags);
		bio_reset(b);
		if (!uptodate)
			clear_bit(BIO_UPTODATE, &b->bi_flags);
		b->bi_vcnt = vcnt;
		b->bi_iter.bi_size = r1_bio->sectors << 9;
		b->bi_iter.bi_sector = r1_bio->sector +
@@ -1990,11 +1994,14 @@ static int process_checks(struct r1bio *r1_bio)
		int j;
		struct bio *pbio = r1_bio->bios[primary];
		struct bio *sbio = r1_bio->bios[i];
		int uptodate = test_bit(BIO_UPTODATE, &sbio->bi_flags);

		if (sbio->bi_end_io != end_sync_read)
			continue;
		/* Now we can 'fixup' the BIO_UPTODATE flag */
		set_bit(BIO_UPTODATE, &sbio->bi_flags);

		if (test_bit(BIO_UPTODATE, &sbio->bi_flags)) {
		if (uptodate) {
			for (j = vcnt; j-- ; ) {
				struct page *p, *s;
				p = pbio->bi_io_vec[j].bv_page;
@@ -2009,7 +2016,7 @@ static int process_checks(struct r1bio *r1_bio)
		if (j >= 0)
			atomic64_add(r1_bio->sectors, &mddev->resync_mismatches);
		if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)
			      && test_bit(BIO_UPTODATE, &sbio->bi_flags))) {
			      && uptodate)) {
			/* No need to write to this device. */
			sbio->bi_end_io = NULL;
			rdev_dec_pending(conf->mirrors[i].rdev, mddev);