From 40765f60b82cc815ec2de29c86374e66f0441eaa Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Wed, 28 Nov 2001 17:41:16 +0000 Subject: [PATCH] o Target to let device-mapper stripe across volumes. --- patches/version_0.1.0/23_striped_target | 207 ++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 patches/version_0.1.0/23_striped_target diff --git a/patches/version_0.1.0/23_striped_target b/patches/version_0.1.0/23_striped_target new file mode 100644 index 0000000..0ec0efe --- /dev/null +++ b/patches/version_0.1.0/23_striped_target @@ -0,0 +1,207 @@ +diff -ruN -X /home/joe/packages/2.4/dontdiff linux-last/drivers/md/Makefile linux/drivers/md/Makefile +--- linux-last/drivers/md/Makefile Wed Nov 28 17:09:15 2001 ++++ linux/drivers/md/Makefile Wed Nov 28 17:09:49 2001 +@@ -7,7 +7,8 @@ + export-objs := md.o xor.o dm-table.o dm-target.o + list-multi := lvm-mod.o + lvm-mod-objs := lvm.o lvm-snap.o +-dm-mod-objs := dm.o dm-table.o dm-target.o dm-ioctl.o dm-linear.o ++dm-mod-objs := dm.o dm-table.o dm-target.o dm-ioctl.o \ ++ dm-linear.o dm-stripe.o + + # Note: link order is important. All raid personalities + # and xor.o must come before md.o, as they each initialise +diff -ruN -X /home/joe/packages/2.4/dontdiff linux-last/drivers/md/dm-stripe.c linux/drivers/md/dm-stripe.c +--- linux-last/drivers/md/dm-stripe.c Thu Jan 1 01:00:00 1970 ++++ linux/drivers/md/dm-stripe.c Wed Nov 28 17:34:39 2001 +@@ -0,0 +1,190 @@ ++/* ++ * Copyright (C) 2001 Sistina Software (UK) Limited. ++ * ++ * This file is released under the GPL. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dm.h" ++ ++struct stripe { ++ struct dm_dev *dev; ++ offset_t physical_start; ++}; ++ ++struct stripe_c { ++ offset_t logical_start; ++ uint32_t stripes; ++ ++ /* The size of this target / num. stripes */ ++ uint32_t stripe_width; ++ ++ /* eg, we stripe in 64k chunks */ ++ uint32_t chunk_shift; ++ offset_t chunk_mask; ++ ++ struct stripe stripe[0]; ++}; ++ ++ ++static inline struct stripe_c *alloc_context(int stripes) ++{ ++ size_t len = sizeof(struct stripe_c) + ++ (sizeof(struct stripe) * stripes); ++ return kmalloc(len, GFP_KERNEL); ++} ++ ++/* ++ * parses a single pair. ++ */ ++static int get_stripe(struct dm_table *t, struct stripe_c *sc, ++ int stripe, const char *args) ++{ ++ int n, r; ++ char path[256]; /* FIXME: buffer overrun risk */ ++ unsigned long start; ++ ++ if (sscanf(args, "%s %lu %n", path, &start, &n) != 2) ++ return -EINVAL; ++ ++ if ((r = dm_table_get_device(t, path, start, sc->stripe_width, ++ &sc->stripe[stripe].dev))) ++ return -ENXIO; ++ ++ sc->stripe[stripe].physical_start = start; ++ return n; ++} ++ ++/* ++ * construct a striped mapping. ++ * [ ]+ ++ */ ++static int stripe_ctr(struct dm_table *t, offset_t b, offset_t l, ++ const char *args, void **context, ++ dm_error_fn err, void *e_private) ++{ ++ struct stripe_c *sc; ++ uint32_t stripes; ++ uint32_t chunk_size; ++ int n, i; ++ ++ if (sscanf(args, "%u %u %n", &stripes, &chunk_size, &n) != 2) { ++ err("couldn't parse ", e_private); ++ return -EINVAL; ++ } ++ ++ if (l % stripes) { ++ err("target length is not divisable by the number of stripes", ++ e_private); ++ return -EINVAL; ++ } ++ ++ if (!(sc = alloc_context(stripes))) { ++ err("couldn't allocate memory for striped context", e_private); ++ return -ENOMEM; ++ } ++ ++ sc->logical_start = b; ++ sc->stripes = stripes; ++ sc->stripe_width = l / stripes; ++ ++ /* ++ * chunk_size is a power of two. We only ++ * that power and the mask. ++ */ ++ if (!chunk_size) { ++ err("invalid chunk size", e_private); ++ return -EINVAL; ++ } ++ ++ sc->chunk_mask = chunk_size - 1; ++ for (sc->chunk_shift = 0; chunk_size; sc->chunk_shift++) ++ chunk_size >>= 1; ++ sc->chunk_shift--; ++ ++ /* ++ * Get the stripe destinations. ++ */ ++ for (i = 0; i < stripes; i++) { ++ args += n; ++ n = get_stripe(t, sc, i, args); ++ ++ if (n < 0) { ++ err("couldn't parse stripe destination", e_private); ++ kfree(sc); ++ return n; ++ } ++ } ++ ++ ++ *context = sc; ++ return 0; ++} ++ ++static void stripe_dtr(struct dm_table *t, void *c) ++{ ++ unsigned int i; ++ struct stripe_c *sc = (struct stripe_c *) c; ++ ++ for (i = 0; i < sc->stripes; i++) ++ dm_table_put_device(t, sc->stripe[i].dev); ++ ++ kfree(sc); ++} ++ ++static int stripe_map(struct buffer_head *bh, int rw, void *context) ++{ ++ struct stripe_c *sc = (struct stripe_c *) context; ++ ++ offset_t offset = bh->b_rsector - sc->logical_start; ++ uint32_t chunk = (uint32_t) (offset >> sc->chunk_shift); ++ uint32_t stripe = chunk % sc->stripes; /* 32bit modulus */ ++ chunk = chunk / sc->stripes; ++ ++ bh->b_rdev = sc->stripe[stripe].dev->dev; ++ bh->b_rsector = sc->stripe[stripe].physical_start + ++ (chunk << sc->chunk_shift) + ++ (offset & sc->chunk_mask); ++ return 1; ++} ++ ++static struct target_type stripe_target = { ++ name: "striped", ++ module: THIS_MODULE, ++ ctr: stripe_ctr, ++ dtr: stripe_dtr, ++ map: stripe_map, ++}; ++ ++static int __init stripe_init(void) ++{ ++ int r; ++ ++ if ((r = dm_register_target(&stripe_target)) < 0) ++ WARN("linear target register failed"); ++ ++ return r; ++} ++ ++static void __exit stripe_exit(void) ++{ ++ if (dm_unregister_target(stripe_target.name)) ++ WARN("striped target unregister failed"); ++} ++ ++module_init(stripe_init); ++module_exit(stripe_exit); ++ ++MODULE_AUTHOR("Joe Thornber "); ++MODULE_DESCRIPTION("Device Mapper: Striped mapping"); ++ ++#ifdef MODULE_LICENSE ++MODULE_LICENSE("GPL"); ++#endif -- 2.43.5