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