fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / md / dm-stripe.c
index b5bacd7..51f5e07 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/bio.h>
 #include <linux/slab.h>
 
+#define DM_MSG_PREFIX "striped"
+
 struct stripe {
        struct dm_dev *dev;
        sector_t physical_start;
@@ -21,7 +23,7 @@ struct stripe_c {
        uint32_t stripes;
 
        /* The size of this target / num. stripes */
-       uint32_t stripe_width;
+       sector_t stripe_width;
 
        /* stripe chunk size */
        uint32_t chunk_shift;
@@ -49,9 +51,9 @@ static inline struct stripe_c *alloc_context(unsigned int stripes)
 static int get_stripe(struct dm_target *ti, struct stripe_c *sc,
                      unsigned int stripe, char **argv)
 {
-       sector_t start;
+       unsigned long long start;
 
-       if (sscanf(argv[1], SECTOR_FORMAT, &start) != 1)
+       if (sscanf(argv[1], "%llu", &start) != 1)
                return -EINVAL;
 
        if (dm_get_device(ti, argv[0], start, sc->stripe_width,
@@ -78,19 +80,19 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        unsigned int i;
 
        if (argc < 2) {
-               ti->error = "dm-stripe: Not enough arguments";
+               ti->error = "Not enough arguments";
                return -EINVAL;
        }
 
        stripes = simple_strtoul(argv[0], &end, 10);
        if (*end) {
-               ti->error = "dm-stripe: Invalid stripe count";
+               ti->error = "Invalid stripe count";
                return -EINVAL;
        }
 
        chunk_size = simple_strtoul(argv[1], &end, 10);
        if (*end) {
-               ti->error = "dm-stripe: Invalid chunk_size";
+               ti->error = "Invalid chunk_size";
                return -EINVAL;
        }
 
@@ -99,13 +101,19 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
         */
        if (!chunk_size || (chunk_size & (chunk_size - 1)) ||
            (chunk_size < (PAGE_SIZE >> SECTOR_SHIFT))) {
-               ti->error = "dm-stripe: Invalid chunk size";
+               ti->error = "Invalid chunk size";
+               return -EINVAL;
+       }
+
+       if (ti->len & (chunk_size - 1)) {
+               ti->error = "Target length not divisible by "
+                   "chunk size";
                return -EINVAL;
        }
 
        width = ti->len;
        if (sector_div(width, stripes)) {
-               ti->error = "dm-stripe: Target length not divisable by "
+               ti->error = "Target length not divisible by "
                    "number of stripes";
                return -EINVAL;
        }
@@ -114,14 +122,14 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
         * Do we have enough arguments for that many stripes ?
         */
        if (argc != (2 + 2 * stripes)) {
-               ti->error = "dm-stripe: Not enough destinations "
+               ti->error = "Not enough destinations "
                        "specified";
                return -EINVAL;
        }
 
        sc = alloc_context(stripes);
        if (!sc) {
-               ti->error = "dm-stripe: Memory allocation for striped context "
+               ti->error = "Memory allocation for striped context "
                    "failed";
                return -ENOMEM;
        }
@@ -143,8 +151,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
                r = get_stripe(ti, sc, i, argv);
                if (r < 0) {
-                       ti->error = "dm-stripe: Couldn't parse stripe "
-                               "destination";
+                       ti->error = "Couldn't parse stripe destination";
                        while (i--)
                                dm_put_device(ti, sc->stripe[i].dev);
                        kfree(sc);
@@ -173,14 +180,13 @@ static int stripe_map(struct dm_target *ti, struct bio *bio,
        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 = sector_div(chunk, sc->stripes);
 
        bio->bi_bdev = sc->stripe[stripe].dev->bdev;
        bio->bi_sector = sc->stripe[stripe].physical_start +
            (chunk << sc->chunk_shift) + (offset & sc->chunk_mask);
-       return 1;
+       return DM_MAPIO_REMAPPED;
 }
 
 static int stripe_status(struct dm_target *ti,
@@ -189,10 +195,6 @@ static int stripe_status(struct dm_target *ti,
        struct stripe_c *sc = (struct stripe_c *) ti->private;
        unsigned int sz = 0;
        unsigned int i;
-       char buffer[32];
-
-#define EMIT(x...) sz += ((sz >= maxlen) ? \
-                         0 : scnprintf(result + sz, maxlen - sz, x))
 
        switch (type) {
        case STATUSTYPE_INFO:
@@ -200,12 +202,11 @@ static int stripe_status(struct dm_target *ti,
                break;
 
        case STATUSTYPE_TABLE:
-               EMIT("%d " SECTOR_FORMAT, sc->stripes, sc->chunk_mask + 1);
-               for (i = 0; i < sc->stripes; i++) {
-                       format_dev_t(buffer, sc->stripe[i].dev->bdev->bd_dev);
-                       EMIT(" %s " SECTOR_FORMAT, buffer,
-                            sc->stripe[i].physical_start);
-               }
+               DMEMIT("%d %llu", sc->stripes,
+                       (unsigned long long)sc->chunk_mask + 1);
+               for (i = 0; i < sc->stripes; i++)
+                       DMEMIT(" %s %llu", sc->stripe[i].dev->name,
+                           (unsigned long long)sc->stripe[i].physical_start);
                break;
        }
        return 0;
@@ -213,7 +214,7 @@ static int stripe_status(struct dm_target *ti,
 
 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,
@@ -227,7 +228,7 @@ int __init dm_stripe_init(void)
 
        r = dm_register_target(&stripe_target);
        if (r < 0)
-               DMWARN("striped target registration failed");
+               DMWARN("target registration failed");
 
        return r;
 }
@@ -235,7 +236,7 @@ int __init dm_stripe_init(void)
 void dm_stripe_exit(void)
 {
        if (dm_unregister_target(&stripe_target))
-               DMWARN("striped target unregistration failed");
+               DMWARN("target unregistration failed");
 
        return;
 }