Module Name: src Committed By: haad Date: Sun Jan 3 22:22:23 UTC 2010
Modified Files: src/sys/dev/dm: device-mapper.c dm_ioctl.c files.dm Log Message: 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 dyo...@. To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 src/sys/dev/dm/device-mapper.c cvs rdiff -u -r1.18 -r1.19 src/sys/dev/dm/dm_ioctl.c cvs rdiff -u -r1.5 -r1.6 src/sys/dev/dm/files.dm Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/dm/device-mapper.c diff -u src/sys/dev/dm/device-mapper.c:1.11 src/sys/dev/dm/device-mapper.c:1.12 --- src/sys/dev/dm/device-mapper.c:1.11 Tue Dec 29 23:37:47 2009 +++ src/sys/dev/dm/device-mapper.c Sun Jan 3 22:22:23 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: device-mapper.c,v 1.11 2009/12/29 23:37:47 haad Exp $ */ +/* $NetBSD: device-mapper.c,v 1.12 2010/01/03 22:22:23 haad Exp $ */ /* * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -38,6 +38,7 @@ #include <sys/buf.h> #include <sys/conf.h> +#include <sys/device.h> #include <sys/dkio.h> #include <sys/disk.h> #include <sys/disklabel.h> @@ -58,14 +59,19 @@ static dev_type_size(dmsize); /* attach and detach routines */ -int dmattach(void); -int dmdestroy(void); +static int dmattach(void); +static int dmdestroy(void); static int dm_cmd_to_fun(prop_dictionary_t); static int disk_ioctl_switch(dev_t, u_long, void *); static int dm_ioctl_switch(u_long); static void dmminphys(struct buf *); +/* CF attach/detach functions used for power management */ +static int dm_detach(device_t, int); +static void dm_attach(device_t, device_t, void *); +static int dm_match(device_t, cfdata_t, void *); + /* ***Variable-definitions*** */ const struct bdevsw dm_bdevsw = { .d_open = dmopen, @@ -95,6 +101,14 @@ .d_strategy = dmstrategy }; +/* Autoconf defines */ +CFDRIVER_DECL(dm, DV_DISK, NULL); +CFATTACH_DECL3_NEW(dm, 0, + dm_match, dm_attach, dm_detach, NULL, NULL, NULL, + DVF_DETACH_SHUTDOWN); + +extern struct cfdriver dm_cd; + extern uint64_t dev_counter; /* @@ -134,11 +148,27 @@ { #ifdef _MODULE int bmajor = -1, cmajor = -1; + int error; + + error = 0; switch (cmd) { case MODULE_CMD_INIT: dmattach(); - return devsw_attach("dm", &dm_bdevsw, &bmajor, + + error = config_cfdriver_attach(&dm_cd); + if (error) + break; + + error = config_cfattach_attach(dm_cd.cd_name, &dm_ca); + if (error) { + config_cfdriver_detach(&dm_cd); + aprint_error("Unable to register cfattach for dm driver\n"); + + break; + } + + error = devsw_attach("dm", &dm_bdevsw, &bmajor, &dm_cdevsw, &cmajor); break; @@ -152,7 +182,14 @@ if (dev_counter > 0) return EBUSY; dmdestroy(); - return devsw_detach(&dm_bdevsw, &dm_cdevsw); + + error = config_cfattach_detach(dm_cd.cd_name, &dm_ca); + if (error) + break; + + config_cfdriver_detach(&dm_cd); + + devsw_detach(&dm_bdevsw, &dm_cdevsw); break; case MODULE_CMD_STAT: return ENOTTY; @@ -161,7 +198,7 @@ return ENOTTY; } - return 0; + return error; #else if (cmd == MODULE_CMD_INIT) @@ -172,10 +209,75 @@ } +/* + * dm_match: + * + * Autoconfiguration match function for pseudo-device glue. + */ +static int +dm_match(device_t parent, cfdata_t match, + void *aux) +{ + + /* Pseudo-device; always present. */ + return (1); +} + +/* + * dm_attach: + * + * Autoconfiguration attach function for pseudo-device glue. + */ +static void +dm_attach(device_t parent, device_t self, + void *aux) +{ + return; +} + + +/* + * dm_detach: + * + * Autoconfiguration detach function for pseudo-device glue. + * This routine is called by dm_ioctl::dm_dev_remove_ioctl and by autoconf to + * remove devices created in device-mapper. + */ +static int +dm_detach(device_t self, int flags) +{ + dm_dev_t *dmv; + + /* Detach device from global device list */ + if ((dmv = dm_dev_detach(self)) == NULL) + 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); + + /* Decrement device counter After removing device */ + atomic_dec_64(&dev_counter); + + return 0; +} + /* attach routine */ -int +static int dmattach(void) { + dm_target_init(); dm_dev_init(); dm_pdev_init(); @@ -184,9 +286,10 @@ } /* Destroy routine */ -int +static int dmdestroy(void) { + dm_dev_destroy(); dm_pdev_destroy(); dm_target_destroy(); @@ -197,6 +300,7 @@ static int dmopen(dev_t dev, int flags, int mode, struct lwp *l) { + aprint_debug("open routine called %" PRIu32 "\n", minor(dev)); return 0; } @@ -204,8 +308,8 @@ static int dmclose(dev_t dev, int flags, int mode, struct lwp *l) { - aprint_debug("CLOSE routine called\n"); + aprint_debug("CLOSE routine called\n"); return 0; } Index: src/sys/dev/dm/dm_ioctl.c diff -u src/sys/dev/dm/dm_ioctl.c:1.18 src/sys/dev/dm/dm_ioctl.c:1.19 --- src/sys/dev/dm/dm_ioctl.c:1.18 Tue Dec 29 23:37:48 2009 +++ src/sys/dev/dm/dm_ioctl.c Sun Jan 3 22:22:23 2010 @@ -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 @@ 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_t *dmv; const char *name, *uuid; int r, flags; + device_t devt; r = 0; flags = 0; @@ -218,9 +228,14 @@ 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 @@ 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_t *dmv; const char *name, *uuid; uint32_t flags, minor; + device_t devt; flags = 0; name = NULL; @@ -383,32 +399,20 @@ 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); } /* Index: src/sys/dev/dm/files.dm diff -u src/sys/dev/dm/files.dm:1.5 src/sys/dev/dm/files.dm:1.6 --- src/sys/dev/dm/files.dm:1.5 Sun Jun 28 22:05:07 2009 +++ src/sys/dev/dm/files.dm Sun Jan 3 22:22:23 2010 @@ -1,4 +1,4 @@ -defpseudo dm +defpseudodev dm file dev/dm/device-mapper.c dm file dev/dm/dm_dev.c dm file dev/dm/dm_ioctl.c dm