]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
md/raid5: allow for more than 2^31 chunks.
authorNeilBrown <neilb@suse.de>
Tue, 20 Apr 2010 04:13:34 +0000 (14:13 +1000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 12 May 2010 22:02:30 +0000 (15:02 -0700)
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>
drivers/md/raid5.c

index ceb24afdc147aada31741b10213443375617257f..f7d7b2e5abb46fb6fd0604f10408eabab8e060fd 100644 (file)
@@ -1649,8 +1649,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                                     int previous, int *dd_idx,
                                     struct stripe_head *sh)
 {
-       long stripe;
-       unsigned long chunk_number;
+       sector_t stripe;
+       sector_t chunk_number;
        unsigned int chunk_offset;
        int pd_idx, qd_idx;
        int ddf_layout = 0;
@@ -1670,17 +1670,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
         */
        chunk_offset = sector_div(r_sector, sectors_per_chunk);
        chunk_number = r_sector;
-       BUG_ON(r_sector != chunk_number);
 
        /*
         * Compute the stripe number
         */
-       stripe = chunk_number / data_disks;
-
-       /*
-        * Compute the data disk and parity disk indexes inside the stripe
-        */
-       *dd_idx = chunk_number % data_disks;
+       stripe = chunk_number;
+       *dd_idx = sector_div(stripe, data_disks);
 
        /*
         * 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)
                                 : conf->algorithm;
        sector_t stripe;
        int chunk_offset;
-       int chunk_number, dummy1, dd_idx = i;
+       sector_t chunk_number;
+       int dummy1, dd_idx = i;
        sector_t r_sector;
        struct stripe_head sh2;
 
 
        chunk_offset = sector_div(new_sector, sectors_per_chunk);
        stripe = new_sector;
-       BUG_ON(new_sector != stripe);
 
        if (i == sh->pd_idx)
                return 0;
@@ -1969,7 +1964,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
        }
 
        chunk_number = stripe * data_disks + i;
-       r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
+       r_sector = chunk_number * sectors_per_chunk + chunk_offset;
 
        check = raid5_compute_sector(conf, r_sector,
                                     previous, &dummy1, &sh2);