List targets ioctl. [Patrick Caulfield] --- diff/drivers/md/dm-ioctl-v4.c 2004-01-19 10:22:56.000000000 +0000 +++ source/drivers/md/dm-ioctl-v4.c 2004-02-18 09:07:03.000000000 +0000 @@ -33,6 +33,14 @@ struct dm_table *new_map; }; +struct vers_iter { + size_t param_size; + struct dm_target_versions *vers, *old_vers; + char *end; + uint32_t flags; +}; + + #define NUM_BUCKETS 64 #define MASK_BUCKETS (NUM_BUCKETS - 1) static struct list_head _name_buckets[NUM_BUCKETS]; @@ -415,6 +423,80 @@ return 0; } +static void list_version_get_needed(struct target_type *tt, void *param) +{ + int *needed = param; + + *needed += strlen(tt->name); + *needed += sizeof(tt->version); + *needed += ALIGN_MASK; +} + +static void list_version_get_info(struct target_type *tt, void *param) +{ + struct vers_iter *info = param; + + /* Check space - it might have changed since the first iteration */ + if ((char *)info->vers + sizeof(tt->version) + strlen(tt->name) + 1 > + info->end) { + + info->flags = DM_BUFFER_FULL_FLAG; + return; + } + + if (info->old_vers) + info->old_vers->next = (uint32_t) ((void *)info->vers - + (void *)info->old_vers); + info->vers->version[0] = tt->version[0]; + info->vers->version[1] = tt->version[1]; + info->vers->version[2] = tt->version[2]; + info->vers->next = 0; + strcpy(info->vers->name, tt->name); + + info->old_vers = info->vers; + info->vers = align_ptr(((void *) ++info->vers) + strlen(tt->name) + 1); +} + +static int list_versions(struct dm_ioctl *param, size_t param_size) +{ + size_t len, needed = 0; + struct dm_target_versions *vers; + struct vers_iter iter_info; + + /* + * Loop through all the devices working out how much + * space we need. + */ + dm_target_iterate(list_version_get_needed, &needed); + + /* + * Grab our output buffer. + */ + vers = get_result_buffer(param, param_size, &len); + if (len < needed) { + param->flags |= DM_BUFFER_FULL_FLAG; + goto out; + } + param->data_size = param->data_start + needed; + + iter_info.param_size = param_size; + iter_info.old_vers = NULL; + iter_info.vers = vers; + iter_info.flags = 0; + iter_info.end = (char *)vers+len; + + /* + * Now loop through filling out the names & versions. + */ + dm_target_iterate(list_version_get_info, &iter_info); + param->flags |= iter_info.flags; + + out: + return 0; +} + + + static int check_name(const char *name) { if (strchr(name, '/')) { @@ -1045,7 +1127,9 @@ {DM_TABLE_LOAD_CMD, table_load}, {DM_TABLE_CLEAR_CMD, table_clear}, {DM_TABLE_DEPS_CMD, table_deps}, - {DM_TABLE_STATUS_CMD, table_status} + {DM_TABLE_STATUS_CMD, table_status}, + + {DM_LIST_VERSIONS_CMD, list_versions} }; return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; --- diff/drivers/md/dm-linear.c 2004-02-18 09:06:52.000000000 +0000 +++ source/drivers/md/dm-linear.c 2004-02-18 09:07:03.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Sistina Software (UK) Limited. + * Copyright (C) 2001-2003 Sistina Software (UK) Limited. * * This file is released under the GPL. */ @@ -97,6 +97,7 @@ static struct target_type linear_target = { .name = "linear", + .version= {1, 0, 1}, .module = THIS_MODULE, .ctr = linear_ctr, .dtr = linear_dtr, --- diff/drivers/md/dm-stripe.c 2004-02-18 09:06:52.000000000 +0000 +++ source/drivers/md/dm-stripe.c 2004-02-18 09:07:03.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Sistina Software (UK) Limited. + * Copyright (C) 2001-2003 Sistina Software (UK) Limited. * * This file is released under the GPL. */ @@ -212,6 +212,7 @@ static struct target_type stripe_target = { .name = "striped", + .version= {1, 0, 1}, .module = THIS_MODULE, .ctr = stripe_ctr, .dtr = stripe_dtr, --- diff/drivers/md/dm-target.c 2004-02-18 09:06:52.000000000 +0000 +++ source/drivers/md/dm-target.c 2004-02-18 09:07:03.000000000 +0000 @@ -100,6 +100,20 @@ return ti; } + +int dm_target_iterate(void (*iter_func)(struct target_type *tt, + void *param), void *param) +{ + struct tt_internal *ti; + + down_read(&_lock); + list_for_each_entry (ti, &_targets, list) + iter_func(&ti->tt, param); + up_read(&_lock); + + return 0; +} + int dm_register_target(struct target_type *t) { int rv = 0; @@ -165,6 +179,7 @@ static struct target_type error_target = { .name = "error", + .version = {1, 0, 1}, .ctr = io_err_ctr, .dtr = io_err_dtr, .map = io_err_map, --- diff/drivers/md/dm.h 2004-02-18 09:04:00.000000000 +0000 +++ source/drivers/md/dm.h 2004-02-18 09:07:03.000000000 +0000 @@ -123,6 +123,8 @@ void dm_target_exit(void); struct target_type *dm_get_target_type(const char *name); void dm_put_target_type(struct target_type *t); +int dm_target_iterate(void (*iter_func)(struct target_type *tt, + void *param), void *param); /*----------------------------------------------------------------- --- diff/include/linux/device-mapper.h 2004-02-18 09:06:52.000000000 +0000 +++ source/include/linux/device-mapper.h 2004-02-18 09:07:03.000000000 +0000 @@ -74,6 +74,7 @@ struct target_type { const char *name; struct module *module; + unsigned version[3]; dm_ctr_fn ctr; dm_dtr_fn dtr; dm_map_fn map; @@ -104,7 +105,7 @@ sector_t split_io; /* - * These are automaticall filled in by + * These are automatically filled in by * dm_table_get_device. */ struct io_restrictions limits; --- diff/include/linux/dm-ioctl-v4.h 2003-08-20 14:16:15.000000000 +0100 +++ source/include/linux/dm-ioctl-v4.h 2004-02-18 09:07:03.000000000 +0000 @@ -163,6 +163,16 @@ }; /* + * Used to retrieve the target versions + */ +struct dm_target_versions { + uint32_t next; + uint32_t version[3]; + + char name[0]; +}; + +/* * If you change this make sure you make the corresponding change * to dm-ioctl.c:lookup_ioctl() */ @@ -185,6 +195,9 @@ DM_TABLE_CLEAR_CMD, DM_TABLE_DEPS_CMD, DM_TABLE_STATUS_CMD, + + /* Added later */ + DM_LIST_VERSIONS_CMD, }; #define DM_IOCTL 0xfd @@ -205,10 +218,12 @@ #define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl) #define DM_TABLE_STATUS _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl) +#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl) + #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 0 +#define DM_VERSION_MINOR 1 #define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2003-06-04)" +#define DM_VERSION_EXTRA "-ioctl (2003-12-10)" /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */