aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-04-20 00:13:34 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-12 18:02:30 -0400
commit5c0bdba0714bef2917ec866f7c9ed112cb45d7ab (patch)
tree47f28309e7a57ca68523de39ad46a5edea2c8411
parentf483fae216ef77d997d2f38873d274b6a9f6ecdf (diff)
md/raid5: allow for more than 2^31 chunks.
commit 35f2a591192d0a5d9f7fc696869c76f0b8e49c3d upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-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 ceb24afdc147..f7d7b2e5abb4 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1649,8 +1649,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
1649 int previous, int *dd_idx, 1649 int previous, int *dd_idx,
1650 struct stripe_head *sh) 1650 struct stripe_head *sh)
1651{ 1651{
1652 long stripe; 1652 sector_t stripe;
1653 unsigned long chunk_number; 1653 sector_t chunk_number;
1654 unsigned int chunk_offset; 1654 unsigned int chunk_offset;
1655 int pd_idx, qd_idx; 1655 int pd_idx, qd_idx;
1656 int ddf_layout = 0; 1656 int ddf_layout = 0;
@@ -1670,17 +1670,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
1670 */ 1670 */
1671 chunk_offset = sector_div(r_sector, sectors_per_chunk); 1671 chunk_offset = sector_div(r_sector, sectors_per_chunk);
1672 chunk_number = r_sector; 1672 chunk_number = r_sector;
1673 BUG_ON(r_sector != chunk_number);
1674 1673
1675 /* 1674 /*
1676 * Compute the stripe number 1675 * Compute the stripe number
1677 */ 1676 */
1678 stripe = chunk_number / data_disks; 1677 stripe = chunk_number;
1679 1678 *dd_idx = sector_div(stripe, data_disks);
1680 /*
1681 * Compute the data disk and parity disk indexes inside the stripe
1682 */
1683 *dd_idx = chunk_number % data_disks;
1684 1679
1685 /* 1680 /*
1686 * Select the parity disk based on the user selected algorithm. 1681 * Select the parity disk based on the user selected algorithm.
@@ -1869,14 +1864,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
1869 : conf->algorithm; 1864 : conf->algorithm;
1870 sector_t stripe; 1865 sector_t stripe;
1871 int chunk_offset; 1866 int chunk_offset;
1872 int chunk_number, dummy1, dd_idx = i; 1867 sector_t chunk_number;
1868 int dummy1, dd_idx = i;
1873 sector_t r_sector; 1869 sector_t r_sector;
1874 struct stripe_head sh2; 1870 struct stripe_head sh2;
1875 1871
1876 1872
1877 chunk_offset = sector_div(new_sector, sectors_per_chunk); 1873 chunk_offset = sector_div(new_sector, sectors_per_chunk);
1878 stripe = new_sector; 1874 stripe = new_sector;
1879 BUG_ON(new_sector != stripe);
1880 1875
1881 if (i == sh->pd_idx) 1876 if (i == sh->pd_idx)
1882 return 0; 1877 return 0;
@@ -1969,7 +1964,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
1969 } 1964 }
1970 1965
1971 chunk_number = stripe * data_disks + i; 1966 chunk_number = stripe * data_disks + i;
1972 r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; 1967 r_sector = chunk_number * sectors_per_chunk + chunk_offset;
1973 1968
1974 check = raid5_compute_sector(conf, r_sector, 1969 check = raid5_compute_sector(conf, r_sector,
1975 previous, &dummy1, &sh2); 1970 previous, &dummy1, &sh2);