diff options
| author | haad <haad@NetBSD.org> | 2009-03-01 23:15:56 +0000 |
|---|---|---|
| committer | haad <haad@NetBSD.org> | 2009-03-01 23:15:56 +0000 |
| commit | f048f56f717ac5fb15a6f3605880128632babe7d (patch) | |
| tree | 6c34c109d9240a0d8c73caabac769c10228008cb /sys/dev | |
| parent | dcc33b5c39b6dd299204ec6d7921d3b6180f4442 (diff) | |
Add initial support for striping target, hardcode maximal number of stripes
to 2 for now. strategy routine must be written, for now only parsing and
support routines are available. This is work in progress code and should be
taken very carefully.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/dm/dm.h | 10 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target_stripe.c | 120 |
2 files changed, 117 insertions, 13 deletions
diff --git a/sys/dev/dm/dm.h b/sys/dev/dm/dm.h index 1b30e4390ab..ed177d8941a 100644 --- a/sys/dev/dm/dm.h +++ b/sys/dev/dm/dm.h @@ -1,4 +1,4 @@ -/* $NetBSD: dm.h,v 1.9 2009/02/19 23:07:32 haad Exp $ */ +/* $NetBSD: dm.h,v 1.10 2009/03/01 23:15:56 haad Exp $ */ /* * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -163,6 +163,14 @@ typedef struct target_linear_config { uint64_t offset; } dm_target_linear_config_t; +/* for stripe : */ +typedef struct target_stripe_config { +#define MAX_STRIPES 2 + struct target_linear_config stripe_devs[MAX_STRIPES]; + uint8_t stripe_num; + uint64_t stripe_chunksize; + size_t params_len; +} dm_target_stripe_config_t; /* for mirror : */ typedef struct target_mirror_config { diff --git a/sys/dev/dm/dm_target_stripe.c b/sys/dev/dm/dm_target_stripe.c index 0d15ddff141..19fdce1a7ae 100644 --- a/sys/dev/dm/dm_target_stripe.c +++ b/sys/dev/dm/dm_target_stripe.c @@ -1,4 +1,4 @@ -/*$NetBSD: dm_target_stripe.c,v 1.2 2009/01/02 22:33:51 haad Exp $*/ +/*$NetBSD: dm_target_stripe.c,v 1.3 2009/03/01 23:15:56 haad Exp $*/ /* * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -36,6 +36,8 @@ #include <sys/param.h> #include <sys/buf.h> +#include <sys/kmem.h> +#include <sys/vnode.h> #include "dm.h" @@ -61,9 +63,11 @@ dm_target_stripe_modcmd(modcmd_t cmd, void *arg) switch (cmd) { case MODULE_CMD_INIT: - if ((dmt = dm_target_lookup("stripe")) != NULL) + if ((dmt = dm_target_lookup("stripe")) != NULL) { + dm_target_unbusy(dmt); return EEXIST; - + } + dmt = dm_target_alloc("stripe"); dmt->version[0] = 1; @@ -97,34 +101,94 @@ dm_target_stripe_modcmd(modcmd_t cmd, void *arg) #endif -/* Init function called from dm_table_load_ioctl. */ +/* + * Init function called from dm_table_load_ioctl. + * Example line sent to dm from lvm tools when using striped target. + * start length striped #stripes chunk_size device1 offset1 ... deviceN offsetN + * 0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0 + */ int -dm_target_stripe_init(dm_dev_t *dmv, void **target_config, char *argv) +dm_target_stripe_init(dm_dev_t *dmv, void **target_config, char *params) { + dm_target_stripe_config_t *tsc; + size_t len; + char **ap, *argv[10]; + + if(params == NULL) + return EINVAL; + len = strlen(params) + 1; + + /* + * Parse a string, containing tokens delimited by white space, + * into an argument vector + */ + for (ap = argv; ap < &argv[9] && + (*ap = strsep(¶ms, " \t")) != NULL;) { + if (**ap != '\0') + ap++; + } + printf("Stripe target init function called!!\n"); - *target_config = NULL; + printf("Stripe target chunk size %s number of stripes %s\n", argv[1], argv[0]); + printf("Stripe target device name %s -- offset %s\n", argv[2], argv[3]); + printf("Stripe target device name %s -- offset %s\n", argv[4], argv[5]); + + if (atoi(argv[0]) > MAX_STRIPES) + return ENOTSUP; + + if ((tsc = kmem_alloc(sizeof(dm_target_stripe_config_t), KM_NOSLEEP)) + == NULL) + return ENOMEM; + + /* Insert dmp to global pdev list */ + if ((tsc->stripe_devs[0].pdev = dm_pdev_insert(argv[2])) == NULL) + return ENOENT; + + /* Insert dmp to global pdev list */ + if ((tsc->stripe_devs[1].pdev = dm_pdev_insert(argv[4])) == NULL) + return ENOENT; + + tsc->stripe_devs[0].offset = atoi(argv[3]); + tsc->stripe_devs[1].offset = atoi(argv[5]); + + /* Save length of param string */ + tsc->params_len = len; + tsc->stripe_chunksize = atoi(argv[1]); + tsc->stripe_num = (uint8_t)atoi(argv[0]); + + *target_config = tsc; dmv->dev_type = DM_STRIPE_DEV; - return ENOSYS; + return 0; } /* Status routine called to get params string. */ char * dm_target_stripe_status(void *target_config) { - return NULL; + dm_target_stripe_config_t *tsc; + char *params; + + tsc = target_config; + + if ((params = kmem_alloc(tsc->params_len, KM_NOSLEEP)) == NULL) + return NULL; + + snprintf(params, tsc->params_len, "%d %lld %s %lld %s %lld", tsc->stripe_num, tsc->stripe_chunksize, + tsc->stripe_devs[0].pdev->name, tsc->stripe_devs[0].offset, + tsc->stripe_devs[1].pdev->name, tsc->stripe_devs[1].offset); + + return params; } /* Strategy routine called from dm_strategy. */ int dm_target_stripe_strategy(dm_table_entry_t *table_en, struct buf *bp) { - - printf("Stripe target read function called!!\n"); - + bp->b_error = EIO; bp->b_resid = 0; @@ -137,11 +201,23 @@ dm_target_stripe_strategy(dm_table_entry_t *table_en, struct buf *bp) int dm_target_stripe_destroy(dm_table_entry_t *table_en) { - table_en->target_config = NULL; + dm_target_stripe_config_t *tsc; + + tsc = table_en->target_config; + + if (tsc == NULL) + return 0; + + dm_pdev_decr(tsc->stripe_devs[0].pdev); + dm_pdev_decr(tsc->stripe_devs[1].pdev); /* Unbusy target so we can unload it */ dm_target_unbusy(table_en->target); + kmem_free(tsc, sizeof(dm_target_stripe_config_t)); + + table_en->target_config = NULL; + return 0; } @@ -149,6 +225,26 @@ dm_target_stripe_destroy(dm_table_entry_t *table_en) int dm_target_stripe_deps(dm_table_entry_t *table_en, prop_array_t prop_array) { + dm_target_stripe_config_t *tsc; + struct vattr va; + + int error; + + if (table_en->target_config == NULL) + return ENOENT; + + tsc = table_en->target_config; + + if ((error = VOP_GETATTR(tsc->stripe_devs[0].pdev->pdev_vnode, &va, curlwp->l_cred)) != 0) + return error; + + prop_array_add_uint64(prop_array, (uint64_t)va.va_rdev); + + if ((error = VOP_GETATTR(tsc->stripe_devs[1].pdev->pdev_vnode, &va, curlwp->l_cred)) != 0) + return error; + + prop_array_add_uint64(prop_array, (uint64_t)va.va_rdev); + return 0; } |
