diff --git a/sys/dev/dm/dm.h b/sys/dev/dm/dm.h index 1b30e4390aba..ed177d8941a0 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 0d15ddff141f..19fdce1a7ae2 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 #include +#include +#include #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; }