summaryrefslogtreecommitdiff
path: root/sys/dev/dm/dm_ioctl.c
diff options
context:
space:
mode:
authorhaad <haad@NetBSD.org>2010-01-03 22:22:23 +0000
committerhaad <haad@NetBSD.org>2010-01-03 22:22:23 +0000
commitb9ba4842cecb48474989c2048ad9688736c134ff (patch)
tree5be023e9e58142a6ef7ad7f1a83577d9e70a41a2 /sys/dev/dm/dm_ioctl.c
parent0d3270a1695088c036d594ea9c26a89215ff61d7 (diff)
Hook device-mapper to autoconf framework. Add dm_attach, dm_match and dm_detach
routines used by autoconf users. Change dm_dev_remove_ioctl to call dm_detach. This should be primary used by kernel to disable devices during shutdown of system with nested disk devices. Requested by dyoung@.
Diffstat (limited to 'sys/dev/dm/dm_ioctl.c')
-rw-r--r--sys/dev/dm/dm_ioctl.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/sys/dev/dm/dm_ioctl.c b/sys/dev/dm/dm_ioctl.c
index 7d93d7455d5..d79a7d83ab4 100644
--- a/sys/dev/dm/dm_ioctl.c
+++ b/sys/dev/dm/dm_ioctl.c
@@ -1,5 +1,5 @@
-/* $NetBSD: dm_ioctl.c,v 1.18 2009/12/29 23:37:48 haad Exp $ */
+/* $NetBSD: dm_ioctl.c,v 1.19 2010/01/03 22:22:23 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -82,6 +82,7 @@
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/device.h>
#include <sys/disk.h>
#include <sys/disklabel.h>
#include <sys/kmem.h>
@@ -97,6 +98,14 @@ static uint64_t sc_minor_num;
extern const struct dkdriver dmdkdriver;
uint64_t dev_counter;
+/* Generic cf_data for device-mapper driver */
+static struct cfdata dm_cfdata = {
+ .cf_name = "dm",
+ .cf_atname = "dm",
+ .cf_fstate = FSTATE_STAR,
+ .cf_unit = 0
+};
+
#define DM_REMOVE_FLAG(flag, name) do { \
prop_dictionary_get_uint32(dm_dict,DM_IOCTL_FLAGS,&flag); \
flag &= ~name; \
@@ -198,6 +207,7 @@ dm_dev_create_ioctl(prop_dictionary_t dm_dict)
dm_dev_t *dmv;
const char *name, *uuid;
int r, flags;
+ device_t devt;
r = 0;
flags = 0;
@@ -218,9 +228,14 @@ dm_dev_create_ioctl(prop_dictionary_t dm_dict)
return EEXIST;
}
+ if ((devt = config_attach_pseudo(&dm_cfdata)) == NULL) {
+ aprint_error("Unable to attach pseudo device dm/%s\n", name);
+ return (ENOMEM);
+ }
+
if ((dmv = dm_dev_alloc()) == NULL)
return ENOMEM;
-
+
if (uuid)
strncpy(dmv->uuid, uuid, DM_UUID_LEN);
else
@@ -230,18 +245,18 @@ dm_dev_create_ioctl(prop_dictionary_t dm_dict)
strlcpy(dmv->name, name, DM_NAME_LEN);
dmv->minor = atomic_inc_64_nv(&sc_minor_num);
-
dmv->flags = 0; /* device flags are set when needed */
dmv->ref_cnt = 0;
dmv->event_nr = 0;
dmv->dev_type = 0;
+ dmv->devt = devt;
+ dm_table_head_init(&dmv->table_head);
+
mutex_init(&dmv->dev_mtx, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&dmv->diskp_mtx, MUTEX_DEFAULT, IPL_NONE);
cv_init(&dmv->dev_cv, "dm_dev");
- dm_table_head_init(&dmv->table_head);
-
if (flags & DM_READONLY_FLAG)
dmv->flags |= DM_READONLY_FLAG;
@@ -371,6 +386,7 @@ dm_dev_remove_ioctl(prop_dictionary_t dm_dict)
dm_dev_t *dmv;
const char *name, *uuid;
uint32_t flags, minor;
+ device_t devt;
flags = 0;
name = NULL;
@@ -383,32 +399,20 @@ dm_dev_remove_ioctl(prop_dictionary_t dm_dict)
prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
dm_dbg_print_flags(flags);
-
- /* Remove device from global device list */
- if ((dmv = dm_dev_rem(name, uuid, minor)) == NULL){
+
+ /* This seems as hack to me, probably use routine dm_dev_get_devt to
+ atomicaly get devt from device. */
+ if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
return ENOENT;
}
- /* 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);
-
- /* Destroy disk device structure */
- disk_detach(dmv->diskp);
- disk_destroy(dmv->diskp);
-
- /* Destroy device */
- (void)dm_dev_free(dmv);
+ devt = dmv->devt;
- /* Decrement device counter After removing device */
- atomic_dec_64(&dev_counter);
+ dm_dev_unbusy(dmv);
- return 0;
+ /* This will call dm_detach routine which will actually removes device. */
+ return config_detach(devt, DETACH_QUIET);
}
/*