dm - add remove_all, refactor
authorAlex Hornung <ahornung@gmail.com>
Mon, 13 Dec 2010 18:17:08 +0000 (18:17 +0000)
committerAlex Hornung <ahornung@gmail.com>
Mon, 13 Dec 2010 21:48:31 +0000 (21:48 +0000)
* Refactor the dm dev creation and removal methods as to avoid
  duplication and, as a bonus, do things properly.

* Rename foo_destroy to foo_uninit, because that's what they really are,
  uninit functions.

* Add an experimental 'remove_all' method

* Move atoi64 into device-mapper so that the striped target works
  without loading the linear target.

sys/dev/disk/dm/device-mapper.c
sys/dev/disk/dm/dm.h
sys/dev/disk/dm/dm_dev.c
sys/dev/disk/dm/dm_ioctl.c
sys/dev/disk/dm/dm_pdev.c
sys/dev/disk/dm/dm_target.c
sys/dev/disk/dm/targets/linear/dm_target_linear.c

index bae26df..05b9440 100644 (file)
@@ -39,7 +39,6 @@
 #include <sys/buf.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/devfs.h>
 #include <sys/disk.h>
 #include <sys/disklabel.h>
 #include <sys/dtype.h>
@@ -72,8 +71,6 @@ static int dm_ioctl_switch(u_long);
 static void dmminphys(struct buf *);
 #endif
 
