dm: support non power of two target max_io_len
[deliverable/linux.git] / drivers / md / dm-stripe.c
index 35c94ff24ad5867917ed715a8ce387fbb8d3b150..992c9d4c3bd93f42d8b95f19919939f293cb2ede 100644 (file)
@@ -26,7 +26,6 @@ struct stripe {
 struct stripe_c {
        uint32_t stripes;
        int stripes_shift;
-       sector_t stripes_mask;
 
        /* The size of this target / num. stripes */
        sector_t stripe_width;
@@ -99,7 +98,6 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        sector_t width;
        uint32_t stripes;
        uint32_t chunk_size;
-       char *end;
        int r;
        unsigned int i;
 
@@ -108,14 +106,12 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                return -EINVAL;
        }
 
-       stripes = simple_strtoul(argv[0], &end, 10);
-       if (!stripes || *end) {
+       if (kstrtouint(argv[0], 10, &stripes) || !stripes) {
                ti->error = "Invalid stripe count";
                return -EINVAL;
        }
 
-       chunk_size = simple_strtoul(argv[1], &end, 10);
-       if (*end) {
+       if (kstrtouint(argv[1], 10, &chunk_size)) {
                ti->error = "Invalid chunk_size";
                return -EINVAL;
        }
@@ -135,7 +131,6 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                return -EINVAL;
        }
 
-       width = ti->len;
        if (sector_div(width, stripes)) {
                ti->error = "Target length not divisible by "
                    "number of stripes";
@@ -167,12 +162,13 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        if (stripes & (stripes - 1))
                sc->stripes_shift = -1;
-       else {
-               sc->stripes_shift = ffs(stripes) - 1;
-               sc->stripes_mask = ((sector_t) stripes) - 1;
-       }
+       else
+               sc->stripes_shift = __ffs(stripes);
+
+       r = dm_set_target_max_io_len(ti, chunk_size);
+       if (r)
+               return r;
 
-       ti->split_io = chunk_size;
        ti->num_flush_requests = stripes;
        ti->num_discard_requests = stripes;
 
@@ -222,7 +218,7 @@ static void stripe_map_sector(struct stripe_c *sc, sector_t sector,
        if (sc->stripes_shift < 0)
                *stripe = sector_div(chunk, sc->stripes);
        else {
-               *stripe = chunk & sc->stripes_mask;
+               *stripe = chunk & (sc->stripes - 1);
                chunk >>= sc->stripes_shift;
        }
 
This page took 0.025594 seconds and 5 git commands to generate.