From patchwork Sat Jun 27 02:30:06 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chandra Seetharaman X-Patchwork-Id: 32646 Received: from hormel.redhat.com (hormel1.redhat.com [209.132.177.33]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n5R2SD6S032549 for ; Sat, 27 Jun 2009 02:28:13 GMT Received: from listman.util.phx.redhat.com (listman.util.phx.redhat.com [10.8.4.110]) by hormel.redhat.com (Postfix) with ESMTP id 244E461A216; Fri, 26 Jun 2009 22:28:12 -0400 (EDT) Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by listman.util.phx.redhat.com (8.13.1/8.13.1) with ESMTP id n5R2S9LU014022 for ; Fri, 26 Jun 2009 22:28:10 -0400 Received: from mx1.redhat.com (mx1.redhat.com [172.16.48.31]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n5R2S9TJ002028 for ; Fri, 26 Jun 2009 22:28:09 -0400 Received: from e34.co.us.ibm.com (e34.co.us.ibm.com [32.97.110.152]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n5R2Rnv0003700 for ; Fri, 26 Jun 2009 22:27:49 -0400 Received: from d03relay02.boulder.ibm.com (d03relay02.boulder.ibm.com [9.17.195.227]) by e34.co.us.ibm.com (8.13.1/8.13.1) with ESMTP id n5R2OZdH008924 for ; Fri, 26 Jun 2009 20:24:35 -0600 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay02.boulder.ibm.com (8.13.8/8.13.8/NCO v9.2) with ESMTP id n5R2RmQe113432 for ; Fri, 26 Jun 2009 20:27:48 -0600 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id n5R2RmQl005289 for ; Fri, 26 Jun 2009 20:27:48 -0600 Received: from [9.47.17.98] (chandra-ubuntu.beaverton.ibm.com [9.47.17.98]) by d03av02.boulder.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id n5R2Rlvg005272; Fri, 26 Jun 2009 20:27:47 -0600 From: Chandra Seetharaman To: Linux SCSI Mailing list Organization: IBM Date: Fri, 26 Jun 2009 19:30:06 -0700 Message-Id: <1246069806.14164.49.camel@chandra-ubuntu> Mime-Version: 1.0 X-RedHat-Spam-Score: -3.5 X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 X-Scanned-By: MIMEDefang 2.63 on 172.16.48.31 X-loop: dm-devel@redhat.com Cc: Mario Mech , dm-devel Subject: [dm-devel] [PATCH]: scsi_dh: Reference count scsi_dh_attach X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.5 Precedence: junk Reply-To: sekharan@linux.vnet.ibm.com, device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com Problem reported: http://marc.info/?l=dm-devel&m=124585978305866&w=2 This patch fixes the problem: ----------------- scsi_dh does not do a refernce count for attach/detach, and this affects the way it is supposed to work with multipath when a device is not in the dev_list of the hardware handler. This patch adds a reference count that counts each attach. Signed-Off-by: Chandra Seetharaman --- drivers/scsi/device_handler/scsi_dh.c | 23 ++++++++++++++++------- include/scsi/scsi_device.h | 2 ++ 2 files changed, 18 insertions(+), 7 deletions(-) -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel Index: linux-2.6.31-rc1/include/scsi/scsi_device.h =================================================================== --- linux-2.6.31-rc1.orig/include/scsi/scsi_device.h +++ linux-2.6.31-rc1/include/scsi/scsi_device.h @@ -191,6 +191,8 @@ struct scsi_device_handler { struct scsi_dh_data { struct scsi_device_handler *scsi_dh; + struct scsi_device *sdev; + struct kref kref; char buf[0]; }; Index: linux-2.6.31-rc1/drivers/scsi/device_handler/scsi_dh.c =================================================================== --- linux-2.6.31-rc1.orig/drivers/scsi/device_handler/scsi_dh.c +++ linux-2.6.31-rc1/drivers/scsi/device_handler/scsi_dh.c @@ -153,12 +153,24 @@ 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 __detach_handler (struct kref *kref) +{ + struct scsi_dh_data *scsi_dh_data = container_of(kref, struct scsi_dh_data, kref); + 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 @@ -180,7 +192,7 @@ static void scsi_dh_handler_detach(struc 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, __detach_handler); } /* @@ -474,7 +486,6 @@ int scsi_dh_attach(struct request_queue if (!err) { err = scsi_dh_handler_attach(sdev, scsi_dh); - put_device(&sdev->sdev_gendev); } return err; @@ -505,10 +516,8 @@ void scsi_dh_detach(struct request_queue return; if (sdev->scsi_dh_data) { - /* if sdev is not on internal list, detach */ scsi_dh = sdev->scsi_dh_data->scsi_dh; - if (!device_handler_match(scsi_dh, sdev)) - scsi_dh_handler_detach(sdev, scsi_dh); + scsi_dh_handler_detach(sdev, scsi_dh); } put_device(&sdev->sdev_gendev); }