aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-02-02 08:01:26 -0500
committerJames Bottomley <JBottomley@Parallels.com>2015-03-19 09:43:15 -0400
commitcff549e4860fcdea6b22510defdc8c8a0f82455a (patch)
tree62b1d3e75ba06f46593883beb0ef48ac684907a3
parent3d9a1f530e508ff6fc9ab8220016b02f1bce255b (diff)
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 dc4515ea ("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 <hch@lst.de> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/scsi.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index c9c3b579eece..3833bf59fb66 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -972,18 +972,24 @@ EXPORT_SYMBOL(scsi_report_opcode);
972 * Description: Gets a reference to the scsi_device and increments the use count 972 * Description: Gets a reference to the scsi_device and increments the use count
973 * of the underlying LLDD module. You must hold host_lock of the 973 * of the underlying LLDD module. You must hold host_lock of the
974 * parent Scsi_Host or already have a reference when calling this. 974 * 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.
975 */ 978 */
976int scsi_device_get(struct scsi_device *sdev) 979int scsi_device_get(struct scsi_device *sdev)
977{ 980{
978 if (sdev->sdev_state == SDEV_DEL) 981 if (sdev->sdev_state == SDEV_DEL || sdev->sdev_state == SDEV_CANCEL)
979 return -ENXIO; 982 goto fail;
980 if (!get_device(&sdev->sdev_gendev)) 983 if (!get_device(&sdev->sdev_gendev))
981 return -ENXIO; 984 goto fail;
982 /* We can fail try_module_get if we're doing SCSI operations 985 if (!try_module_get(sdev->host->hostt->module))
983 * from module exit (like cache flush) */ 986 goto fail_put_device;
984 __module_get(sdev->host->hostt->module);
985
986 return 0; 987 return 0;
988
989fail_put_device:
990 put_device(&sdev->sdev_gendev);
991fail:
992 return -ENXIO;
987} 993}
988EXPORT_SYMBOL(scsi_device_get); 994EXPORT_SYMBOL(scsi_device_get);
989 995