diff options
author | NeilBrown <neilb@suse.de> | 2011-07-27 21:38:13 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-07-27 21:38:13 -0400 |
commit | 62096bce231b3760882ed91205fc84682d6b0529 (patch) | |
tree | 90b8a89be6f3c1983e88a4b0fe9d5a0e15ccda7e /drivers/md/raid1.c | |
parent | 3a9f28a5117e00a868dd8b4395f9a707ae56764b (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.c | 310 |
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 | ||
1864 | static 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 | |||
1887 | static 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 | |||
1916 | static 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); | ||
1944 | read_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 | |||
1864 | static void raid1d(mddev_t *mddev) | 2006 | static 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); | ||
1985 | read_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); |