Module Name: src Committed By: haad Date: Tue Dec 29 23:37:48 UTC 2009
Modified Files: src/sys/dev/dm: device-mapper.c dm.h dm_dev.c dm_ioctl.c Log Message: Add private lock to dm_dev_t used for mutual exclusion for diks(9) api routines. This change fixes PR kern/42532. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/dev/dm/device-mapper.c cvs rdiff -u -r1.16 -r1.17 src/sys/dev/dm/dm.h cvs rdiff -u -r1.6 -r1.7 src/sys/dev/dm/dm_dev.c cvs rdiff -u -r1.17 -r1.18 src/sys/dev/dm/dm_ioctl.c 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.10 src/sys/dev/dm/device-mapper.c:1.11 --- src/sys/dev/dm/device-mapper.c:1.10 Sun Dec 6 14:33:46 2009 +++ src/sys/dev/dm/device-mapper.c Tue Dec 29 23:37:47 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: device-mapper.c,v 1.10 2009/12/06 14:33:46 haad Exp $ */ +/* $NetBSD: device-mapper.c,v 1.11 2009/12/29 23:37:47 haad Exp $ */ /* * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -402,8 +402,13 @@ return; } - /* FIXME: have to be called with IPL_BIO*/ + /* + * disk(9) is part of device structure and it can't be used without + * mutual exclusion, use diskp_mtx until it will be fixed. + */ + mutex_enter(&dmv->diskp_mtx); disk_busy(dmv->diskp); + mutex_exit(&dmv->diskp_mtx); /* Select active table */ tbl = dm_table_get_entry(&dmv->table_head, DM_TABLE_ACTIVE); @@ -459,9 +464,10 @@ if (issued_len < buf_len) nestiobuf_done(bp, buf_len - issued_len, EINVAL); - /* FIXME have to be called with SPL_BIO*/ + mutex_enter(&dmv->diskp_mtx); disk_unbusy(dmv->diskp, buf_len, bp != NULL ? bp->b_flags & B_READ : 0); - + mutex_exit(&dmv->diskp_mtx); + dm_table_release(&dmv->table_head, DM_TABLE_ACTIVE); dm_dev_unbusy(dmv); Index: src/sys/dev/dm/dm.h diff -u src/sys/dev/dm/dm.h:1.16 src/sys/dev/dm/dm.h:1.17 --- src/sys/dev/dm/dm.h:1.16 Sun Dec 6 14:31:16 2009 +++ src/sys/dev/dm/dm.h Tue Dec 29 23:37:48 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: dm.h,v 1.16 2009/12/06 14:31:16 haad Exp $ */ +/* $NetBSD: dm.h,v 1.17 2009/12/29 23:37:48 haad Exp $ */ /* * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -43,6 +43,7 @@ #include <sys/rwlock.h> #include <sys/queue.h> +#include <sys/device.h> #include <sys/disklabel.h> #include <prop/proplib.h> @@ -120,6 +121,7 @@ char name[DM_NAME_LEN]; char uuid[DM_UUID_LEN]; + device_t devt; /* pointer to autoconf device_t structure */ uint64_t minor; uint32_t flags; /* store communication protocol flags */ @@ -136,6 +138,7 @@ struct dm_dev_head upcalls; struct disk *diskp; + kmutex_t diskp_mtx; TAILQ_ENTRY(dm_dev) next_upcall; /* LIST of mirrored, snapshoted devices. */ @@ -357,6 +360,7 @@ dm_dev_t* dm_dev_alloc(void); void dm_dev_busy(dm_dev_t *); int dm_dev_destroy(void); +dm_dev_t* dm_dev_detach(device_t); int dm_dev_free(dm_dev_t *); int dm_dev_init(void); int dm_dev_insert(dm_dev_t *); Index: src/sys/dev/dm/dm_dev.c diff -u src/sys/dev/dm/dm_dev.c:1.6 src/sys/dev/dm/dm_dev.c:1.7 --- src/sys/dev/dm/dm_dev.c:1.6 Wed Sep 9 22:38:49 2009 +++ src/sys/dev/dm/dm_dev.c Tue Dec 29 23:37:48 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: dm_dev.c,v 1.6 2009/09/09 22:38:49 haad Exp $ */ +/* $NetBSD: dm_dev.c,v 1.7 2009/12/29 23:37:48 haad Exp $ */ /* * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -50,6 +50,7 @@ kmutex_t dm_dev_mutex; +/* dm_dev_mutex must be holdby caller before using disable_dev. */ __inline static void disable_dev(dm_dev_t *dmv) { @@ -220,6 +221,29 @@ } #endif +/* + * dm_dev_lookup_devt look for selected device_t. We keep this routine + * outside of dm_dev_lookup because it is a temporally solution. + * + * TODO: This is a hack autoconf should be more flexible. + */ +dm_dev_t * +dm_dev_detach(device_t devt) +{ + dm_dev_t *dmv; + + mutex_enter(&dm_dev_mutex); + TAILQ_FOREACH(dmv, &dm_dev_list, next_devlist){ + if (devt == dmv->devt){ + disable_dev(dmv); + return dmv; + } + } + mutex_exit(&dm_dev_mutex); + + return NULL; +} + /* * Remove device selected with dm_dev from global list of devices. */ @@ -321,6 +345,7 @@ KASSERT(dmv != NULL); mutex_destroy(&dmv->dev_mtx); + mutex_destroy(&dmv->diskp_mtx); cv_destroy(&dmv->dev_cv); if(dmv->diskp != NULL) Index: src/sys/dev/dm/dm_ioctl.c diff -u src/sys/dev/dm/dm_ioctl.c:1.17 src/sys/dev/dm/dm_ioctl.c:1.18 --- src/sys/dev/dm/dm_ioctl.c:1.17 Sun Dec 6 14:33:46 2009 +++ src/sys/dev/dm/dm_ioctl.c Tue Dec 29 23:37:48 2009 @@ -1,5 +1,5 @@ -/* $NetBSD: dm_ioctl.c,v 1.17 2009/12/06 14:33:46 haad Exp $ */ +/* $NetBSD: dm_ioctl.c,v 1.18 2009/12/29 23:37:48 haad Exp $ */ /* * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -237,6 +237,7 @@ dmv->dev_type = 0; 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);