X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmd%2Fdm-stripe.c;h=51f5e0760012dd76c35d939bb18862a20e2ee435;hb=refs%2Fheads%2Fvserver;hp=b5bacd717760a4954fb8dbb80457be3c9d4b1c51;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index b5bacd717..51f5e0760 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c @@ -12,6 +12,8 @@ #include #include +#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; }