Skip to content

Commit cff549e

Browse files
Christoph HellwigJames Bottomley
Christoph Hellwig
authored and
James Bottomley
committed
scsi: proper state checking and module refcount handling in scsi_device_get
This effectively reverts commits 85b6c7 ("[SCSI] sd: fix cache flushing on module removal (and individual device removal)" and dc4515e ("scsi: always increment reference count"). We now never call scsi_device_get from the shutdown path, and the fact that we started grabbing reference there in commit 85b6c7 turned out turned out to create more problems than it solves, and required workarounds for workarounds for workarounds. Move back to properly checking the device state and carefully handle module refcounting. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Paolo Bonzini <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent 3d9a1f5 commit cff549e

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

drivers/scsi/scsi.c

+13-7
Original file line numberDiff line numberDiff line change
@@ -972,18 +972,24 @@ EXPORT_SYMBOL(scsi_report_opcode);
972972
* Description: Gets a reference to the scsi_device and increments the use count
973973
* of the underlying LLDD module. You must hold host_lock of the
974974
* parent Scsi_Host or already have a reference when calling this.
975+
*
976+
* This will fail if a device is deleted or cancelled, or when the LLD module
977+
* is in the process of being unloaded.
975978
*/
976979
int scsi_device_get(struct scsi_device *sdev)
977980
{
978-
if (sdev->sdev_state == SDEV_DEL)
979-
return -ENXIO;
981+
if (sdev->sdev_state == SDEV_DEL || sdev->sdev_state == SDEV_CANCEL)
982+
goto fail;
980983
if (!get_device(&sdev->sdev_gendev))
981-
return -ENXIO;
982-
/* We can fail try_module_get if we're doing SCSI operations
983-
* from module exit (like cache flush) */
984-
__module_get(sdev->host->hostt->module);
985-
984+
goto fail;
985+
if (!try_module_get(sdev->host->hostt->module))
986+
goto fail_put_device;
986987
return 0;
988+
989+
fail_put_device:
990+
put_device(&sdev->sdev_gendev);
991+
fail:
992+
return -ENXIO;
987993
}
988994
EXPORT_SYMBOL(scsi_device_get);
989995

0 commit comments

Comments
 (0)