From patchwork Mon Jul 6 14:15:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 6724651 Return-Path: X-Original-To: patchwork-linux-scsi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7415B9F319 for ; Mon, 6 Jul 2015 14:15:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 80FD52055A for ; Mon, 6 Jul 2015 14:15:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 909C9206D5 for ; Mon, 6 Jul 2015 14:15:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752177AbbGFOPS (ORCPT ); Mon, 6 Jul 2015 10:15:18 -0400 Received: from cantor2.suse.de ([195.135.220.15]:51813 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751860AbbGFOPL (ORCPT ); Mon, 6 Jul 2015 10:15:11 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 9CCC9ADC2; Mon, 6 Jul 2015 14:15:07 +0000 (UTC) From: Hannes Reinecke To: James Bottomley Cc: Christoph Hellwig , linux-scsi@vger.kernel.org, "Martin K. Petersen" , Mike Snitzer Subject: [PATCH 7/9] scsi_dh: add a common helper to get a scsi_device from a request_queue Date: Mon, 6 Jul 2015 16:15:03 +0200 Message-Id: <1436192105-44064-8-git-send-email-hare@suse.de> X-Mailer: git-send-email 1.8.5.2 In-Reply-To: <1436192105-44064-1-git-send-email-hare@suse.de> References: <1436192105-44064-1-git-send-email-hare@suse.de> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Christoph Hellwig And cleanup the various messy opencoded versions of this. Note that this moves the sdev_state checks outside the queue_lock coverage, but as we don't hold the lock over the activation they are only advisory anyway. Signed-off-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Hannes Reinecke --- drivers/scsi/scsi_dh.c | 99 +++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c index f0b100e..8cae1c9 100644 --- a/drivers/scsi/scsi_dh.c +++ b/drivers/scsi/scsi_dh.c @@ -281,6 +281,20 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) } EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); +static struct scsi_device *get_sdev_from_queue(struct request_queue *q) +{ + struct scsi_device *sdev; + unsigned long flags; + + spin_lock_irqsave(q->queue_lock, flags); + sdev = q->queuedata; + if (!sdev || !get_device(&sdev->sdev_gendev)) + sdev = NULL; + spin_unlock_irqrestore(q->queue_lock, flags); + + return sdev; +} + /* * scsi_dh_activate - activate the path associated with the scsi_device * corresponding to the given request queue. @@ -296,41 +310,37 @@ EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); */ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) { - int err = 0; - unsigned long flags; struct scsi_device *sdev; - struct device *dev = NULL; + int err = SCSI_DH_NOSYS; - spin_lock_irqsave(q->queue_lock, flags); - sdev = q->queuedata; + sdev = get_sdev_from_queue(q); if (!sdev) { - spin_unlock_irqrestore(q->queue_lock, flags); - err = SCSI_DH_NOSYS; if (fn) fn(data, err); return err; } - dev = get_device(&sdev->sdev_gendev); - if (!sdev->handler || !dev || - sdev->sdev_state == SDEV_CANCEL || + if (!sdev->handler) + goto out_fn; + if (sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL) - err = SCSI_DH_NOSYS; - if (sdev->sdev_state == SDEV_OFFLINE) - err = SCSI_DH_DEV_OFFLINED; - spin_unlock_irqrestore(q->queue_lock, flags); + goto out_fn; - if (err) { - if (fn) - fn(data, err); - goto out; - } + err = SCSI_DH_DEV_OFFLINED; + if (sdev->sdev_state == SDEV_OFFLINE) + goto out_fn; if (sdev->handler->activate) err = sdev->handler->activate(sdev, fn, data); -out: - put_device(dev); + +out_put_device: + put_device(&sdev->sdev_gendev); return err; + +out_fn: + if (fn) + fn(data, err); + goto out_put_device; } EXPORT_SYMBOL_GPL(scsi_dh_activate); @@ -346,21 +356,15 @@ EXPORT_SYMBOL_GPL(scsi_dh_activate); */ int scsi_dh_set_params(struct request_queue *q, const char *params) { - int err = -SCSI_DH_NOSYS; - unsigned long flags; struct scsi_device *sdev; + int err = -SCSI_DH_NOSYS; - spin_lock_irqsave(q->queue_lock, flags); - sdev = q->queuedata; - if (sdev->handler && - sdev->handler->set_params && - get_device(&sdev->sdev_gendev)) - err = 0; - spin_unlock_irqrestore(q->queue_lock, flags); - - if (err) + sdev = get_sdev_from_queue(q); + if (!sdev) return err; - err = sdev->handler->set_params(sdev, params); + + if (sdev->handler && sdev->handler->set_params) + err = sdev->handler->set_params(sdev, params); put_device(&sdev->sdev_gendev); return err; } @@ -374,23 +378,19 @@ EXPORT_SYMBOL_GPL(scsi_dh_set_params); */ int scsi_dh_attach(struct request_queue *q, const char *name) { - unsigned long flags; struct scsi_device *sdev; struct scsi_device_handler *scsi_dh; int err = 0; - scsi_dh = scsi_dh_lookup(name); - if (!scsi_dh) - return -EINVAL; - - spin_lock_irqsave(q->queue_lock, flags); - sdev = q->queuedata; - if (!sdev || !get_device(&sdev->sdev_gendev)) - err = -ENODEV; - spin_unlock_irqrestore(q->queue_lock, flags); + sdev = get_sdev_from_queue(q); + if (!sdev) + return -ENODEV; - if (err) - return err; + scsi_dh = scsi_dh_lookup(name); + if (!scsi_dh) { + err = -EINVAL; + goto out_put_device; + } if (sdev->handler) { if (sdev->handler != scsi_dh) @@ -417,22 +417,15 @@ EXPORT_SYMBOL_GPL(scsi_dh_attach); */ const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp) { - unsigned long flags; struct scsi_device *sdev; const char *handler_name = NULL; - spin_lock_irqsave(q->queue_lock, flags); - sdev = q->queuedata; - if (!sdev || !get_device(&sdev->sdev_gendev)) - sdev = NULL; - spin_unlock_irqrestore(q->queue_lock, flags); - + sdev = get_sdev_from_queue(q); if (!sdev) return NULL; if (sdev->handler) handler_name = kstrdup(sdev->handler->name, gfp); - put_device(&sdev->sdev_gendev); return handler_name; }