aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid1.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-02-04 20:17:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-22 15:41:29 -0500
commit9f2d289933e60ec726a7a9522e2dcdfdc82c58de (patch)
tree37514362cbb644dc0699d7f24a28e8006dbaa7d1 /drivers/md/raid1.c
parentdbd515879a94273d4a6e1e6195d20951af2a65af (diff)
md/raid1: restore ability for check and repair to fix read errors.
commit 1877db75589a895bbdc4c4c3f23558e57b521141 upstream. commit 30bc9b53878a9921b02e3b5bc4283ac1c6de102a 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> Fixed: 30bc9b53878a9921b02e3b5bc4283ac1c6de102a Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r--drivers/md/raid1.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index afaa5d425e9a..e73740b55aea 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1854,11 +1854,15 @@ static int process_checks(struct r1bio *r1_bio)
1854 for (i = 0; i < conf->raid_disks * 2; i++) { 1854 for (i = 0; i < conf->raid_disks * 2; i++) {
1855 int j; 1855 int j;
1856 int size; 1856 int size;
1857 int uptodate;
1857 struct bio *b = r1_bio->bios[i]; 1858 struct bio *b = r1_bio->bios[i];
1858 if (b->bi_end_io != end_sync_read) 1859 if (b->bi_end_io != end_sync_read)
1859 continue; 1860 continue;
1860 /* fixup the bio for reuse */ 1861 /* fixup the bio for reuse, but preserve BIO_UPTODATE */
1862 uptodate = test_bit(BIO_UPTODATE, &b->bi_flags);
1861 bio_reset(b); 1863 bio_reset(b);
1864 if (!uptodate)
1865 clear_bit(BIO_UPTODATE, &b->bi_flags);
1862 b->bi_vcnt = vcnt; 1866 b->bi_vcnt = vcnt;
1863 b->bi_size = r1_bio->sectors << 9; 1867 b->bi_size = r1_bio->sectors << 9;
1864 b->bi_sector = r1_bio->sector + 1868 b->bi_sector = r1_bio->sector +
@@ -1891,11 +1895,14 @@ static int process_checks(struct r1bio *r1_bio)
1891 int j; 1895 int j;
1892 struct bio *pbio = r1_bio->bios[primary]; 1896 struct bio *pbio = r1_bio->bios[primary];
1893 struct bio *sbio = r1_bio->bios[i]; 1897 struct bio *sbio = r1_bio->bios[i];
1898 int uptodate = test_bit(BIO_UPTODATE, &sbio->bi_flags);
1894 1899
1895 if (sbio->bi_end_io != end_sync_read) 1900 if (sbio->bi_end_io != end_sync_read)
1896 continue; 1901 continue;
1902 /* Now we can 'fixup' the BIO_UPTODATE flag */
1903 set_bit(BIO_UPTODATE, &sbio->bi_flags);
1897 1904
1898 if (test_bit(BIO_UPTODATE, &sbio->bi_flags)) { 1905 if (uptodate) {
1899 for (j = vcnt; j-- ; ) { 1906 for (j = vcnt; j-- ; ) {
1900 struct page *p, *s; 1907 struct page *p, *s;
1901 p = pbio->bi_io_vec[j].bv_page; 1908 p = pbio->bi_io_vec[j].bv_page;
@@ -1910,7 +1917,7 @@ static int process_checks(struct r1bio *r1_bio)
1910 if (j >= 0) 1917 if (j >= 0)
1911 atomic64_add(r1_bio->sectors, &mddev->resync_mismatches); 1918 atomic64_add(r1_bio->sectors, &mddev->resync_mismatches);
1912 if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery) 1919 if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)
1913 && test_bit(BIO_UPTODATE, &sbio->bi_flags))) { 1920 && uptodate)) {
1914 /* No need to write to this device. */ 1921 /* No need to write to this device. */
1915 sbio->bi_end_io = NULL; 1922 sbio->bi_end_io = NULL;
1916 rdev_dec_pending(conf->mirrors[i].rdev, mddev); 1923 rdev_dec_pending(conf->mirrors[i].rdev, mddev);