diff options
Diffstat (limited to 'drivers/md/raid1.c')
| -rw-r--r-- | drivers/md/raid1.c | 53 |
1 files changed, 30 insertions, 23 deletions
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 | } |
