diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-18 20:37:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-18 20:37:46 -0400 |
commit | 4b8b8a4afa4f794a0029cdf2c13b6789fd38d9de (patch) | |
tree | 2f4bfdae3c41aa9faab26ab7ae0d45724d8b2ed4 | |
parent | 0a693ab6b6b2af0a230e98323023acd3678b0f81 (diff) | |
parent | 30bc9b53878a9921b02e3b5bc4283ac1c6de102a (diff) |
Merge tag 'md-3.11-fixes' of git://neil.brown.name/md
Pull md bug fixes from NeilBrown:
"Sorry boss, back at work now boss. Here's them nice shiny patches ya
wanted. All nicely tagged and justified for -stable and everyfing:
Three bug fixes for md in 3.10
3.10 wasn't a good release for md. The bio changes left a couple of
bugs, and an md "fix" created another one.
These three patches appear to fix the issues and have been tagged for
-stable"
* tag 'md-3.11-fixes' of git://neil.brown.name/md:
md/raid1: fix bio handling problems in process_checks()
md: Remove recent change which allows devices to skip recovery.
md/raid10: fix two problems with RAID10 resync.
-rw-r--r-- | drivers/md/md.c | 14 | ||||
-rw-r--r-- | drivers/md/raid1.c | 53 | ||||
-rw-r--r-- | drivers/md/raid10.c | 11 |
3 files changed, 39 insertions, 39 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index dddc87bcf64a..9f13e13506ef 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -7716,20 +7716,6 @@ static int remove_and_add_spares(struct mddev *mddev, | |||
7716 | continue; | 7716 | continue; |
7717 | 7717 | ||
7718 | rdev->recovery_offset = 0; | 7718 | rdev->recovery_offset = 0; |
7719 | if (rdev->saved_raid_disk >= 0 && mddev->in_sync) { | ||
7720 | spin_lock_irq(&mddev->write_lock); | ||
7721 | if (mddev->in_sync) | ||
7722 | /* OK, this device, which is in_sync, | ||
7723 | * will definitely be noticed before | ||
7724 | * the next write, so recovery isn't | ||
7725 | * needed. | ||
7726 | */ | ||
7727 | rdev->recovery_offset = mddev->recovery_cp; | ||
7728 | spin_unlock_irq(&mddev->write_lock); | ||
7729 | } | ||
7730 | if (mddev->ro && rdev->recovery_offset != MaxSector) | ||
7731 | /* not safe to add this disk now */ | ||
7732 | continue; | ||
7733 | if (mddev->pers-> | 7719 | if (mddev->pers-> |
7734 | hot_add_disk(mddev, rdev) == 0) { | 7720 | hot_add_disk(mddev, rdev) == 0) { |
7735 | if (sysfs_link_rdev(mddev, rdev)) | 7721 | if (sysfs_link_rdev(mddev, rdev)) |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ec734588a1c6..d60412c7f995 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1849,6 +1849,36 @@ static int process_checks(struct r1bio *r1_bio) | |||
1849 | int i; | 1849 | int i; |
1850 | int vcnt; | 1850 | int vcnt; |
1851 | 1851 | ||
1852 | /* Fix variable parts of all bios */ | ||
1853 | vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9); | ||
1854 | for (i = 0; i < conf->raid_disks * 2; i++) { | ||
1855 | int j; | ||
1856 | int size; | ||
1857 | struct bio *b = r1_bio->bios[i]; | ||
1858 | if (b->bi_end_io != end_sync_read) | ||
1859 | continue; | ||
1860 | /* fixup the bio for reuse */ | ||
1861 | bio_reset(b); | ||
1862 | b->bi_vcnt = vcnt; | ||
1863 | b->bi_size = r1_bio->sectors << 9; | ||
1864 | b->bi_sector = r1_bio->sector + | ||
1865 | conf->mirrors[i].rdev->data_offset; | ||
1866 | b->bi_bdev = conf->mirrors[i].rdev->bdev; | ||
1867 | b->bi_end_io = end_sync_read; | ||
1868 | b->bi_private = r1_bio; | ||
1869 | |||
1870 | size = b->bi_size; | ||
1871 | for (j = 0; j < vcnt ; j++) { | ||
1872 | struct bio_vec *bi; | ||
1873 | bi = &b->bi_io_vec[j]; | ||
1874 | bi->bv_offset = 0; | ||
1875 | if (size > PAGE_SIZE) | ||
1876 | bi->bv_len = PAGE_SIZE; | ||
1877 | else | ||
1878 | bi->bv_len = size; | ||
1879 | size -= PAGE_SIZE; | ||
1880 | } | ||
1881 | } | ||
1852 | for (primary = 0; primary < conf->raid_disks * 2; primary++) | 1882 | for (primary = 0; primary < conf->raid_disks * 2; primary++) |
1853 | if (r1_bio->bios[primary]->bi_end_io == end_sync_read && | 1883 | if (r1_bio->bios[primary]->bi_end_io == end_sync_read && |
1854 | test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) { | 1884 | test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) { |
@@ -1857,12 +1887,10 @@ static int process_checks(struct r1bio *r1_bio) | |||
1857 | break; | 1887 | break; |
1858 | } | 1888 | } |
1859 | r1_bio->read_disk = primary; | 1889 | r1_bio->read_disk = primary; |
1860 | vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9); | ||
1861 | for (i = 0; i < conf->raid_disks * 2; i++) { | 1890 | for (i = 0; i < conf->raid_disks * 2; i++) { |
1862 | int j; | 1891 | int j; |
1863 | struct bio *pbio = r1_bio->bios[primary]; | 1892 | struct bio *pbio = r1_bio->bios[primary]; |
1864 | struct bio *sbio = r1_bio->bios[i]; | 1893 | struct bio *sbio = r1_bio->bios[i]; |
1865 | int size; | ||
1866 | 1894 | ||
1867 | if (sbio->bi_end_io != end_sync_read) | 1895 | if (sbio->bi_end_io != end_sync_read) |
1868 | continue; | 1896 | continue; |
@@ -1888,27 +1916,6 @@ static int process_checks(struct r1bio *r1_bio) | |||
1888 | rdev_dec_pending(conf->mirrors[i].rdev, mddev); | 1916 | rdev_dec_pending(conf->mirrors[i].rdev, mddev); |
1889 | continue; | 1917 | continue; |
1890 | } | 1918 | } |
1891 | /* fixup the bio for reuse */ | ||
1892 | bio_reset(sbio); | ||
1893 | sbio->bi_vcnt = vcnt; | ||
1894 | sbio->bi_size = r1_bio->sectors << 9; | ||
1895 | sbio->bi_sector = r1_bio->sector + | ||
1896 | conf->mirrors[i].rdev->data_offset; | ||
1897 | sbio->bi_bdev = conf->mirrors[i].rdev->bdev; | ||
1898 | sbio->bi_end_io = end_sync_read; | ||
1899 | sbio->bi_private = r1_bio; | ||
1900 | |||
1901 | size = sbio->bi_size; | ||
1902 | for (j = 0; j < vcnt ; j++) { | ||
1903 | struct bio_vec *bi; | ||
1904 | bi = &sbio->bi_io_vec[j]; | ||
1905 | bi->bv_offset = 0; | ||
1906 | if (size > PAGE_SIZE) | ||
1907 | bi->bv_len = PAGE_SIZE; | ||
1908 | else | ||
1909 | bi->bv_len = size; | ||
1910 | size -= PAGE_SIZE; | ||
1911 | } | ||
1912 | 1919 | ||
1913 | bio_copy_data(sbio, pbio); | 1920 | bio_copy_data(sbio, pbio); |
1914 | } | 1921 | } |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index cd066b63bdaf..957a719e8c2f 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -2097,11 +2097,17 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) | |||
2097 | * both 'first' and 'i', so we just compare them. | 2097 | * both 'first' and 'i', so we just compare them. |
2098 | * All vec entries are PAGE_SIZE; | 2098 | * All vec entries are PAGE_SIZE; |
2099 | */ | 2099 | */ |
2100 | for (j = 0; j < vcnt; j++) | 2100 | int sectors = r10_bio->sectors; |
2101 | for (j = 0; j < vcnt; j++) { | ||
2102 | int len = PAGE_SIZE; | ||
2103 | if (sectors < (len / 512)) | ||
2104 | len = sectors * 512; | ||
2101 | if (memcmp(page_address(fbio->bi_io_vec[j].bv_page), | 2105 | if (memcmp(page_address(fbio->bi_io_vec[j].bv_page), |
2102 | page_address(tbio->bi_io_vec[j].bv_page), | 2106 | page_address(tbio->bi_io_vec[j].bv_page), |
2103 | fbio->bi_io_vec[j].bv_len)) | 2107 | len)) |
2104 | break; | 2108 | break; |
2109 | sectors -= len/512; | ||
2110 | } | ||
2105 | if (j == vcnt) | 2111 | if (j == vcnt) |
2106 | continue; | 2112 | continue; |
2107 | atomic64_add(r10_bio->sectors, &mddev->resync_mismatches); | 2113 | atomic64_add(r10_bio->sectors, &mddev->resync_mismatches); |
@@ -3407,6 +3413,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
3407 | 3413 | ||
3408 | if (bio->bi_end_io == end_sync_read) { | 3414 | if (bio->bi_end_io == end_sync_read) { |
3409 | md_sync_acct(bio->bi_bdev, nr_sectors); | 3415 | md_sync_acct(bio->bi_bdev, nr_sectors); |
3416 | set_bit(BIO_UPTODATE, &bio->bi_flags); | ||
3410 | generic_make_request(bio); | 3417 | generic_make_request(bio); |
3411 | } | 3418 | } |
3412 | } | 3419 | } |