Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/dm Add private lock to dm_dev_t used for mutual excl...



details:   https://anonhg.NetBSD.org/src/rev/e6a604183edc
branches:  trunk
changeset: 750398:e6a604183edc
user:      haad <haad%NetBSD.org@localhost>
date:      Tue Dec 29 23:37:47 2009 +0000

description:
Add private lock to dm_dev_t used for mutual exclusion for diks(9) api
routines. This change fixes PR kern/42532.

diffstat:

 sys/dev/dm/device-mapper.c |  14 ++++++++++----
 sys/dev/dm/dm.h            |   6 +++++-
 sys/dev/dm/dm_dev.c        |  27 ++++++++++++++++++++++++++-
 sys/dev/dm/dm_ioctl.c      |   3 ++-
 4 files changed, 43 insertions(+), 7 deletions(-)

diffs (151 lines):

diff -r 3fe0cbd7870f -r e6a604183edc sys/dev/dm/device-mapper.c
--- a/sys/dev/dm/device-mapper.c        Tue Dec 29 23:01:09 2009 +0000
+++ b/sys/dev/dm/device-mapper.c        Tue Dec 29 23:37:47 2009 +0000
@@ -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);
 
diff -r 3fe0cbd7870f -r e6a604183edc sys/dev/dm/dm.h
--- a/sys/dev/dm/dm.h   Tue Dec 29 23:01:09 2009 +0000
+++ b/sys/dev/dm/dm.h   Tue Dec 29 23:37:47 2009 +0000
@@ -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 *);
diff -r 3fe0cbd7870f -r e6a604183edc sys/dev/dm/dm_dev.c
--- a/sys/dev/dm/dm_dev.c       Tue Dec 29 23:01:09 2009 +0000
+++ b/sys/dev/dm/dm_dev.c       Tue Dec 29 23:37:47 2009 +0000
@@ -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)
diff -r 3fe0cbd7870f -r e6a604183edc sys/dev/dm/dm_ioctl.c
--- a/sys/dev/dm/dm_ioctl.c     Tue Dec 29 23:01:09 2009 +0000
+++ b/sys/dev/dm/dm_ioctl.c     Tue Dec 29 23:37:47 2009 +0000
@@ -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);



Home | Main Index | Thread Index | Old Index