aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid1.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-27 21:38:13 -0400
committerNeilBrown <neilb@suse.de>2011-07-27 21:38:13 -0400
commit62096bce231b3760882ed91205fc84682d6b0529 (patch)
tree90b8a89be6f3c1983e88a4b0fe9d5a0e15ccda7e /drivers/md/raid1.c
parent3a9f28a5117e00a868dd8b4395f9a707ae56764b (diff)
md/raid1: factor several functions out or raid1d()
raid1d is too big with several deep branches. So separate them out into their own functions. Signed-off-by: NeilBrown <neilb@suse.de> Reviewed-by: Namhyung Kim <namhyung@gmail.com>
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r--drivers/md/raid1.c310
1 files changed, 151 insertions, 159 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 039e3af72929..32323f0afd89 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1861,21 +1861,160 @@ static int narrow_write_error(r1bio_t *r1_bio, int i)
1861 return ok; 1861 return ok;
1862} 1862}
1863 1863
1864static void handle_sync_write_finished(conf_t *conf, r1bio_t *r1_bio)
1865{
1866 int m;
1867 int s = r1_bio->sectors;
1868 for (m = 0; m < conf->raid_disks ; m++) {
1869 mdk_rdev_t *rdev = conf->mirrors[m].rdev;
1870 struct bio *bio = r1_bio->bios[m];
1871 if (bio->bi_end_io == NULL)
1872 continue;
1873 if (test_bit(BIO_UPTODATE, &bio->bi_flags) &&
1874 test_bit(R1BIO_MadeGood, &r1_bio->state)) {
1875 rdev_clear_badblocks(rdev, r1_bio->sector, s);
1876 }
1877 if (!test_bit(BIO_UPTODATE, &bio->bi_flags) &&
1878 test_bit(R1BIO_WriteError, &r1_bio->state)) {
1879 if (!rdev_set_badblocks(rdev, r1_bio->sector, s, 0))
1880 md_error(conf->mddev, rdev);
1881 }
1882 }
1883 put_buf(r1_bio);
1884 md_done_sync(conf->mddev, s, 1);
1885}
1886
1887static void handle_write_finished(conf_t *conf, r1bio_t *r1_bio)
1888{
1889 int m;
1890 for (m = 0; m < conf->raid_disks ; m++)
1891 if (r1_bio->bios[m] == IO_MADE_GOOD) {
1892 mdk_rdev_t *rdev = conf->mirrors[m].rdev;
1893 rdev_clear_badblocks(rdev,
1894 r1_bio->sector,
1895 r1_bio->sectors);
1896 rdev_dec_pending(rdev, conf->mddev);
1897 } else if (r1_bio->bios[m] != NULL) {
1898 /* This drive got a write error. We need to
1899 * narrow down and record precise write
1900 * errors.
1901 */
1902 if (!narrow_write_error(r1_bio, m)) {
1903 md_error(conf->mddev,
1904 conf->mirrors[m].rdev);
1905 /* an I/O failed, we can't clear the bitmap */
1906 set_bit(R1BIO_Degraded, &r1_bio->state);
1907 }
1908 rdev_dec_pending(conf->mirrors[m].rdev,
1909 conf->mddev);
1910 }
1911 if (test_bit(R1BIO_WriteError, &r1_bio->state))
1912 close_write(r1_bio);
1913 raid_end_bio_io(r1_bio);
1914}
1915
1916static void handle_read_error(conf_t *conf, r1bio_t *r1_bio)
1917{
1918 int disk;
1919 int max_sectors;
1920 mddev_t *mddev = conf->mddev;
1921 struct bio *bio;
1922 char b[BDEVNAME_SIZE];
1923 mdk_rdev_t *rdev;
1924
1925 clear_bit(R1BIO_ReadError, &r1_bio->state);
1926 /* we got a read error. Maybe the drive is bad. Maybe just
1927 * the block and we can fix it.
1928 * We freeze all other IO, and try reading the block from
1929 * other devices. When we find one, we re-write
1930 * and check it that fixes the read error.
1931 * This is all done synchronously while the array is
1932 * frozen
1933 */
1934 if (mddev->ro == 0) {
1935 freeze_array(conf);
1936 fix_read_error(conf, r1_bio->read_disk,
1937 r1_bio->sector, r1_bio->sectors);
1938 unfreeze_array(conf);
1939 } else
1940 md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
1941
1942 bio = r1_bio->bios[r1_bio->read_disk];
1943 bdevname(bio->bi_bdev, b);
1944read_more:
1945 disk = read_balance(conf, r1_bio, &max_sectors);
1946 if (disk == -1) {
1947 printk(KERN_ALERT "md/raid1:%s: %s: unrecoverable I/O"
1948 " read error for block %llu\n",
1949 mdname(mddev), b, (unsigned long long)r1_bio->sector);
1950 raid_end_bio_io(r1_bio);
1951 } else {
1952 const unsigned long do_sync
1953 = r1_bio->master_bio->bi_rw & REQ_SYNC;
1954 if (bio) {
1955 r1_bio->bios[r1_bio->read_disk] =
1956 mddev->ro ? IO_BLOCKED : NULL;
1957 bio_put(bio);
1958 }
1959 r1_bio->read_disk = disk;
1960 bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
1961 md_trim_bio(bio, r1_bio->sector - bio->bi_sector, max_sectors);
1962 r1_bio->bios[r1_bio->read_disk] = bio;
1963 rdev = conf->mirrors[disk].rdev;
1964 printk_ratelimited(KERN_ERR
1965 "md/raid1:%s: redirecting sector %llu"
1966 " to other mirror: %s\n",
1967 mdname(mddev),
1968 (unsigned long long)r1_bio->sector,
1969 bdevname(rdev->bdev, b));
1970 bio->bi_sector = r1_bio->sector + rdev->data_offset;
1971 bio->bi_bdev = rdev->bdev;
1972 bio->bi_end_io = raid1_end_read_request;
1973 bio->bi_rw = READ | do_sync;
1974 bio->bi_private = r1_bio;
1975 if (max_sectors < r1_bio->sectors) {
1976 /* Drat - have to split this up more */
1977 struct bio *mbio = r1_bio->master_bio;
1978 int sectors_handled = (r1_bio->sector + max_sectors
1979 - mbio->bi_sector);
1980 r1_bio->sectors = max_sectors;
1981 spin_lock_irq(&conf->device_lock);
1982 if (mbio->bi_phys_segments == 0)
1983 mbio->bi_phys_segments = 2;
1984 else
1985 mbio->bi_phys_segments++;
1986 spin_unlock_irq(&conf->device_lock);
1987 generic_make_request(bio);
1988 bio = NULL;
1989
1990 r1_bio = mempool_alloc(conf->r1bio_pool, GFP_NOIO);
1991
1992 r1_bio->master_bio = mbio;
1993 r1_bio->sectors = (mbio->bi_size >> 9)
1994 - sectors_handled;
1995 r1_bio->state = 0;
1996 set_bit(R1BIO_ReadError, &r1_bio->state);
1997 r1_bio->mddev = mddev;
1998 r1_bio->sector = mbio->bi_sector + sectors_handled;
1999
2000 goto read_more;
2001 } else
2002 generic_make_request(bio);
2003 }
2004}
2005
1864static void raid1d(mddev_t *mddev) 2006static void raid1d(mddev_t *mddev)
1865{ 2007{
1866 r1bio_t *r1_bio; 2008 r1bio_t *r1_bio;
1867 struct bio *bio;
1868 unsigned long flags; 2009 unsigned long flags;
1869 conf_t *conf = mddev->private; 2010 conf_t *conf = mddev->private;
1870 struct list_head *head = &conf->retry_list; 2011 struct list_head *head = &conf->retry_list;
1871 mdk_rdev_t *rdev;
1872 struct blk_plug plug; 2012 struct blk_plug plug;
1873 2013
1874 md_check_recovery(mddev); 2014 md_check_recovery(mddev);
1875 2015
1876 blk_start_plug(&plug); 2016 blk_start_plug(&plug);
1877 for (;;) { 2017 for (;;) {
1878 char b[BDEVNAME_SIZE];
1879 2018
1880 if (atomic_read(&mddev->plug_cnt) == 0) 2019 if (atomic_read(&mddev->plug_cnt) == 0)
1881 flush_pending_writes(conf); 2020 flush_pending_writes(conf);
@@ -1894,168 +2033,21 @@ static void raid1d(mddev_t *mddev)
1894 conf = mddev->private; 2033 conf = mddev->private;
1895 if (test_bit(R1BIO_IsSync, &r1_bio->state)) { 2034 if (test_bit(R1BIO_IsSync, &r1_bio->state)) {
1896 if (test_bit(R1BIO_MadeGood, &r1_bio->state) || 2035 if (test_bit(R1BIO_MadeGood, &r1_bio->state) ||
1897 test_bit(R1BIO_WriteError, &r1_bio->state)) { 2036 test_bit(R1BIO_WriteError, &r1_bio->state))
1898 int m; 2037 handle_sync_write_finished(conf, r1_bio);
1899 int s = r1_bio->sectors; 2038 else
1900 for (m = 0; m < conf->raid_disks ; m++) {
1901 mdk_rdev_t *rdev
1902 = conf->mirrors[m].rdev;
1903 struct bio *bio = r1_bio->bios[m];
1904 if (bio->bi_end_io == NULL)
1905 continue;
1906 if (test_bit(BIO_UPTODATE,
1907 &bio->bi_flags) &&
1908 test_bit(R1BIO_MadeGood,
1909 &r1_bio->state)) {
1910 rdev_clear_badblocks(
1911 rdev,
1912 r1_bio->sector,
1913 r1_bio->sectors);
1914 }
1915 if (!test_bit(BIO_UPTODATE,
1916 &bio->bi_flags) &&
1917 test_bit(R1BIO_WriteError,
1918 &r1_bio->state)) {
1919 if (!rdev_set_badblocks(
1920 rdev,
1921 r1_bio->sector,
1922 r1_bio->sectors, 0))
1923 md_error(mddev, rdev);
1924 }
1925 }
1926 put_buf(r1_bio);
1927 md_done_sync(mddev, s, 1);
1928 } else
1929 sync_request_write(mddev, r1_bio); 2039 sync_request_write(mddev, r1_bio);
1930 } else if (test_bit(R1BIO_MadeGood, &r1_bio->state) || 2040 } else if (test_bit(R1BIO_MadeGood, &r1_bio->state) ||
1931 test_bit(R1BIO_WriteError, &r1_bio->state)) { 2041 test_bit(R1BIO_WriteError, &r1_bio->state))
1932 int m; 2042 handle_write_finished(conf, r1_bio);
1933 for (m = 0; m < conf->raid_disks ; m++) 2043 else if (test_bit(R1BIO_ReadError, &r1_bio->state))
1934 if (r1_bio->bios[m] == IO_MADE_GOOD) { 2044 handle_read_error(conf, r1_bio);
1935 rdev = conf->mirrors[m].rdev; 2045 else
1936 rdev_clear_badblocks(
1937 rdev,
1938 r1_bio->sector,
1939 r1_bio->sectors);
1940 rdev_dec_pending(rdev, mddev);
1941 } else if (r1_bio->bios[m] != NULL) {
1942 /* This drive got a write error. We
1943 * need to narrow down and record
1944 * precise write errors.
1945 */
1946 if (!narrow_write_error(r1_bio, m)) {
1947 md_error(mddev,
1948 conf->mirrors[m].rdev);
1949 /* an I/O failed, we can't clear
1950 * the bitmap */
1951 set_bit(R1BIO_Degraded,
1952 &r1_bio->state);
1953 }
1954 rdev_dec_pending(conf->mirrors[m].rdev,
1955 mddev);
1956 }
1957 if (test_bit(R1BIO_WriteError, &r1_bio->state))
1958 close_write(r1_bio);
1959 raid_end_bio_io(r1_bio);
1960 } else if (test_bit(R1BIO_ReadError, &r1_bio->state)) {
1961 int disk;
1962 int max_sectors;
1963
1964 clear_bit(R1BIO_ReadError, &r1_bio->state);
1965 /* we got a read error. Maybe the drive is bad. Maybe just
1966 * the block and we can fix it.
1967 * We freeze all other IO, and try reading the block from
1968 * other devices. When we find one, we re-write
1969 * and check it that fixes the read error.
1970 * This is all done synchronously while the array is
1971 * frozen
1972 */
1973 if (mddev->ro == 0) {
1974 freeze_array(conf);
1975 fix_read_error(conf, r1_bio->read_disk,
1976 r1_bio->sector,
1977 r1_bio->sectors);
1978 unfreeze_array(conf);
1979 } else
1980 md_error(mddev,
1981 conf->mirrors[r1_bio->read_disk].rdev);
1982
1983 bio = r1_bio->bios[r1_bio->read_disk];
1984 bdevname(bio->bi_bdev, b);
1985read_more:
1986 disk = read_balance(conf, r1_bio, &max_sectors);
1987 if (disk == -1) {
1988 printk(KERN_ALERT "md/raid1:%s: %s: unrecoverable I/O"
1989 " read error for block %llu\n",
1990 mdname(mddev), b,
1991 (unsigned long long)r1_bio->sector);
1992 raid_end_bio_io(r1_bio);
1993 } else {
1994 const unsigned long do_sync = r1_bio->master_bio->bi_rw & REQ_SYNC;
1995 if (bio) {
1996 r1_bio->bios[r1_bio->read_disk] =
1997 mddev->ro ? IO_BLOCKED : NULL;
1998 bio_put(bio);
1999 }
2000 r1_bio->read_disk = disk;
2001 bio = bio_clone_mddev(r1_bio->master_bio,
2002 GFP_NOIO, mddev);
2003 md_trim_bio(bio,
2004 r1_bio->sector - bio->bi_sector,
2005 max_sectors);
2006 r1_bio->bios[r1_bio->read_disk] = bio;
2007 rdev = conf->mirrors[disk].rdev;
2008 printk_ratelimited(
2009 KERN_ERR
2010 "md/raid1:%s: redirecting sector %llu"
2011 " to other mirror: %s\n",
2012 mdname(mddev),
2013 (unsigned long long)r1_bio->sector,
2014 bdevname(rdev->bdev, b));
2015 bio->bi_sector = r1_bio->sector + rdev->data_offset;
2016 bio->bi_bdev = rdev->bdev;
2017 bio->bi_end_io = raid1_end_read_request;
2018 bio->bi_rw = READ | do_sync;
2019 bio->bi_private = r1_bio;
2020 if (max_sectors < r1_bio->sectors) {
2021 /* Drat - have to split this up more */
2022 struct bio *mbio = r1_bio->master_bio;
2023 int sectors_handled =
2024 r1_bio->sector + max_sectors
2025 - mbio->bi_sector;
2026 r1_bio->sectors = max_sectors;
2027 spin_lock_irq(&conf->device_lock);
2028 if (mbio->bi_phys_segments == 0)
2029 mbio->bi_phys_segments = 2;
2030 else
2031 mbio->bi_phys_segments++;
2032 spin_unlock_irq(&conf->device_lock);
2033 generic_make_request(bio);
2034 bio = NULL;
2035
2036 r1_bio = mempool_alloc(conf->r1bio_pool,
2037 GFP_NOIO);
2038
2039 r1_bio->master_bio = mbio;
2040 r1_bio->sectors = (mbio->bi_size >> 9)
2041 - sectors_handled;
2042 r1_bio->state = 0;
2043 set_bit(R1BIO_ReadError,
2044 &r1_bio->state);
2045 r1_bio->mddev = mddev;
2046 r1_bio->sector = mbio->bi_sector
2047 + sectors_handled;
2048
2049 goto read_more;
2050 } else
2051 generic_make_request(bio);
2052 }
2053 } else {
2054 /* just a partial read to be scheduled from separate 2046 /* just a partial read to be scheduled from separate
2055 * context 2047 * context
2056 */ 2048 */
2057 generic_make_request(r1_bio->bios[r1_bio->read_disk]); 2049 generic_make_request(r1_bio->bios[r1_bio->read_disk]);
2058 } 2050
2059 cond_resched(); 2051 cond_resched();
2060 if (mddev->flags & ~(1<<MD_CHANGE_PENDING)) 2052 if (mddev->flags & ~(1<<MD_CHANGE_PENDING))
2061 md_check_recovery(mddev); 2053 md_check_recovery(mddev);