]> git.hungrycats.org Git - linux/commitdiff
[PATCH] dm: list targets cmd
authorAndrew Morton <akpm@osdl.org>
Fri, 12 Mar 2004 00:14:14 +0000 (16:14 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 12 Mar 2004 00:14:14 +0000 (16:14 -0800)
From: Joe Thornber <thornber@redhat.com>

List targets ioctl.  [Patrick Caulfield]

drivers/md/dm-crypt.c
drivers/md/dm-ioctl.c
drivers/md/dm-linear.c
drivers/md/dm-stripe.c
drivers/md/dm-target.c
drivers/md/dm.h
include/linux/compat_ioctl.h
include/linux/device-mapper.h
include/linux/dm-ioctl.h

index 5b73745a7d8fc8ae4f8ed1c011ab11ade2658c76..8e1798115e2f6b5fac7e64729a918d7cefadb9a9 100644 (file)
@@ -740,6 +740,7 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
 
 static struct target_type crypt_target = {
        .name   = "crypt",
+       .version= {1, 0, 0},
        .module = THIS_MODULE,
        .ctr    = crypt_ctr,
        .dtr    = crypt_dtr,
index c691839801145e428fe5d95de8705629f93095d7..72915e2ae07cfb8bde95983a54116a6ad72c638b 100644 (file)
@@ -33,6 +33,14 @@ struct hash_cell {
        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];
@@ -409,6 +417,80 @@ static int list_devices(struct dm_ioctl *param, size_t param_size)
        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, '/')) {
@@ -1038,7 +1120,9 @@ static ioctl_fn lookup_ioctl(unsigned int cmd)
                {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;
@@ -1112,7 +1196,9 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
        param->flags &= ~DM_BUFFER_FULL_FLAG;
 
        /* Ignores parameters */
-       if (cmd == DM_REMOVE_ALL_CMD || cmd == DM_LIST_DEVICES_CMD)
+       if (cmd == DM_REMOVE_ALL_CMD ||
+           cmd == DM_LIST_DEVICES_CMD ||
+           cmd == DM_LIST_VERSIONS_CMD)
                return 0;
 
        /* Unless creating, either name or uuid but not both */
index fcb44dca2ff7240d892cffeda861ff2411d701b7..df79d95329f6ad2c587165972068a8d8089b2c7a 100644 (file)
@@ -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 int linear_status(struct dm_target *ti, status_type_t type,
 
 static struct target_type linear_target = {
        .name   = "linear",
+       .version= {1, 0, 1},
        .module = THIS_MODULE,
        .ctr    = linear_ctr,
        .dtr    = linear_dtr,
index 047a1580eb69e5f42fd002d7ceb2268bae3b18a9..70b5553fc09a65dce7bea5c7c85ed380df37a5cd 100644 (file)
@@ -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 int stripe_status(struct dm_target *ti,
 
 static struct target_type stripe_target = {
        .name   = "striped",
+       .version= {1, 0, 1},
        .module = THIS_MODULE,
        .ctr    = stripe_ctr,
        .dtr    = stripe_dtr,
index fc0839e4c75ae8baf5ed47c19aa7f59565814205..7a9122d704570c2950270bcac4b93a2b2f936fe1 100644 (file)
@@ -96,6 +96,20 @@ static struct tt_internal *alloc_target(struct target_type *t)
        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;
@@ -161,6 +175,7 @@ static int io_err_map(struct dm_target *ti, struct bio *bio,
 
 static struct target_type error_target = {
        .name = "error",
+       .version = {1, 0, 1},
        .ctr  = io_err_ctr,
        .dtr  = io_err_dtr,
        .map  = io_err_map,
index c20460bcbf35d5edc920651bfe12c03803483895..cc56cef1b88d094385f9096f97531cdc5e808288 100644 (file)
@@ -123,6 +123,8 @@ int dm_target_init(void);
 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);
 
 
 /*-----------------------------------------------------------------
index bfb63a0400918afcf28e93662cdf1ee4b256bc96..cd4c0c8d7ca50e8ebfe0faa2b48048e7cd65af0d 100644 (file)
@@ -134,6 +134,7 @@ COMPATIBLE_IOCTL(DM_TABLE_LOAD)
 COMPATIBLE_IOCTL(DM_TABLE_CLEAR)
 COMPATIBLE_IOCTL(DM_TABLE_DEPS)
 COMPATIBLE_IOCTL(DM_TABLE_STATUS)
+COMPATIBLE_IOCTL(DM_LIST_VERSIONS)
 /* Big K */
 COMPATIBLE_IOCTL(PIO_FONT)
 COMPATIBLE_IOCTL(GIO_FONT)
index a9ecba77fb305822fd85f07116734f5644062f2e..7abe54e3ee7049e177d1664a273d874b852bce5d 100644 (file)
@@ -74,6 +74,7 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d);
 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 @@ struct dm_target {
        sector_t split_io;
 
        /*
-        * These are automaticall filled in by
+        * These are automatically filled in by
         * dm_table_get_device.
         */
        struct io_restrictions limits;
index 74a8d14b885d98dd76652890d89f5f161f818477..cd781d795f8d11f538ae323bcef30a34a466d915 100644 (file)
@@ -162,6 +162,16 @@ struct dm_name_list {
        char name[0];
 };
 
+/*
+ * 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 @@ enum {
        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 @@ enum {
 #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 */