-struct devfs_bitmap dm_minor_bitmap;
-
 /* ***Variable-definitions*** */
 struct dev_ops dm_ops = {
        { "dm", 0, D_DISK | D_MPSAFE },
@@ -122,6 +119,7 @@ static struct cmd_function cmd_fn[] = {
                { .cmd = "names",   .fn = dm_dev_list_ioctl},
                { .cmd = "suspend", .fn = dm_dev_suspend_ioctl},
                { .cmd = "remove",  .fn = dm_dev_remove_ioctl},
+               { .cmd = "remove_all", .fn = dm_dev_remove_all_ioctl},
                { .cmd = "rename",  .fn = dm_dev_rename_ioctl},
                { .cmd = "resume",  .fn = dm_dev_resume_ioctl},
                { .cmd = "clear",   .fn = dm_table_clear_ioctl},
@@ -144,7 +142,6 @@ dm_modcmd(module_t mod, int cmd, void *unused)
 
        switch (cmd) {
        case MOD_LOAD:
-               devfs_clone_bitmap_init(&dm_minor_bitmap);
                dm_doinit();
                kprintf("Device Mapper version %d.%d.%d loaded\n",
                    DM_VERSION_MAJOR, DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL);
@@ -173,41 +170,6 @@ dm_modcmd(module_t mod, int cmd, void *unused)
        return error;
 }
 
-/*
- * dm_detach is called to completely destroy & remove a dm disk device.
- */
-int
-dm_detach(dm_dev_t *dmv)
-{
-       int minor;
-
-       /* Remove device from list and wait for refcnt to drop to zero */
-       dm_dev_rem(dmv, NULL, NULL, -1);
-
-       /* Destroy active table first.  */
-       dm_table_destroy(&dmv->table_head, DM_TABLE_ACTIVE);
-
-       /* Destroy inactive table if exits, too. */
-       dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
-
-       dm_table_head_destroy(&dmv->table_head);
-
-       minor = dkunit(dmv->devt);
-       disk_destroy(dmv->diskp);
-       devstat_remove_entry(&dmv->stats);
-
-       release_dev(dmv->devt);
-       devfs_clone_bitmap_put(&dm_minor_bitmap, minor);
-
-       /* Destroy device */
-       (void)dm_dev_free(dmv);
-
-       /* Decrement device counter After removing device */
-       --dm_dev_counter; /* XXX: was atomic 64 */
-
-       return 0;
-}
-
 static void
 dm_doinit(void)
 {
@@ -223,9 +185,9 @@ dmdestroy(void)
 {
        destroy_dev(dmcdev);
 
-       dm_dev_destroy();
-       dm_pdev_destroy();
-       dm_target_destroy();
+       dm_dev_uninit();
+       dm_pdev_uninit();
+       dm_target_uninit();
 
        return 0;
 }
@@ -677,6 +639,26 @@ dmsetdiskinfo(struct disk *disk, dm_table_head_t *head)
        disk_setdiskinfo(disk, &info);
 }
 
+/*
+ * Transform char s to uint64_t offset number.
+ */
+uint64_t
+atoi64(const char *s)
+{
+       uint64_t n;
+       n = 0;
+
+       while (*s != '\0') {
+               if (!isdigit(*s))
+                       break;
+
+               n = (10 * n) + (*s - '0');
+               s++;
+       }
+
+       return n;
+}
+
 void
 dm_builtin_init(void *arg)
 {
index c8c55b5..82e09b5 100644 (file)
@@ -145,7 +145,6 @@ typedef struct dm_dev {
        struct dm_dev_head upcalls;
 
        struct disk *diskp;
-       struct lock diskp_mtx;
 
        struct devstat stats;
 
@@ -266,6 +265,7 @@ int dm_detach(dm_dev_t *);
 int dm_dev_create_ioctl(prop_dictionary_t);
 int dm_dev_list_ioctl(prop_dictionary_t);
 int dm_dev_remove_ioctl(prop_dictionary_t);
+int dm_dev_remove_all_ioctl(prop_dictionary_t);
 int dm_dev_rename_ioctl(prop_dictionary_t);
 int dm_dev_resume_ioctl(prop_dictionary_t);
 int dm_dev_status_ioctl(prop_dictionary_t);
@@ -281,9 +281,10 @@ int dm_table_load_ioctl(prop_dictionary_t);
 int dm_table_status_ioctl(prop_dictionary_t);
 
 /* dm_target.c */
+int dm_target_init(void);
+int dm_target_uninit(void);
 dm_target_t* dm_target_alloc(const char *);
 dm_target_t* dm_target_autoload(const char *);
-int dm_target_destroy(void);
 int dm_target_insert(dm_target_t *);
 prop_array_t dm_target_prop_list(void);
 dm_target_t* dm_target_lookup(const char *);
@@ -291,9 +292,6 @@ int dm_target_rem(char *);
 void dm_target_unbusy(dm_target_t *);
 void dm_target_busy(dm_target_t *);
 
-/* XXX temporally add */
-int dm_target_init(void);
-
 #define DM_MAX_PARAMS_SIZE 1024
 
 /* Generic function used to convert char to string */
@@ -337,11 +335,15 @@ void dm_table_head_init(dm_table_head_t *);
 void dm_table_head_destroy(dm_table_head_t *);
 
 /* dm_dev.c */
+int dm_dev_init(void);
+int dm_dev_uninit(void);
 dm_dev_t* dm_dev_alloc(void);
 void dm_dev_busy(dm_dev_t *);
-int dm_dev_destroy(void);
+int dm_dev_create(dm_dev_t **, const char *, const char *, int);
+int dm_dev_remove(dm_dev_t *);
+int dm_dev_remove_all(int);
+int dm_dev_destroy(dm_dev_t *);
 int dm_dev_free(dm_dev_t *);
-int dm_dev_init(void);
 int dm_dev_insert(dm_dev_t *);
 dm_dev_t* dm_dev_lookup(const char *, const char *, int);
 prop_array_t dm_dev_prop_list(void);
@@ -350,9 +352,9 @@ dm_dev_t* dm_dev_rem(dm_dev_t *, const char *, const char *, int);
 void dm_dev_unbusy(dm_dev_t *);
 
 /* dm_pdev.c */
-int dm_pdev_decr(dm_pdev_t *);
-int dm_pdev_destroy(void);
 int dm_pdev_init(void);
+int dm_pdev_uninit(void);
+int dm_pdev_decr(dm_pdev_t *);
 dm_pdev_t* dm_pdev_insert(const char *);
 off_t dm_pdev_correct_dump_offset(dm_pdev_t *, off_t);
 
index 7f0afff..029366f 100644 (file)
 
 #include <sys/types.h>
 #include <sys/param.h>
+#include <machine/thread.h>
+#include <sys/thread2.h>
 
 #include <sys/disk.h>
 #include <sys/disklabel.h>
+#include <sys/devicestat.h>
+#include <sys/device.h>
+#include <sys/udev.h>
+#include <sys/devfs.h>
 #include <sys/ioccom.h>
 #include <sys/malloc.h>
 #include <dev/disk/dm/dm.h>
 
 #include "netbsd-dm.h"
 
+extern struct dev_ops dm_ops;
+
+struct devfs_bitmap dm_minor_bitmap;
+uint64_t dm_dev_counter;
+
 static dm_dev_t *dm_dev_lookup_name(const char *);
 static dm_dev_t *dm_dev_lookup_uuid(const char *);
 static dm_dev_t *dm_dev_lookup_minor(int);
@@ -49,13 +60,15 @@ TAILQ_HEAD_INITIALIZER(dm_dev_list);
 
 struct lock dm_dev_mutex;
 
-/* dm_dev_mutex must be holdby caller before using disable_dev. */
+/* dm_dev_mutex must be held by caller before using disable_dev. */
 static void
 disable_dev(dm_dev_t * dmv)
 {
+       KKASSERT(lockstatus(&dm_dev_mutex, curthread) == LK_EXCLUSIVE);
+
        TAILQ_REMOVE(&dm_dev_list, dmv, next_devlist);
+
        lockmgr(&dmv->dev_mtx, LK_EXCLUSIVE);
-       lockmgr(&dm_dev_mutex, LK_RELEASE);
        while (dmv->ref_cnt != 0)
                cv_wait(&dmv->dev_cv, &dmv->dev_mtx);
        lockmgr(&dmv->dev_mtx, LK_RELEASE);
@@ -181,69 +194,145 @@ dm_dev_rem(dm_dev_t *dmv, const char *dm_dev_name, const char *dm_dev_uuid,
 
        if (dmv != NULL) {
                disable_dev(dmv);
-               return dmv;
-       }
-
-       if (dm_dev_minor > 0)
-               if ((dmv = dm_dev_lookup_minor(dm_dev_minor)) != NULL) {
+       } else if (dm_dev_minor > 0) {
+               if ((dmv = dm_dev_lookup_minor(dm_dev_minor)) != NULL)
                        disable_dev(dmv);
-                       return dmv;
-               }
-       if (dm_dev_name != NULL)
-               if ((dmv = dm_dev_lookup_name(dm_dev_name)) != NULL) {
+       } else if (dm_dev_name != NULL) {
+               if ((dmv = dm_dev_lookup_name(dm_dev_name)) != NULL)
                        disable_dev(dmv);
-                       return dmv;
-               }
-       if (dm_dev_uuid != NULL)
-               if ((dmv = dm_dev_lookup_name(dm_dev_uuid)) != NULL) {
+       } else if (dm_dev_uuid != NULL) {
+               if ((dmv = dm_dev_lookup_name(dm_dev_uuid)) != NULL)
                        disable_dev(dmv);
-                       return dmv;
-               }
+       }
+
        lockmgr(&dm_dev_mutex, LK_RELEASE);
 
-       return NULL;
+       return dmv;
 }
-/*
- * Destroy all devices created in device-mapper. Remove all tables
- * free all allocated memmory.
- */
+
 int
-dm_dev_destroy(void)
+dm_dev_create(dm_dev_t **dmvp, const char *name, const char *uuid, int flags)
 {
        dm_dev_t *dmv;
-       lockmgr(&dm_dev_mutex, LK_EXCLUSIVE);
+       char name_buf[MAXPATHLEN];
+       int r, dm_minor;
+
+       if ((dmv = dm_dev_alloc()) == NULL)
+               return ENOMEM;
+
+       if (uuid)
+               strncpy(dmv->uuid, uuid, DM_UUID_LEN);
+       else
+               dmv->uuid[0] = '\0';
+
+       if (name)
+               strlcpy(dmv->name, name, DM_NAME_LEN);
+
+       dm_minor = devfs_clone_bitmap_get(&dm_minor_bitmap, 0);
+
+       dm_table_head_init(&dmv->table_head);
+
+       lockinit(&dmv->dev_mtx, "dmdev", 0, LK_CANRECURSE);
+       cv_init(&dmv->dev_cv, "dm_dev");
 
-       while (TAILQ_FIRST(&dm_dev_list) != NULL) {
+       if (flags & DM_READONLY_FLAG)
+               dmv->flags |= DM_READONLY_FLAG;
 
-               dmv = TAILQ_FIRST(&dm_dev_list);
+       aprint_debug("Creating device dm/%s\n", name);
+       ksnprintf(name_buf, sizeof(name_buf), "mapper/%s", dmv->name);
 
-               TAILQ_REMOVE(&dm_dev_list, TAILQ_FIRST(&dm_dev_list),
-                   next_devlist);
+       devstat_add_entry(&dmv->stats, name, 0, DEV_BSIZE,
+           DEVSTAT_NO_ORDERED_TAGS,
+           DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER,
+           DEVSTAT_PRIORITY_DISK);
 
-               lockmgr(&dmv->dev_mtx, LK_EXCLUSIVE);
+       dmv->devt = disk_create_named(name_buf, dm_minor, dmv->diskp, &dm_ops);
+       reference_dev(dmv->devt);
 
-               while (dmv->ref_cnt != 0)
-                       cv_wait(&dmv->dev_cv, &dmv->dev_mtx);
+       dmv->minor = minor(dmv->devt);
+       udev_dict_set_cstr(dmv->devt, "subsystem", "disk");
 
-               /* Destroy active table first.  */
-               dm_table_destroy(&dmv->table_head, DM_TABLE_ACTIVE);
+       if ((r = dm_dev_insert(dmv)) != 0)
+               dm_dev_destroy(dmv);
 
-               /* Destroy inactive table if exits, too. */
-               dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
+       /* Increment device counter After creating device */
+       ++dm_dev_counter; /* XXX: was atomic 64 */
+       *dmvp = dmv;
 
-               dm_table_head_destroy(&dmv->table_head);
+       return r;
+}
+
+int
+dm_dev_destroy(dm_dev_t *dmv)
+{
+       int minor;
+
+       /* Destroy active table first.  */
+       dm_table_destroy(&dmv->table_head, DM_TABLE_ACTIVE);
 
-               lockmgr(&dmv->dev_mtx, LK_RELEASE);
-               lockuninit(&dmv->dev_mtx);
-               cv_destroy(&dmv->dev_cv);
+       /* Destroy inactive table if exits, too. */
+       dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
 
-               (void) kfree(dmv, M_DM);
+       dm_table_head_destroy(&dmv->table_head);
+
+       minor = dkunit(dmv->devt);
+       disk_destroy(dmv->diskp);
+       devstat_remove_entry(&dmv->stats);
+
+       release_dev(dmv->devt);
+       devfs_clone_bitmap_put(&dm_minor_bitmap, minor);
+
+       lockuninit(&dmv->dev_mtx);
+       cv_destroy(&dmv->dev_cv);
+
+       /* Destroy device */
+       (void)dm_dev_free(dmv);
+
+       /* Decrement device counter After removing device */
+       --dm_dev_counter; /* XXX: was atomic 64 */
+
+       return 0;
+}
+
+/*
+ * dm_detach is called to completely destroy & remove a dm disk device.
+ */
+int
+dm_dev_remove(dm_dev_t *dmv)
+{
+       /* Remove device from list and wait for refcnt to drop to zero */
+       dm_dev_rem(dmv, NULL, NULL, -1);
+
+       /* Destroy and free the device */
+       dm_dev_destroy(dmv);
+
+       return 0;
+}
+
+int
+dm_dev_remove_all(int gentle)
+{
+       dm_dev_t *dmv, *dmv2;
+       int r;
+
+       r = 0;
+
+       lockmgr(&dm_dev_mutex, LK_EXCLUSIVE);
+
+       TAILQ_FOREACH_MUTABLE(dmv, &dm_dev_list, next_devlist, dmv2) {
+               if (gentle && dmv->is_open) {
+                       r = EBUSY;
+                       continue;
+               }
+
+               disable_dev(dmv);
+               dm_dev_destroy(dmv);
        }
        lockmgr(&dm_dev_mutex, LK_RELEASE);
 
-       lockuninit(&dm_dev_mutex);
-       return 0;
+       return r;
 }
+
 /*
  * Allocate new device entry.
  */
@@ -267,10 +356,6 @@ dm_dev_free(dm_dev_t * dmv)
 {
        KKASSERT(dmv != NULL);
 
-       lockuninit(&dmv->dev_mtx);
-       lockuninit(&dmv->diskp_mtx);
-       cv_destroy(&dmv->dev_cv);
-
        if (dmv->diskp != NULL)
                (void) kfree(dmv->diskp, M_DM);
 
@@ -332,5 +417,20 @@ dm_dev_init(void)
 {
        TAILQ_INIT(&dm_dev_list);       /* initialize global dev list */
        lockinit(&dm_dev_mutex, "dmdevlist", 0, LK_CANRECURSE);
+       devfs_clone_bitmap_init(&dm_minor_bitmap);
+       return 0;
+}
+
+/*
+ * Destroy all devices created in device-mapper. Remove all tables
+ * free all allocated memmory.
+ */
+int
+dm_dev_uninit(void)
+{
+       /* Force removal of all devices */
+       dm_dev_remove_all(0);
+
+       lockuninit(&dm_dev_mutex);
        return 0;
 }
index 6376f1c..32d05e9 100644 (file)
 
 #include <sys/types.h>
 #include <sys/param.h>
-
 #include <sys/device.h>
-#include <sys/devicestat.h>
-#include <sys/devfs.h>
-#include <sys/disk.h>
-#include <sys/disklabel.h>
 #include <sys/malloc.h>
-#include <sys/udev.h>
 #include <sys/vnode.h>
 #include <dev/disk/dm/dm.h>
 
 #include "netbsd-dm.h"
 
-extern struct dev_ops dm_ops;
-extern struct devfs_bitmap dm_minor_bitmap;
-uint64_t dm_dev_counter;
-
 #define DM_REMOVE_FLAG(flag, name) do {                                        \
                prop_dictionary_get_uint32(dm_dict,DM_IOCTL_FLAGS,&flag); \
                flag &= ~name;                                          \
@@ -192,8 +182,7 @@ dm_dev_create_ioctl(prop_dictionary_t dm_dict)
 {
        dm_dev_t *dmv;
        const char *name, *uuid;
-       char name_buf[MAXPATHLEN];
-       int r, flags, dm_minor;
+       int r, flags;
 
        r = 0;
        flags = 0;
@@ -214,56 +203,13 @@ dm_dev_create_ioctl(prop_dictionary_t dm_dict)
                return EEXIST;
        }
 
-       if ((dmv = dm_dev_alloc()) == NULL)
-               return ENOMEM;
-
-       if (uuid)
-               strncpy(dmv->uuid, uuid, DM_UUID_LEN);
-       else
-               dmv->uuid[0] = '\0';
-
-       if (name)
-               strlcpy(dmv->name, name, DM_NAME_LEN);
-
-       dm_minor = devfs_clone_bitmap_get(&dm_minor_bitmap, 0);
-       dmv->flags = 0;         /* device flags are set when needed */
-       dmv->ref_cnt = 0;
-       dmv->event_nr = 0;
-       dmv->dev_type = 0;
-       dmv->is_open = 0;
-
-       dm_table_head_init(&dmv->table_head);
-
-       lockinit(&dmv->dev_mtx, "dmdev", 0, LK_CANRECURSE);
-       lockinit(&dmv->diskp_mtx, "dmdisk", 0, LK_CANRECURSE);
-       cv_init(&dmv->dev_cv, "dm_dev");
-
-       if (flags & DM_READONLY_FLAG)
-               dmv->flags |= DM_READONLY_FLAG;
-
-       aprint_debug("Creating device dm/%s\n", name);
-       ksnprintf(name_buf, sizeof(name_buf), "mapper/%s", dmv->name);
-
-       devstat_add_entry(&dmv->stats, name, 0, DEV_BSIZE,
-           DEVSTAT_NO_ORDERED_TAGS,
-           DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER,
-           DEVSTAT_PRIORITY_DISK);
-
-       dmv->devt = disk_create_named(name_buf, dm_minor, dmv->diskp, &dm_ops);
-       reference_dev(dmv->devt);
-
-       dmv->minor = minor(dmv->devt);
-       prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
-       udev_dict_set_cstr(dmv->devt, "subsystem", "disk");
-
-       if ((r = dm_dev_insert(dmv)) != 0)
-               dm_dev_free(dmv);
-
-       DM_ADD_FLAG(flags, DM_EXISTS_FLAG);
-       DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
-
-       /* Increment device counter After creating device */
-       ++dm_dev_counter; /* XXX: was atomic 64 */
+       r = dm_dev_create(&dmv, name, uuid, flags);
+       
+       if (r == 0) {
+               prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
+               DM_ADD_FLAG(flags, DM_EXISTS_FLAG);
+               DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
+       }
 
        return r;
 }
@@ -317,6 +263,7 @@ dm_dev_list_ioctl(prop_dictionary_t dm_dict)
 int
 dm_dev_rename_ioctl(prop_dictionary_t dm_dict)
 {
+#if 0
        prop_array_t cmd_array;
        dm_dev_t *dmv;
 
@@ -359,12 +306,19 @@ dm_dev_rename_ioctl(prop_dictionary_t dm_dict)
        prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid);
 
        dm_dev_insert(dmv);
+#endif
 
+       /*
+        * XXX: the rename is not yet implemented. The main complication
+        *      here is devfs. We'd probably need a new function, rename_dev()
+        *      that would trigger a node rename in devfs.
+        */
+       kprintf("dm_dev_rename_ioctl called, but not implemented!\n");
        return 0;
 }
+
 /*
- * Remove device from global list I have to remove active
- * and inactive tables first.
+ * Remove device
  */
 int
 dm_dev_remove_ioctl(prop_dictionary_t dm_dict)
@@ -400,11 +354,29 @@ dm_dev_remove_ioctl(prop_dictionary_t dm_dict)
                return EBUSY;
 
        /*
-        * This will call dm_detach routine which will actually removes
+        * This will call dm_detach routine which will actually remove
         * device.
         */
-       return dm_detach(dmv);
+       return dm_dev_remove(dmv);
 }
+
+/*
+ * Try to remove all devices
+ */
+int
+dm_dev_remove_all_ioctl(prop_dictionary_t dm_dict)
+{
+       uint32_t flags = 0;
+
+       /* Get needed values from dictionary. */
+       prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
+
+       dm_dbg_print_flags(flags);
+
+       /* Gently remove all devices, if possible */
+       return dm_dev_remove_all(1);
+}
+
 /*
  * Return actual state of device to libdevmapper.
  */
index 934c2d6..5b17d76 100644 (file)
@@ -159,17 +159,7 @@ dm_pdev_insert(const char *dev_name)
 
        return dmp;
 }
-/*
- * Initialize pdev subsystem.
- */
-int
-dm_pdev_init(void)
-{
-       SLIST_INIT(&dm_pdev_list);      /* initialize global pdev list */
-       lockinit(&dm_pdev_mutex, "dmpdev", 0, LK_CANRECURSE);
 
-       return 0;
-}
 /*
  * Allocat new pdev structure if is not already present and
  * set name.
@@ -209,28 +199,7 @@ dm_pdev_rem(dm_pdev_t * dmp)
 
        return 0;
 }
-/*
- * Destroy all existing pdev's in device-mapper.
- */
-int
-dm_pdev_destroy(void)
-{
-       dm_pdev_t *dm_pdev;
 
-       lockmgr(&dm_pdev_mutex, LK_EXCLUSIVE);
-       while (!SLIST_EMPTY(&dm_pdev_list)) {   /* List Deletion. */
-
-               dm_pdev = SLIST_FIRST(&dm_pdev_list);
-
-               SLIST_REMOVE_HEAD(&dm_pdev_list, next_pdev);
-
-               dm_pdev_rem(dm_pdev);
-       }
-       lockmgr(&dm_pdev_mutex, LK_RELEASE);
-
-       lockuninit(&dm_pdev_mutex);
-       return 0;
-}
 /*
  * This funcion is called from dm_dev_remove_ioctl.
  * When I'm removing device from list, I have to decrement
@@ -261,3 +230,38 @@ dm_pdev_decr(dm_pdev_t * dmp)
        lockmgr(&dm_pdev_mutex, LK_RELEASE);
        return 0;
 }
+
+/*
+ * Initialize pdev subsystem.
+ */
+int
+dm_pdev_init(void)
+{
+       SLIST_INIT(&dm_pdev_list);      /* initialize global pdev list */
+       lockinit(&dm_pdev_mutex, "dmpdev", 0, LK_CANRECURSE);
+
+       return 0;
+}
+
+/*
+ * Destroy all existing pdev's in device-mapper.
+ */
+int
+dm_pdev_uninit(void)
+{
+       dm_pdev_t *dm_pdev;
+
+       lockmgr(&dm_pdev_mutex, LK_EXCLUSIVE);
+       while (!SLIST_EMPTY(&dm_pdev_list)) {   /* List Deletion. */
+
+               dm_pdev = SLIST_FIRST(&dm_pdev_list);
+
+               SLIST_REMOVE_HEAD(&dm_pdev_list, next_pdev);
+
+               dm_pdev_rem(dm_pdev);
+       }
+       lockmgr(&dm_pdev_mutex, LK_RELEASE);
+
+       lockuninit(&dm_pdev_mutex);
+       return 0;
+}
index 087bd73..5c72e2b 100644 (file)
@@ -191,32 +191,7 @@ dm_target_rem(char *dm_target_name)
 
        return 0;
 }
-/*
- * Destroy all targets and remove them from queue.
- * This routine is called from dm_detach, before module
- * is unloaded.
- */
-int
-dm_target_destroy(void)
-{
-       dm_target_t *dm_target;
-
-       lockmgr(&dm_target_mutex, LK_EXCLUSIVE);
-       while (TAILQ_FIRST(&dm_target_list) != NULL) {
-
-               dm_target = TAILQ_FIRST(&dm_target_list);
 
-               TAILQ_REMOVE(&dm_target_list, TAILQ_FIRST(&dm_target_list),
-                   dm_target_next);
-
-               (void) kfree(dm_target, M_DM);
-       }
-       lockmgr(&dm_target_mutex, LK_RELEASE);
-
-       lockuninit(&dm_target_mutex);
-
-       return 0;
-}
 /*
  * Allocate new target entry.
  */
@@ -271,3 +246,30 @@ dm_target_init(void)
 
        return 0;
 }
