Re: device-mapper: fix TB stripe data corruption

From: Kevin Corry
Date: Fri Jan 21 2005 - 17:19:30 EST


On Friday 21 January 2005 3:20 pm, Roland Dreier wrote:
> Kevin> We have to take a mod of the chunk value and the number of
> Kevin> stripes (which can be a non-power-of-2, so a shift won't
> Kevin> work). It's been my understanding that you couldn't mod a
> Kevin> 64-bit value with a 32-bit value in the kernel.
>
> If I understand you correctly, do_div() (defined in <asm/div64.h>)
> does what you need. Look at asm-generic/div64.h for a good
> description of the precise semantics of do_div().

Thanks for the tip, Roland. That seems to be exactly what we needed. Here's a
different version of Alasdair's patch that changes chunk to 64-bit and uses
do_div().

--
Kevin Corry
kevcorry@xxxxxxxxxx
http://evms.sourceforge.net/


In stripe_map(), change chunk to 64-bit and use do_div to divide and mod by
the number of stripes.

--- diff/drivers/md/dm-stripe.c 2005-01-21 15:55:02.093379864 -0600
+++ source/drivers/md/dm-stripe.c 2005-01-21 15:54:25.400957960 -0600
@@ -173,9 +173,8 @@
struct stripe_c *sc = (struct stripe_c *) ti->private;

sector_t offset = bio->bi_sector - ti->begin;
- uint32_t chunk = (uint32_t) (offset >> sc->chunk_shift);
- uint32_t stripe = chunk % sc->stripes; /* 32bit modulus */
- chunk = chunk / sc->stripes;
+ sector_t chunk = offset >> sc->chunk_shift;
+ uint32_t stripe = do_div(chunk, sc->stripes);

bio->bi_bdev = sc->stripe[stripe].dev->bdev;
bio->bi_sector = sc->stripe[stripe].physical_start +
@@ -210,7 +209,7 @@

static struct target_type stripe_target = {
.name = "striped",
- .version= {1, 0, 1},
+ .version= {1, 0, 2},
.module = THIS_MODULE,
.ctr = stripe_ctr,
.dtr = stripe_dtr,
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/