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@xxxxxxxxxx] Sent: Tuesday, October 07, 2008 2:19 PM To: Moger, Babu Cc: device-mapper development; linux-scsi@xxxxxxxxxxxxxxx Subject: RE: 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@xxxxxxxxxx> --- 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]; }; -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel