diff options
Diffstat (limited to 'drivers/md/raid5.c')
| -rw-r--r-- | drivers/md/raid5.c | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e3e9a36ea3b7..58ea0ecae7c3 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -1650,8 +1650,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1650 | int previous, int *dd_idx, | 1650 | int previous, int *dd_idx, |
| 1651 | struct stripe_head *sh) | 1651 | struct stripe_head *sh) |
| 1652 | { | 1652 | { |
| 1653 | long stripe; | 1653 | sector_t stripe, stripe2; |
| 1654 | unsigned long chunk_number; | 1654 | sector_t chunk_number; |
| 1655 | unsigned int chunk_offset; | 1655 | unsigned int chunk_offset; |
| 1656 | int pd_idx, qd_idx; | 1656 | int pd_idx, qd_idx; |
| 1657 | int ddf_layout = 0; | 1657 | int ddf_layout = 0; |
| @@ -1671,18 +1671,13 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1671 | */ | 1671 | */ |
| 1672 | chunk_offset = sector_div(r_sector, sectors_per_chunk); | 1672 | chunk_offset = sector_div(r_sector, sectors_per_chunk); |
| 1673 | chunk_number = r_sector; | 1673 | chunk_number = r_sector; |
| 1674 | BUG_ON(r_sector != chunk_number); | ||
| 1675 | 1674 | ||
| 1676 | /* | 1675 | /* |
| 1677 | * Compute the stripe number | 1676 | * Compute the stripe number |
| 1678 | */ | 1677 | */ |
| 1679 | stripe = chunk_number / data_disks; | 1678 | stripe = chunk_number; |
| 1680 | 1679 | *dd_idx = sector_div(stripe, data_disks); | |
| 1681 | /* | 1680 | stripe2 = stripe; |
| 1682 | * Compute the data disk and parity disk indexes inside the stripe | ||
| 1683 | */ | ||
| 1684 | *dd_idx = chunk_number % data_disks; | ||
| 1685 | |||
| 1686 | /* | 1681 | /* |
| 1687 | * Select the parity disk based on the user selected algorithm. | 1682 | * Select the parity disk based on the user selected algorithm. |
| 1688 | */ | 1683 | */ |
| @@ -1694,21 +1689,21 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1694 | case 5: | 1689 | case 5: |
| 1695 | switch (algorithm) { | 1690 | switch (algorithm) { |
| 1696 | case ALGORITHM_LEFT_ASYMMETRIC: | 1691 | case ALGORITHM_LEFT_ASYMMETRIC: |
| 1697 | pd_idx = data_disks - stripe % raid_disks; | 1692 | pd_idx = data_disks - sector_div(stripe2, raid_disks); |
| 1698 | if (*dd_idx >= pd_idx) | 1693 | if (*dd_idx >= pd_idx) |
| 1699 | (*dd_idx)++; | 1694 | (*dd_idx)++; |
| 1700 | break; | 1695 | break; |
| 1701 | case ALGORITHM_RIGHT_ASYMMETRIC: | 1696 | case ALGORITHM_RIGHT_ASYMMETRIC: |
| 1702 | pd_idx = stripe % raid_disks; | 1697 | pd_idx = sector_div(stripe2, raid_disks); |
| 1703 | if (*dd_idx >= pd_idx) | 1698 | if (*dd_idx >= pd_idx) |
| 1704 | (*dd_idx)++; | 1699 | (*dd_idx)++; |
| 1705 | break; | 1700 | break; |
| 1706 | case ALGORITHM_LEFT_SYMMETRIC: | 1701 | case ALGORITHM_LEFT_SYMMETRIC: |
| 1707 | pd_idx = data_disks - stripe % raid_disks; | 1702 | pd_idx = data_disks - sector_div(stripe2, raid_disks); |
| 1708 | *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; | 1703 | *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; |
| 1709 | break; | 1704 | break; |
| 1710 | case ALGORITHM_RIGHT_SYMMETRIC: | 1705 | case ALGORITHM_RIGHT_SYMMETRIC: |
| 1711 | pd_idx = stripe % raid_disks; | 1706 | pd_idx = sector_div(stripe2, raid_disks); |
| 1712 | *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; | 1707 | *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; |
| 1713 | break; | 1708 | break; |
| 1714 | case ALGORITHM_PARITY_0: | 1709 | case ALGORITHM_PARITY_0: |
| @@ -1728,7 +1723,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1728 | 1723 | ||
| 1729 | switch (algorithm) { | 1724 | switch (algorithm) { |
| 1730 | case ALGORITHM_LEFT_ASYMMETRIC: | 1725 | case ALGORITHM_LEFT_ASYMMETRIC: |
| 1731 | pd_idx = raid_disks - 1 - (stripe % raid_disks); | 1726 | pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); |
| 1732 | qd_idx = pd_idx + 1; | 1727 | qd_idx = pd_idx + 1; |
| 1733 | if (pd_idx == raid_disks-1) { | 1728 | if (pd_idx == raid_disks-1) { |
| 1734 | (*dd_idx)++; /* Q D D D P */ | 1729 | (*dd_idx)++; /* Q D D D P */ |
| @@ -1737,7 +1732,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1737 | (*dd_idx) += 2; /* D D P Q D */ | 1732 | (*dd_idx) += 2; /* D D P Q D */ |
| 1738 | break; | 1733 | break; |
| 1739 | case ALGORITHM_RIGHT_ASYMMETRIC: | 1734 | case ALGORITHM_RIGHT_ASYMMETRIC: |
| 1740 | pd_idx = stripe % raid_disks; | 1735 | pd_idx = sector_div(stripe2, raid_disks); |
| 1741 | qd_idx = pd_idx + 1; | 1736 | qd_idx = pd_idx + 1; |
| 1742 | if (pd_idx == raid_disks-1) { | 1737 | if (pd_idx == raid_disks-1) { |
| 1743 | (*dd_idx)++; /* Q D D D P */ | 1738 | (*dd_idx)++; /* Q D D D P */ |
| @@ -1746,12 +1741,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1746 | (*dd_idx) += 2; /* D D P Q D */ | 1741 | (*dd_idx) += 2; /* D D P Q D */ |
| 1747 | break; | 1742 | break; |
| 1748 | case ALGORITHM_LEFT_SYMMETRIC: | 1743 | case ALGORITHM_LEFT_SYMMETRIC: |
| 1749 | pd_idx = raid_disks - 1 - (stripe % raid_disks); | 1744 | pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); |
| 1750 | qd_idx = (pd_idx + 1) % raid_disks; | 1745 | qd_idx = (pd_idx + 1) % raid_disks; |
| 1751 | *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; | 1746 | *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; |
| 1752 | break; | 1747 | break; |
| 1753 | case ALGORITHM_RIGHT_SYMMETRIC: | 1748 | case ALGORITHM_RIGHT_SYMMETRIC: |
| 1754 | pd_idx = stripe % raid_disks; | 1749 | pd_idx = sector_div(stripe2, raid_disks); |
| 1755 | qd_idx = (pd_idx + 1) % raid_disks; | 1750 | qd_idx = (pd_idx + 1) % raid_disks; |
| 1756 | *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; | 1751 | *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; |
| 1757 | break; | 1752 | break; |
| @@ -1770,7 +1765,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1770 | /* Exactly the same as RIGHT_ASYMMETRIC, but or | 1765 | /* Exactly the same as RIGHT_ASYMMETRIC, but or |
| 1771 | * of blocks for computing Q is different. | 1766 | * of blocks for computing Q is different. |
| 1772 | */ | 1767 | */ |
| 1773 | pd_idx = stripe % raid_disks; | 1768 | pd_idx = sector_div(stripe2, raid_disks); |
| 1774 | qd_idx = pd_idx + 1; | 1769 | qd_idx = pd_idx + 1; |
| 1775 | if (pd_idx == raid_disks-1) { | 1770 | if (pd_idx == raid_disks-1) { |
| 1776 | (*dd_idx)++; /* Q D D D P */ | 1771 | (*dd_idx)++; /* Q D D D P */ |
| @@ -1785,7 +1780,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1785 | * D D D P Q rather than | 1780 | * D D D P Q rather than |
| 1786 | * Q D D D P | 1781 | * Q D D D P |
| 1787 | */ | 1782 | */ |
| 1788 | pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks); | 1783 | stripe2 += 1; |
| 1784 | pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); | ||
| 1789 | qd_idx = pd_idx + 1; | 1785 | qd_idx = pd_idx + 1; |
| 1790 | if (pd_idx == raid_disks-1) { | 1786 | if (pd_idx == raid_disks-1) { |
| 1791 | (*dd_idx)++; /* Q D D D P */ | 1787 | (*dd_idx)++; /* Q D D D P */ |
| @@ -1797,7 +1793,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1797 | 1793 | ||
| 1798 | case ALGORITHM_ROTATING_N_CONTINUE: | 1794 | case ALGORITHM_ROTATING_N_CONTINUE: |
| 1799 | /* Same as left_symmetric but Q is before P */ | 1795 | /* Same as left_symmetric but Q is before P */ |
| 1800 | pd_idx = raid_disks - 1 - (stripe % raid_disks); | 1796 | pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); |
| 1801 | qd_idx = (pd_idx + raid_disks - 1) % raid_disks; | 1797 | qd_idx = (pd_idx + raid_disks - 1) % raid_disks; |
| 1802 | *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; | 1798 | *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; |
| 1803 | ddf_layout = 1; | 1799 | ddf_layout = 1; |
| @@ -1805,27 +1801,27 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
| 1805 | 1801 | ||
| 1806 | case ALGORITHM_LEFT_ASYMMETRIC_6: | 1802 | case ALGORITHM_LEFT_ASYMMETRIC_6: |
| 1807 | /* RAID5 left_asymmetric, with Q on last device */ | 1803 | /* RAID5 left_asymmetric, with Q on last device */ |
| 1808 | pd_idx = data_disks - stripe % (raid_disks-1); | 1804 | pd_idx = data_disks - sector_div(stripe2, raid_disks-1); |
| 1809 | if (*dd_idx >= pd_idx) | 1805 | if (*dd_idx >= pd_idx) |
| 1810 | (*dd_idx)++; | 1806 | (*dd_idx)++; |
| 1811 | qd_idx = raid_disks - 1; | 1807 | qd_idx = raid_disks - 1; |
| 1812 | break; | 1808 | break; |
| 1813 | 1809 | ||
| 1814 | case ALGORITHM_RIGHT_ASYMMETRIC_6: | 1810 | case ALGORITHM_RIGHT_ASYMMETRIC_6: |
| 1815 | pd_idx = stripe % (raid_disks-1); | 1811 | pd_idx = sector_div(stripe2, raid_disks-1); |
| 1816 | if (*dd_idx >= pd_idx) | 1812 | if (*dd_idx >= pd_idx) |
| 1817 | (*dd_idx)++; | 1813 | (*dd_idx)++; |
| 1818 | qd_idx = raid_disks - 1; | 1814 | qd_idx = raid_disks - 1; |
| 1819 | break; | 1815 | break; |
| 1820 | 1816 | ||
| 1821 | case ALGORITHM_LEFT_SYMMETRIC_6: | 1817 | case ALGORITHM_LEFT_SYMMETRIC_6: |
| 1822 | pd_idx = data_disks - stripe % (raid_disks-1); | 1818 | pd_idx = data_disks - sector_div(stripe2, raid_disks-1); |
| 1823 | *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); | 1819 | *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); |
| 1824 | qd_idx = raid_disks - 1; | 1820 | qd_idx = raid_disks - 1; |
| 1825 | break; | 1821 | break; |
| 1826 | 1822 | ||
| 1827 | case ALGORITHM_RIGHT_SYMMETRIC_6: | 1823 | case ALGORITHM_RIGHT_SYMMETRIC_6: |
| 1828 | pd_idx = stripe % (raid_disks-1); | 1824 | pd_idx = sector_div(stripe2, raid_disks-1); |
| 1829 | *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); | 1825 | *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); |
| 1830 | qd_idx = raid_disks - 1; | 1826 | qd_idx = raid_disks - 1; |
| 1831 | break; | 1827 | break; |
| @@ -1870,14 +1866,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) | |||
| 1870 | : conf->algorithm; | 1866 | : conf->algorithm; |
| 1871 | sector_t stripe; | 1867 | sector_t stripe; |
| 1872 | int chunk_offset; | 1868 | int chunk_offset; |
| 1873 | int chunk_number, dummy1, dd_idx = i; | 1869 | sector_t chunk_number; |
| 1870 | int dummy1, dd_idx = i; | ||
| 1874 | sector_t r_sector; | 1871 | sector_t r_sector; |
| 1875 | struct stripe_head sh2; | 1872 | struct stripe_head sh2; |
| 1876 | 1873 | ||
| 1877 | 1874 | ||
| 1878 | chunk_offset = sector_div(new_sector, sectors_per_chunk); | 1875 | chunk_offset = sector_div(new_sector, sectors_per_chunk); |
| 1879 | stripe = new_sector; | 1876 | stripe = new_sector; |
| 1880 | BUG_ON(new_sector != stripe); | ||
| 1881 | 1877 | ||
| 1882 | if (i == sh->pd_idx) | 1878 | if (i == sh->pd_idx) |
| 1883 | return 0; | 1879 | return 0; |
| @@ -1970,7 +1966,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) | |||
| 1970 | } | 1966 | } |
| 1971 | 1967 | ||
| 1972 | chunk_number = stripe * data_disks + i; | 1968 | chunk_number = stripe * data_disks + i; |
| 1973 | r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; | 1969 | r_sector = chunk_number * sectors_per_chunk + chunk_offset; |
| 1974 | 1970 | ||
| 1975 | check = raid5_compute_sector(conf, r_sector, | 1971 | check = raid5_compute_sector(conf, r_sector, |
| 1976 | previous, &dummy1, &sh2); | 1972 | previous, &dummy1, &sh2); |
