md/raid1: restore ability for check and repair to fix read errors.
commit30bc9b5387
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: Michael Tokarev <mjt@tls.msk.ru> Cc: stable@vger.kernel.org (3.10+) Fixed:30bc9b5387
Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
@@ -1953,11 +1953,15 @@ static int process_checks(struct r1bio *r1_bio)
|
|||||||
for (i = 0; i < conf->raid_disks * 2; i++) {
|
for (i = 0; i < conf->raid_disks * 2; i++) {
|
||||||
int j;
|
int j;
|
||||||
int size;
|
int size;
|
||||||
|
int uptodate;
|
||||||
struct bio *b = r1_bio->bios[i];
|
struct bio *b = r1_bio->bios[i];
|
||||||
if (b->bi_end_io != end_sync_read)
|
if (b->bi_end_io != end_sync_read)
|
||||||
continue;
|
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);
|
bio_reset(b);
|
||||||
|
if (!uptodate)
|
||||||
|
clear_bit(BIO_UPTODATE, &b->bi_flags);
|
||||||
b->bi_vcnt = vcnt;
|
b->bi_vcnt = vcnt;
|
||||||
b->bi_iter.bi_size = r1_bio->sectors << 9;
|
b->bi_iter.bi_size = r1_bio->sectors << 9;
|
||||||
b->bi_iter.bi_sector = r1_bio->sector +
|
b->bi_iter.bi_sector = r1_bio->sector +
|
||||||
@@ -1990,11 +1994,14 @@ static int process_checks(struct r1bio *r1_bio)
|
|||||||
int j;
|
int j;
|
||||||
struct bio *pbio = r1_bio->bios[primary];
|
struct bio *pbio = r1_bio->bios[primary];
|
||||||
struct bio *sbio = r1_bio->bios[i];
|
struct bio *sbio = r1_bio->bios[i];
|
||||||
|
int uptodate = test_bit(BIO_UPTODATE, &sbio->bi_flags);
|
||||||
|
|
||||||
if (sbio->bi_end_io != end_sync_read)
|
if (sbio->bi_end_io != end_sync_read)
|
||||||
continue;
|
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-- ; ) {
|
for (j = vcnt; j-- ; ) {
|
||||||
struct page *p, *s;
|
struct page *p, *s;
|
||||||
p = pbio->bi_io_vec[j].bv_page;
|
p = pbio->bi_io_vec[j].bv_page;
|
||||||
@@ -2009,7 +2016,7 @@ static int process_checks(struct r1bio *r1_bio)
|
|||||||
if (j >= 0)
|
if (j >= 0)
|
||||||
atomic64_add(r1_bio->sectors, &mddev->resync_mismatches);
|
atomic64_add(r1_bio->sectors, &mddev->resync_mismatches);
|
||||||
if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)
|
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. */
|
/* No need to write to this device. */
|
||||||
sbio->bi_end_io = NULL;
|
sbio->bi_end_io = NULL;
|
||||||
rdev_dec_pending(conf->mirrors[i].rdev, mddev);
|
rdev_dec_pending(conf->mirrors[i].rdev, mddev);
|
||||||
|
Reference in New Issue
Block a user