+
+/*
+ * Destroy all targets and remove them from queue.
+ * This routine is called from dm_detach, before module
+ * is unloaded.
+ */
+int
+dm_target_uninit(void)
+{
+       dm_target_t *dm_target;
+
+       lockmgr(&dm_target_mutex, LK_EXCLUSIVE);
+       while (TAILQ_FIRST(&dm_target_list) != NULL) {
+
+               dm_target = TAILQ_FIRST(&dm_target_list);
+
+               TAILQ_REMOVE(&dm_target_list, TAILQ_FIRST(&dm_target_list),
+                   dm_target_next);
+
+               (void) kfree(dm_target, M_DM);
+       }
+       lockmgr(&dm_target_mutex, LK_RELEASE);
+
+       lockuninit(&dm_target_mutex);
+
+       return 0;
+}
index 5735f60..f260750 100644 (file)
@@ -226,25 +226,6 @@ dm_target_linear_upcall(dm_table_entry_t * table_en, struct buf * bp)
 {
        return 0;
 }
-/*
- * Transform char s to uint64_t offset number.
- */
-uint64_t
-atoi64(const char *s)
-{
-       uint64_t n;
-       n = 0;
-
-       while (*s != '\0') {
-               if (!isdigit(*s))
-                       break;
-
-               n = (10 * n) + (*s - '0');
-               s++;
-       }
-
-       return n;
-}
 
 static int
 dmtl_mod_handler(module_t mod, int type, void *unused)