diff options
author | Christoph Hellwig <hch@infradead.org> | 2014-02-20 17:20:55 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2014-03-15 13:19:24 -0400 |
commit | 0479633686d370303e3430256ace4bd5f7f138dc (patch) | |
tree | 8315562a82e4c64712d2d8ee423be2f346aa27c5 /drivers/scsi/scsi_lib.c | |
parent | 21a05df547dd0ac532d3a89e241dc504018eb881 (diff) |
[SCSI] do not manipulate device reference counts in scsi_get/put_command
Many callers won't need this and we can optimize them away. In addition
the handling in the __-prefixed variants was inconsistant to start with.
Based on an earlier patch from Bart Van Assche.
[jejb: fix kerneldoc probelm picked up by Fengguang Wu]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 492071ca45d1..007e979fa437 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -95,6 +95,7 @@ static void scsi_unprep_request(struct request *req) | |||
95 | req->special = NULL; | 95 | req->special = NULL; |
96 | 96 | ||
97 | scsi_put_command(cmd); | 97 | scsi_put_command(cmd); |
98 | put_device(&cmd->device->sdev_gendev); | ||
98 | } | 99 | } |
99 | 100 | ||
100 | /** | 101 | /** |
@@ -529,6 +530,7 @@ void scsi_next_command(struct scsi_cmnd *cmd) | |||
529 | get_device(&sdev->sdev_gendev); | 530 | get_device(&sdev->sdev_gendev); |
530 | 531 | ||
531 | scsi_put_command(cmd); | 532 | scsi_put_command(cmd); |
533 | put_device(&sdev->sdev_gendev); | ||
532 | scsi_run_queue(q); | 534 | scsi_run_queue(q); |
533 | 535 | ||
534 | /* ok to remove device now */ | 536 | /* ok to remove device now */ |
@@ -1123,6 +1125,7 @@ err_exit: | |||
1123 | scsi_release_buffers(cmd); | 1125 | scsi_release_buffers(cmd); |
1124 | cmd->request->special = NULL; | 1126 | cmd->request->special = NULL; |
1125 | scsi_put_command(cmd); | 1127 | scsi_put_command(cmd); |
1128 | put_device(&cmd->device->sdev_gendev); | ||
1126 | return error; | 1129 | return error; |
1127 | } | 1130 | } |
1128 | EXPORT_SYMBOL(scsi_init_io); | 1131 | EXPORT_SYMBOL(scsi_init_io); |
@@ -1133,9 +1136,15 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, | |||
1133 | struct scsi_cmnd *cmd; | 1136 | struct scsi_cmnd *cmd; |
1134 | 1137 | ||
1135 | if (!req->special) { | 1138 | if (!req->special) { |
1139 | /* Bail if we can't get a reference to the device */ | ||
1140 | if (!get_device(&sdev->sdev_gendev)) | ||
1141 | return NULL; | ||
1142 | |||
1136 | cmd = scsi_get_command(sdev, GFP_ATOMIC); | 1143 | cmd = scsi_get_command(sdev, GFP_ATOMIC); |
1137 | if (unlikely(!cmd)) | 1144 | if (unlikely(!cmd)) { |
1145 | put_device(&sdev->sdev_gendev); | ||
1138 | return NULL; | 1146 | return NULL; |
1147 | } | ||
1139 | req->special = cmd; | 1148 | req->special = cmd; |
1140 | } else { | 1149 | } else { |
1141 | cmd = req->special; | 1150 | cmd = req->special; |
@@ -1298,6 +1307,7 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret) | |||
1298 | struct scsi_cmnd *cmd = req->special; | 1307 | struct scsi_cmnd *cmd = req->special; |
1299 | scsi_release_buffers(cmd); | 1308 | scsi_release_buffers(cmd); |
1300 | scsi_put_command(cmd); | 1309 | scsi_put_command(cmd); |
1310 | put_device(&cmd->device->sdev_gendev); | ||
1301 | req->special = NULL; | 1311 | req->special = NULL; |
1302 | } | 1312 | } |
1303 | break; | 1313 | break; |