aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-04-20 00:13:34 -0400
committerNeilBrown <neilb@suse.de>2010-04-20 00:13:34 -0400
commit35f2a591192d0a5d9f7fc696869c76f0b8e49c3d (patch)
tree2b4cdbe2824a936f136fa0eb0dbd2db84927b057 /drivers/md
parent85341c61361cc45a9cc0e11c01e8f4479ef460ac (diff)
md/raid5: allow for more than 2^31 chunks.
With many large drives and small chunk sizes it is possible to create a RAID5 with more than 2^31 chunks. Make sure this works. Reported-by: Brett King <king.br@gmail.com> Signed-off-by: NeilBrown <neilb@suse.de> Cc: stable@kernel.org
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid5.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index e3e9a36ea3b7..20e48401910e 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;
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,17 +1671,12 @@ 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 /*
1682 * Compute the data disk and parity disk indexes inside the stripe
1683 */
1684 *dd_idx = chunk_number % data_disks;
1685 1680
1686 /* 1681 /*
1687 * Select the parity disk based on the user selected algorithm. 1682 * Select the parity disk based on the user selected algorithm.
@@ -1870,14 +1865,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
1870 : conf->algorithm; 1865 : conf->algorithm;
1871 sector_t stripe; 1866 sector_t stripe;
1872 int chunk_offset; 1867 int chunk_offset;
1873 int chunk_number, dummy1, dd_idx = i; 1868 sector_t chunk_number;
1869 int dummy1, dd_idx = i;
1874 sector_t r_sector; 1870 sector_t r_sector;
1875 struct stripe_head sh2; 1871 struct stripe_head sh2;
1876 1872
1877 1873
1878 chunk_offset = sector_div(new_sector, sectors_per_chunk); 1874 chunk_offset = sector_div(new_sector, sectors_per_chunk);
1879 stripe = new_sector; 1875 stripe = new_sector;
1880 BUG_ON(new_sector != stripe);
1881 1876
1882 if (i == sh->pd_idx) 1877 if (i == sh->pd_idx)
1883 return 0; 1878 return 0;
@@ -1970,7 +1965,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
1970 } 1965 }
1971 1966
1972 chunk_number = stripe * data_disks + i; 1967 chunk_number = stripe * data_disks + i;
1973 r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; 1968 r_sector = chunk_number * sectors_per_chunk + chunk_offset;
1974 1969
1975 check = raid5_compute_sector(conf, r_sector, 1970 check = raid5_compute_sector(conf, r_sector,
1976 previous, &dummy1, &sh2); 1971 previous, &dummy1, &sh2);