On 06/27/2013 04:57 PM, Bart Van Assche wrote:
> Disallow the SDEV_TRANSPORT_OFFLINE to SDEV_CANCEL transition such
> that no I/O is sent to devices for which the transport is offline.
> Notes:
> - Functions like sd_shutdown() use scsi_execute_req() and hence
>   set the REQ_PREEMPT flag. Such requests are passed to the LLD
>   queuecommand callback in the SDEV_CANCEL state.
> - This patch does not affect Fibre Channel LLD drivers since these
>   drivers invoke fc_remote_port_chkready() before submitting a SCSI
>   request to the HBA. That prevents a timeout to occur in state
>   SDEV_CANCEL if the transport is offline.
> 
> Signed-off-by: Bart Van Assche <bvanass...@acm.org>
> Cc: Mike Christie <micha...@cs.wisc.edu>
> Cc: James Bottomley <jbottom...@parallels.com>
> Cc: Hannes Reinecke <h...@suse.de>
> Cc: Tejun Heo <t...@kernel.org>
> ---
>  drivers/scsi/scsi_lib.c   |    1 -
>  drivers/scsi/scsi_sysfs.c |    4 +++-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 6a4fde7..63875c3 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -2180,7 +2180,6 @@ scsi_device_set_state(struct scsi_device *sdev, enum 
> scsi_device_state state)
>               case SDEV_RUNNING:
>               case SDEV_QUIESCE:
>               case SDEV_OFFLINE:
> -             case SDEV_TRANSPORT_OFFLINE:
>               case SDEV_BLOCK:
>                       break;
>               default:
> diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
> index dfbaa34..666b741 100644
> --- a/drivers/scsi/scsi_sysfs.c
> +++ b/drivers/scsi/scsi_sysfs.c
> @@ -959,14 +959,16 @@ void __scsi_remove_device(struct scsi_device *sdev)
>  {
>       struct Scsi_Host *shost = sdev->host;
>       struct device *dev = &sdev->sdev_gendev;
> +     enum scsi_device_state sdev_state;
>       int res;
>  
>       if (sdev->is_visible) {
>               spin_lock_irq(shost->host_lock);
> +             sdev_state = sdev->sdev_state;
>               res = scsi_device_set_state(sdev, SDEV_CANCEL);
>               spin_unlock_irq(shost->host_lock);
>  
> -             if (res != 0)
> +             if (res != 0 && sdev_state != SDEV_TRANSPORT_OFFLINE)
>                       return;
>  
>               bsg_unregister_queue(sdev->request_queue);
> 
Hmm. This is really subtle. Do you mind adding inserting a comment
here on why this is required?

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                   zSeries & Storage
h...@suse.de                          +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to