From: Alex Hornung Date: Mon, 13 Dec 2010 18:17:08 +0000 (+0000) Subject: dm - add remove_all, refactor X-Git-Tag: v2.11.0~464^2~14 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/9fada28acfffd04235bc0396c7244d25df88b68c dm - add remove_all, refactor * 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. --- diff --git a/sys/dev/disk/dm/device-mapper.c b/sys/dev/disk/dm/device-mapper.c index bae26df476..05b9440f39 100644 --- a/sys/dev/disk/dm/device-mapper.c +++ b/sys/dev/disk/dm/device-mapper.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -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) { diff --git a/sys/dev/disk/dm/dm.h b/sys/dev/disk/dm/dm.h index c8c55b5e81..82e09b55c4 100644 --- a/sys/dev/disk/dm/dm.h +++ b/sys/dev/disk/dm/dm.h @@ -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); diff --git a/sys/dev/disk/dm/dm_dev.c b/sys/dev/disk/dm/dm_dev.c index 7f0afffc95..029366f509 100644 --- a/sys/dev/disk/dm/dm_dev.c +++ b/sys/dev/disk/dm/dm_dev.c @@ -31,15 +31,26 @@ #include #include +#include +#include #include #include +#include +#include +#include +#include #include #include #include #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; } diff --git a/sys/dev/disk/dm/dm_ioctl.c b/sys/dev/disk/dm/dm_ioctl.c index 6376f1c2ed..32d05e940e 100644 --- a/sys/dev/disk/dm/dm_ioctl.c +++ b/sys/dev/disk/dm/dm_ioctl.c @@ -80,23 +80,13 @@ #include #include - #include -#include -#include -#include -#include #include -#include #include #include #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. */ diff --git a/sys/dev/disk/dm/dm_pdev.c b/sys/dev/disk/dm/dm_pdev.c index 934c2d6e82..5b17d76974 100644 --- a/sys/dev/disk/dm/dm_pdev.c +++ b/sys/dev/disk/dm/dm_pdev.c @@ -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; +} diff --git a/sys/dev/disk/dm/dm_target.c b/sys/dev/disk/dm/dm_target.c index 087bd73b6e..5c72e2b44c 100644 --- a/sys/dev/disk/dm/dm_target.c +++ b/sys/dev/disk/dm/dm_target.c @@ -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; +} diff --git a/sys/dev/disk/dm/targets/linear/dm_target_linear.c b/sys/dev/disk/dm/targets/linear/dm_target_linear.c index 5735f60043..f260750b01 100644 --- a/sys/dev/disk/dm/targets/linear/dm_target_linear.c +++ b/sys/dev/disk/dm/targets/linear/dm_target_linear.c @@ -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)