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);

Reply via email to