#include <linux/bio.h>
#include <linux/slab.h>
+#define DM_MSG_PREFIX "striped"
+
struct stripe {
struct dm_dev *dev;
sector_t physical_start;
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;
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,
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;
}
*/
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;
}
* 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;
}
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);
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,
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:
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;
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,
r = dm_register_target(&stripe_target);
if (r < 0)
- DMWARN("striped target registration failed");
+ DMWARN("target registration failed");
return r;
}
void dm_stripe_exit(void)
{
if (dm_unregister_target(&stripe_target))
- DMWARN("striped target unregistration failed");
+ DMWARN("target unregistration failed");
return;
}