[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

RE: [dm-devel] failover does not work with rdac device handler



Hi Chandra,

Yes.  It works fine now.  I tested failover/failback few times and it works as expected. Thanks you very much for helping me to resolve this problem. Please let us know when this change is available in upstream kernel.

Thanks
Babu Moger

-----Original Message-----
From: Chandra Seetharaman [mailto:sekharan us ibm com]
Sent: Tuesday, October 07, 2008 2:19 PM
To: Moger, Babu
Cc: device-mapper development; linux-scsi vger kernel org
Subject: RE: [dm-devel] failover does not work with rdac device handler


Sorry, I sent an imcomplete patch. Here is the correct one.

BTW, The panic you saw is caused by the line (one of the lines you
added):

dev = container_of(&scsi_dh_data, struct scsi_device, scsi_dh_data);

in scsi_dh_release(). We cannot use pointer in a structure to get the
parent structure.

chandra

Keep a reference count of attaches, so that same number of detaches are allowed.
-----------

Signed-off-by: Chandra Seetharaman <sekharan us ibm com>
---
Index: linux-2.6.27-rc8-git5/drivers/scsi/device_handler/scsi_dh.c
===================================================================
--- linux-2.6.27-rc8-git5.orig/drivers/scsi/device_handler/scsi_dh.c
+++ linux-2.6.27-rc8-git5/drivers/scsi/device_handler/scsi_dh.c
@@ -153,12 +153,28 @@ static int scsi_dh_handler_attach(struct
        if (sdev->scsi_dh_data) {
                if (sdev->scsi_dh_data->scsi_dh != scsi_dh)
                        err = -EBUSY;
-       } else if (scsi_dh->attach)
+               else
+                       kref_get(&sdev->scsi_dh_data->kref);
+       } else if (scsi_dh->attach) {
                err = scsi_dh->attach(sdev);
+               if (!err) {
+                       kref_init(&sdev->scsi_dh_data->kref);
+                       sdev->scsi_dh_data->sdev = sdev;
+               }
+       }

        return err;
 }

+static void scsi_dh_release(struct kref *kref)
+{
+       struct scsi_dh_data *scsi_dh_data;
+       scsi_dh_data = container_of(kref, struct scsi_dh_data, kref);
+
+       if (scsi_dh_data->scsi_dh && scsi_dh_data->scsi_dh->detach)
+               scsi_dh_data->scsi_dh->detach(scsi_dh_data->sdev);
+}
+
 /*
  * scsi_dh_handler_detach - Detach a device handler from a device
  * @sdev - SCSI device the device handler should be detached from
@@ -176,11 +192,7 @@ static void scsi_dh_handler_detach(struc
        if (scsi_dh && scsi_dh != sdev->scsi_dh_data->scsi_dh)
                return;

-       if (!scsi_dh)
-               scsi_dh = sdev->scsi_dh_data->scsi_dh;
-
-       if (scsi_dh && scsi_dh->detach)
-               scsi_dh->detach(sdev);
+       kref_put(&sdev->scsi_dh_data->kref, scsi_dh_release);
 }

 /*
Index: linux-2.6.27-rc8-git5/include/scsi/scsi_device.h
===================================================================
--- linux-2.6.27-rc8-git5.orig/include/scsi/scsi_device.h
+++ linux-2.6.27-rc8-git5/include/scsi/scsi_device.h
@@ -6,6 +6,7 @@
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/blkdev.h>
+#include <linux/kref.h>
 #include <scsi/scsi.h>
 #include <asm/atomic.h>

@@ -191,6 +192,8 @@ struct scsi_device_handler {

 struct scsi_dh_data {
        struct scsi_device_handler *scsi_dh;
+       struct kref kref;
+       struct scsi_device *sdev; /* back reference */
        char buf[0];
 };





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]