diff mbox

[1/3] scsi: allow state transition CREATED_BLOCK -> TRANSPORT_OFFLINE

Message ID 1502348731-63534-2-git-send-email-hare@suse.de (mailing list archive)
State Changes Requested, archived
Headers show

Commit Message

Hannes Reinecke Aug. 10, 2017, 7:05 a.m. UTC
scsi_internal_device_unblock_nowait() allows a state transition
SDEV_CREATED_BLOCK -> SDEV_TRANSPORT_OFFLINE/SDEV_OFFLINE,
scsi_device_set_state() does not.
So add the missing state transition to scsi_device_set_state().

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/scsi_lib.c | 1 +
 1 file changed, 1 insertion(+)

Comments

Johannes Thumshirn Aug. 10, 2017, 7:09 a.m. UTC | #1
Looks good,
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Christoph Hellwig Aug. 10, 2017, 9:26 a.m. UTC | #2
Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>
James Bottomley Aug. 10, 2017, 2:31 p.m. UTC | #3
On Thu, 2017-08-10 at 09:05 +0200, Hannes Reinecke wrote:
> scsi_internal_device_unblock_nowait() allows a state transition
> SDEV_CREATED_BLOCK -> SDEV_TRANSPORT_OFFLINE/SDEV_OFFLINE,
> scsi_device_set_state() does not.
> So add the missing state transition to scsi_device_set_state().
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>  drivers/scsi/scsi_lib.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 41c19c7..1ae531b 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -2599,6 +2599,7 @@ void scsi_exit_queue(void)
>  		case SDEV_RUNNING:
>  		case SDEV_QUIESCE:
>  		case SDEV_BLOCK:
> +		case SDEV_CREATED_BLOCK:
>  			break;
>  		default:
>  			goto illegal;

This isn't quite good enough: a device that went CREATE_BLOCK ->
OFFLINE, the queue will still be stopped meaning I/O will pile up in it
forever and it won't restart when the device is brought online.  It we
need to set the queue running again so that the now offline device
errors all pending I/O.  It looks like this is a bug in BLOCK->OFFLINE
too.

We can't simply call scsi_start_queue() from within
scsi_device_set_state() because we may have a lock recursion problem,
so we might have to introduce a new state that allows the queue to be
restarted in the caller.

James
diff mbox

Patch

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 41c19c7..1ae531b 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2599,6 +2599,7 @@  void scsi_exit_queue(void)
 		case SDEV_RUNNING:
 		case SDEV_QUIESCE:
 		case SDEV_BLOCK:
+		case SDEV_CREATED_BLOCK:
 			break;
 		default:
 			goto illegal;