diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid5.c | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 456c3c2c961d..442622067cae 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1618,7 +1618,7 @@ static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2) | |||
1618 | } | 1618 | } |
1619 | 1619 | ||
1620 | static void | 1620 | static void |
1621 | handle_write_operations5(struct stripe_head *sh, struct stripe_head_state *s, | 1621 | schedule_reconstruction5(struct stripe_head *sh, struct stripe_head_state *s, |
1622 | int rcw, int expand) | 1622 | int rcw, int expand) |
1623 | { | 1623 | { |
1624 | int i, pd_idx = sh->pd_idx, disks = sh->disks; | 1624 | int i, pd_idx = sh->pd_idx, disks = sh->disks; |
@@ -1783,7 +1783,7 @@ static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks) | |||
1783 | } | 1783 | } |
1784 | 1784 | ||
1785 | static void | 1785 | static void |
1786 | handle_requests_to_failed_array(raid5_conf_t *conf, struct stripe_head *sh, | 1786 | handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh, |
1787 | struct stripe_head_state *s, int disks, | 1787 | struct stripe_head_state *s, int disks, |
1788 | struct bio **return_bi) | 1788 | struct bio **return_bi) |
1789 | { | 1789 | { |
@@ -1874,23 +1874,28 @@ handle_requests_to_failed_array(raid5_conf_t *conf, struct stripe_head *sh, | |||
1874 | md_wakeup_thread(conf->mddev->thread); | 1874 | md_wakeup_thread(conf->mddev->thread); |
1875 | } | 1875 | } |
1876 | 1876 | ||
1877 | /* __handle_issuing_new_read_requests5 - returns 0 if there are no more disks | 1877 | /* fetch_block5 - checks the given member device to see if its data needs |
1878 | * to process | 1878 | * to be read or computed to satisfy a request. |
1879 | * | ||
1880 | * Returns 1 when no more member devices need to be checked, otherwise returns | ||
1881 | * 0 to tell the loop in handle_stripe_fill5 to continue | ||
1879 | */ | 1882 | */ |
1880 | static int __handle_issuing_new_read_requests5(struct stripe_head *sh, | 1883 | static int fetch_block5(struct stripe_head *sh, struct stripe_head_state *s, |
1881 | struct stripe_head_state *s, int disk_idx, int disks) | 1884 | int disk_idx, int disks) |
1882 | { | 1885 | { |
1883 | struct r5dev *dev = &sh->dev[disk_idx]; | 1886 | struct r5dev *dev = &sh->dev[disk_idx]; |
1884 | struct r5dev *failed_dev = &sh->dev[s->failed_num]; | 1887 | struct r5dev *failed_dev = &sh->dev[s->failed_num]; |
1885 | 1888 | ||
1886 | /* is the data in this block needed, and can we get it? */ | 1889 | /* is the data in this block needed, and can we get it? */ |
1887 | if (!test_bit(R5_LOCKED, &dev->flags) && | 1890 | if (!test_bit(R5_LOCKED, &dev->flags) && |
1888 | !test_bit(R5_UPTODATE, &dev->flags) && (dev->toread || | 1891 | !test_bit(R5_UPTODATE, &dev->flags) && |
1889 | (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) || | 1892 | (dev->toread || |
1890 | s->syncing || s->expanding || (s->failed && | 1893 | (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) || |
1891 | (failed_dev->toread || (failed_dev->towrite && | 1894 | s->syncing || s->expanding || |
1892 | !test_bit(R5_OVERWRITE, &failed_dev->flags) | 1895 | (s->failed && |
1893 | ))))) { | 1896 | (failed_dev->toread || |
1897 | (failed_dev->towrite && | ||
1898 | !test_bit(R5_OVERWRITE, &failed_dev->flags)))))) { | ||
1894 | /* We would like to get this block, possibly by computing it, | 1899 | /* We would like to get this block, possibly by computing it, |
1895 | * otherwise read it if the backing disk is insync | 1900 | * otherwise read it if the backing disk is insync |
1896 | */ | 1901 | */ |
@@ -1908,7 +1913,7 @@ static int __handle_issuing_new_read_requests5(struct stripe_head *sh, | |||
1908 | * subsequent operation. | 1913 | * subsequent operation. |
1909 | */ | 1914 | */ |
1910 | s->uptodate++; | 1915 | s->uptodate++; |
1911 | return 0; /* uptodate + compute == disks */ | 1916 | return 1; /* uptodate + compute == disks */ |
1912 | } else if (test_bit(R5_Insync, &dev->flags)) { | 1917 | } else if (test_bit(R5_Insync, &dev->flags)) { |
1913 | set_bit(R5_LOCKED, &dev->flags); | 1918 | set_bit(R5_LOCKED, &dev->flags); |
1914 | set_bit(R5_Wantread, &dev->flags); | 1919 | set_bit(R5_Wantread, &dev->flags); |
@@ -1918,10 +1923,13 @@ static int __handle_issuing_new_read_requests5(struct stripe_head *sh, | |||
1918 | } | 1923 | } |
1919 | } | 1924 | } |
1920 | 1925 | ||
1921 | return ~0; | 1926 | return 0; |
1922 | } | 1927 | } |
1923 | 1928 | ||
1924 | static void handle_issuing_new_read_requests5(struct stripe_head *sh, | 1929 | /** |
1930 | * handle_stripe_fill5 - read or compute data to satisfy pending requests. | ||
1931 | */ | ||
1932 | static void handle_stripe_fill5(struct stripe_head *sh, | ||
1925 | struct stripe_head_state *s, int disks) | 1933 | struct stripe_head_state *s, int disks) |
1926 | { | 1934 | { |
1927 | int i; | 1935 | int i; |
@@ -1931,16 +1939,14 @@ static void handle_issuing_new_read_requests5(struct stripe_head *sh, | |||
1931 | * midst of changing due to a write | 1939 | * midst of changing due to a write |
1932 | */ | 1940 | */ |
1933 | if (!test_bit(STRIPE_COMPUTE_RUN, &sh->state) && !sh->check_state && | 1941 | if (!test_bit(STRIPE_COMPUTE_RUN, &sh->state) && !sh->check_state && |
1934 | !sh->reconstruct_state) { | 1942 | !sh->reconstruct_state) |
1935 | for (i = disks; i--; ) | 1943 | for (i = disks; i--; ) |
1936 | if (__handle_issuing_new_read_requests5( | 1944 | if (fetch_block5(sh, s, i, disks)) |
1937 | sh, s, i, disks) == 0) | ||
1938 | break; | 1945 | break; |
1939 | } | ||
1940 | set_bit(STRIPE_HANDLE, &sh->state); | 1946 | set_bit(STRIPE_HANDLE, &sh->state); |
1941 | } | 1947 | } |
1942 | 1948 | ||
1943 | static void handle_issuing_new_read_requests6(struct stripe_head *sh, | 1949 | static void handle_stripe_fill6(struct stripe_head *sh, |
1944 | struct stripe_head_state *s, struct r6_state *r6s, | 1950 | struct stripe_head_state *s, struct r6_state *r6s, |
1945 | int disks) | 1951 | int disks) |
1946 | { | 1952 | { |
@@ -1999,12 +2005,12 @@ static void handle_issuing_new_read_requests6(struct stripe_head *sh, | |||
1999 | } | 2005 | } |
2000 | 2006 | ||
2001 | 2007 | ||
2002 | /* handle_completed_write_requests | 2008 | /* handle_stripe_clean_event |
2003 | * any written block on an uptodate or failed drive can be returned. | 2009 | * any written block on an uptodate or failed drive can be returned. |
2004 | * Note that if we 'wrote' to a failed drive, it will be UPTODATE, but | 2010 | * Note that if we 'wrote' to a failed drive, it will be UPTODATE, but |
2005 | * never LOCKED, so we don't need to test 'failed' directly. | 2011 | * never LOCKED, so we don't need to test 'failed' directly. |
2006 | */ | 2012 | */ |
2007 | static void handle_completed_write_requests(raid5_conf_t *conf, | 2013 | static void handle_stripe_clean_event(raid5_conf_t *conf, |
2008 | struct stripe_head *sh, int disks, struct bio **return_bi) | 2014 | struct stripe_head *sh, int disks, struct bio **return_bi) |
2009 | { | 2015 | { |
2010 | int i; | 2016 | int i; |
@@ -2049,7 +2055,7 @@ static void handle_completed_write_requests(raid5_conf_t *conf, | |||
2049 | md_wakeup_thread(conf->mddev->thread); | 2055 | md_wakeup_thread(conf->mddev->thread); |
2050 | } | 2056 | } |
2051 | 2057 | ||
2052 | static void handle_issuing_new_write_requests5(raid5_conf_t *conf, | 2058 | static void handle_stripe_dirtying5(raid5_conf_t *conf, |
2053 | struct stripe_head *sh, struct stripe_head_state *s, int disks) | 2059 | struct stripe_head *sh, struct stripe_head_state *s, int disks) |
2054 | { | 2060 | { |
2055 | int rmw = 0, rcw = 0, i; | 2061 | int rmw = 0, rcw = 0, i; |
@@ -2136,10 +2142,10 @@ static void handle_issuing_new_write_requests5(raid5_conf_t *conf, | |||
2136 | if ((s->req_compute || !test_bit(STRIPE_COMPUTE_RUN, &sh->state)) && | 2142 | if ((s->req_compute || !test_bit(STRIPE_COMPUTE_RUN, &sh->state)) && |
2137 | (s->locked == 0 && (rcw == 0 || rmw == 0) && | 2143 | (s->locked == 0 && (rcw == 0 || rmw == 0) && |
2138 | !test_bit(STRIPE_BIT_DELAY, &sh->state))) | 2144 | !test_bit(STRIPE_BIT_DELAY, &sh->state))) |
2139 | handle_write_operations5(sh, s, rcw == 0, 0); | 2145 | schedule_reconstruction5(sh, s, rcw == 0, 0); |
2140 | } | 2146 | } |
2141 | 2147 | ||
2142 | static void handle_issuing_new_write_requests6(raid5_conf_t *conf, | 2148 | static void handle_stripe_dirtying6(raid5_conf_t *conf, |
2143 | struct stripe_head *sh, struct stripe_head_state *s, | 2149 | struct stripe_head *sh, struct stripe_head_state *s, |
2144 | struct r6_state *r6s, int disks) | 2150 | struct r6_state *r6s, int disks) |
2145 | { | 2151 | { |
@@ -2597,8 +2603,7 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2597 | * need to be failed | 2603 | * need to be failed |
2598 | */ | 2604 | */ |
2599 | if (s.failed > 1 && s.to_read+s.to_write+s.written) | 2605 | if (s.failed > 1 && s.to_read+s.to_write+s.written) |
2600 | handle_requests_to_failed_array(conf, sh, &s, disks, | 2606 | handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
2601 | &return_bi); | ||
2602 | if (s.failed > 1 && s.syncing) { | 2607 | if (s.failed > 1 && s.syncing) { |
2603 | md_done_sync(conf->mddev, STRIPE_SECTORS,0); | 2608 | md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
2604 | clear_bit(STRIPE_SYNCING, &sh->state); | 2609 | clear_bit(STRIPE_SYNCING, &sh->state); |
@@ -2614,7 +2619,7 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2614 | !test_bit(R5_LOCKED, &dev->flags) && | 2619 | !test_bit(R5_LOCKED, &dev->flags) && |
2615 | test_bit(R5_UPTODATE, &dev->flags)) || | 2620 | test_bit(R5_UPTODATE, &dev->flags)) || |
2616 | (s.failed == 1 && s.failed_num == sh->pd_idx))) | 2621 | (s.failed == 1 && s.failed_num == sh->pd_idx))) |
2617 | handle_completed_write_requests(conf, sh, disks, &return_bi); | 2622 | handle_stripe_clean_event(conf, sh, disks, &return_bi); |
2618 | 2623 | ||
2619 | /* Now we might consider reading some blocks, either to check/generate | 2624 | /* Now we might consider reading some blocks, either to check/generate |
2620 | * parity, or to satisfy requests | 2625 | * parity, or to satisfy requests |
@@ -2622,7 +2627,7 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2622 | */ | 2627 | */ |
2623 | if (s.to_read || s.non_overwrite || | 2628 | if (s.to_read || s.non_overwrite || |
2624 | (s.syncing && (s.uptodate + s.compute < disks)) || s.expanding) | 2629 | (s.syncing && (s.uptodate + s.compute < disks)) || s.expanding) |
2625 | handle_issuing_new_read_requests5(sh, &s, disks); | 2630 | handle_stripe_fill5(sh, &s, disks); |
2626 | 2631 | ||
2627 | /* Now we check to see if any write operations have recently | 2632 | /* Now we check to see if any write operations have recently |
2628 | * completed | 2633 | * completed |
@@ -2666,7 +2671,7 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2666 | * block. | 2671 | * block. |
2667 | */ | 2672 | */ |
2668 | if (s.to_write && !sh->reconstruct_state && !sh->check_state) | 2673 | if (s.to_write && !sh->reconstruct_state && !sh->check_state) |
2669 | handle_issuing_new_write_requests5(conf, sh, &s, disks); | 2674 | handle_stripe_dirtying5(conf, sh, &s, disks); |
2670 | 2675 | ||
2671 | /* maybe we need to check and possibly fix the parity for this stripe | 2676 | /* maybe we need to check and possibly fix the parity for this stripe |
2672 | * Any reads will already have been scheduled, so we just see if enough | 2677 | * Any reads will already have been scheduled, so we just see if enough |
@@ -2722,7 +2727,7 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2722 | sh->disks = conf->raid_disks; | 2727 | sh->disks = conf->raid_disks; |
2723 | sh->pd_idx = stripe_to_pdidx(sh->sector, conf, | 2728 | sh->pd_idx = stripe_to_pdidx(sh->sector, conf, |
2724 | conf->raid_disks); | 2729 | conf->raid_disks); |
2725 | handle_write_operations5(sh, &s, 1, 1); | 2730 | schedule_reconstruction5(sh, &s, 1, 1); |
2726 | } else if (s.expanded && !sh->reconstruct_state && s.locked == 0) { | 2731 | } else if (s.expanded && !sh->reconstruct_state && s.locked == 0) { |
2727 | clear_bit(STRIPE_EXPAND_READY, &sh->state); | 2732 | clear_bit(STRIPE_EXPAND_READY, &sh->state); |
2728 | atomic_dec(&conf->reshape_stripes); | 2733 | atomic_dec(&conf->reshape_stripes); |
@@ -2854,8 +2859,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
2854 | * might need to be failed | 2859 | * might need to be failed |
2855 | */ | 2860 | */ |
2856 | if (s.failed > 2 && s.to_read+s.to_write+s.written) | 2861 | if (s.failed > 2 && s.to_read+s.to_write+s.written) |
2857 | handle_requests_to_failed_array(conf, sh, &s, disks, | 2862 | handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
2858 | &return_bi); | ||
2859 | if (s.failed > 2 && s.syncing) { | 2863 | if (s.failed > 2 && s.syncing) { |
2860 | md_done_sync(conf->mddev, STRIPE_SECTORS,0); | 2864 | md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
2861 | clear_bit(STRIPE_SYNCING, &sh->state); | 2865 | clear_bit(STRIPE_SYNCING, &sh->state); |
@@ -2880,7 +2884,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
2880 | ( r6s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | 2884 | ( r6s.q_failed || ((test_bit(R5_Insync, &qdev->flags) |
2881 | && !test_bit(R5_LOCKED, &qdev->flags) | 2885 | && !test_bit(R5_LOCKED, &qdev->flags) |
2882 | && test_bit(R5_UPTODATE, &qdev->flags))))) | 2886 | && test_bit(R5_UPTODATE, &qdev->flags))))) |
2883 | handle_completed_write_requests(conf, sh, disks, &return_bi); | 2887 | handle_stripe_clean_event(conf, sh, disks, &return_bi); |
2884 | 2888 | ||
2885 | /* Now we might consider reading some blocks, either to check/generate | 2889 | /* Now we might consider reading some blocks, either to check/generate |
2886 | * parity, or to satisfy requests | 2890 | * parity, or to satisfy requests |
@@ -2888,11 +2892,11 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
2888 | */ | 2892 | */ |
2889 | if (s.to_read || s.non_overwrite || (s.to_write && s.failed) || | 2893 | if (s.to_read || s.non_overwrite || (s.to_write && s.failed) || |
2890 | (s.syncing && (s.uptodate < disks)) || s.expanding) | 2894 | (s.syncing && (s.uptodate < disks)) || s.expanding) |
2891 | handle_issuing_new_read_requests6(sh, &s, &r6s, disks); | 2895 | handle_stripe_fill6(sh, &s, &r6s, disks); |
2892 | 2896 | ||
2893 | /* now to consider writing and what else, if anything should be read */ | 2897 | /* now to consider writing and what else, if anything should be read */ |
2894 | if (s.to_write) | 2898 | if (s.to_write) |
2895 | handle_issuing_new_write_requests6(conf, sh, &s, &r6s, disks); | 2899 | handle_stripe_dirtying6(conf, sh, &s, &r6s, disks); |
2896 | 2900 | ||
2897 | /* maybe we need to check and possibly fix the parity for this stripe | 2901 | /* maybe we need to check and possibly fix the parity for this stripe |
2898 | * Any reads will already have been scheduled, so we just see if enough | 2902 | * Any reads will already have been scheduled, so we just see if enough |