diff options
author | NeilBrown <neilb@suse.de> | 2010-04-20 00:13:34 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-12 18:02:30 -0400 |
commit | 5c0bdba0714bef2917ec866f7c9ed112cb45d7ab (patch) | |
tree | 47f28309e7a57ca68523de39ad46a5edea2c8411 | |
parent | f483fae216ef77d997d2f38873d274b6a9f6ecdf (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.c | 19 |
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); |