[dm-devel] failover does not work with rdac device handler
Moger, Babu
Babu.Moger at lsi.com
Tue Oct 7 20:26:11 UTC 2008
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 at us.ibm.com]
Sent: Tuesday, October 07, 2008 2:19 PM
To: Moger, Babu
Cc: device-mapper development; linux-scsi at 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 at 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];
};
More information about the dm-devel
mailing list