scsi: remove scsi_end_request
By folding scsi_end_request into its only caller we can significantly clean up the completion logic. We can use simple goto labels now to only have a single place to finish or requeue command there instead of the previous convoluted logic. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Nicholas Bellinger <nab@linux-iscsi.org> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Reviewed-by: Hannes Reinecke <hare@suse.de>
This commit is contained in:
parent
c682adf3e1
commit
bc85dc500f
@ -512,66 +512,6 @@ void scsi_run_host_queues(struct Scsi_Host *shost)
|
|||||||
scsi_run_queue(sdev->request_queue);
|
scsi_run_queue(sdev->request_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: scsi_end_request()
|
|
||||||
*
|
|
||||||
* Purpose: Post-processing of completed commands (usually invoked at end
|
|
||||||
* of upper level post-processing and scsi_io_completion).
|
|
||||||
*
|
|
||||||
* Arguments: cmd - command that is complete.
|
|
||||||
* error - 0 if I/O indicates success, < 0 for I/O error.
|
|
||||||
* bytes - number of bytes of completed I/O
|
|
||||||
* requeue - indicates whether we should requeue leftovers.
|
|
||||||
*
|
|
||||||
* Lock status: Assumed that lock is not held upon entry.
|
|
||||||
*
|
|
||||||
* Returns: cmd if requeue required, NULL otherwise.
|
|
||||||
*
|
|
||||||
* Notes: This is called for block device requests in order to
|
|
||||||
* mark some number of sectors as complete.
|
|
||||||
*
|
|
||||||
* We are guaranteeing that the request queue will be goosed
|
|
||||||
* at some point during this call.
|
|
||||||
* Notes: If cmd was requeued, upon return it will be a stale pointer.
|
|
||||||
*/
|
|
||||||
static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
|
|
||||||
int bytes, int requeue)
|
|
||||||
{
|
|
||||||
struct request_queue *q = cmd->device->request_queue;
|
|
||||||
struct request *req = cmd->request;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If there are blocks left over at the end, set up the command
|
|
||||||
* to queue the remainder of them.
|
|
||||||
*/
|
|
||||||
if (blk_end_request(req, error, bytes)) {
|
|
||||||
/* kill remainder if no retrys */
|
|
||||||
if (error && scsi_noretry_cmd(cmd))
|
|
||||||
blk_end_request_all(req, error);
|
|
||||||
else {
|
|
||||||
if (requeue) {
|
|
||||||
/*
|
|
||||||
* Bleah. Leftovers again. Stick the
|
|
||||||
* leftovers in the front of the
|
|
||||||
* queue, and goose the queue again.
|
|
||||||
*/
|
|
||||||
scsi_release_buffers(cmd);
|
|
||||||
scsi_requeue_command(q, cmd);
|
|
||||||
cmd = NULL;
|
|
||||||
}
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This will goose the queue request function at the end, so we don't
|
|
||||||
* need to worry about launching another command.
|
|
||||||
*/
|
|
||||||
scsi_release_buffers(cmd);
|
|
||||||
scsi_next_command(cmd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int scsi_sgtable_index(unsigned short nents)
|
static inline unsigned int scsi_sgtable_index(unsigned short nents)
|
||||||
{
|
{
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
@ -717,16 +657,9 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
|
|||||||
*
|
*
|
||||||
* Returns: Nothing
|
* Returns: Nothing
|
||||||
*
|
*
|
||||||
* Notes: This function is matched in terms of capabilities to
|
* Notes: We will finish off the specified number of sectors. If we
|
||||||
* the function that created the scatter-gather list.
|
* are done, the command block will be released and the queue
|
||||||
* In other words, if there are no bounce buffers
|
* function will be goosed. If we are not done then we have to
|
||||||
* (the normal case for most drivers), we don't need
|
|
||||||
* the logic to deal with cleaning up afterwards.
|
|
||||||
*
|
|
||||||
* We must call scsi_end_request(). This will finish off
|
|
||||||
* the specified number of sectors. If we are done, the
|
|
||||||
* command block will be released and the queue function
|
|
||||||
* will be goosed. If we are not done then we have to
|
|
||||||
* figure out what to do next:
|
* figure out what to do next:
|
||||||
*
|
*
|
||||||
* a) We can call scsi_requeue_command(). The request
|
* a) We can call scsi_requeue_command(). The request
|
||||||
@ -735,7 +668,7 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
|
|||||||
* be used if we made forward progress, or if we want
|
* be used if we made forward progress, or if we want
|
||||||
* to switch from READ(10) to READ(6) for example.
|
* to switch from READ(10) to READ(6) for example.
|
||||||
*
|
*
|
||||||
* b) We can call scsi_queue_insert(). The request will
|
* b) We can call __scsi_queue_insert(). The request will
|
||||||
* be put back on the queue and retried using the same
|
* be put back on the queue and retried using the same
|
||||||
* command as before, possibly after a delay.
|
* command as before, possibly after a delay.
|
||||||
*
|
*
|
||||||
@ -794,6 +727,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
|
|||||||
|
|
||||||
scsi_release_buffers(cmd);
|
scsi_release_buffers(cmd);
|
||||||
scsi_release_bidi_buffers(cmd);
|
scsi_release_bidi_buffers(cmd);
|
||||||
|
|
||||||
blk_end_request_all(req, 0);
|
blk_end_request_all(req, 0);
|
||||||
|
|
||||||
scsi_next_command(cmd);
|
scsi_next_command(cmd);
|
||||||
@ -833,12 +767,25 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A number of bytes were successfully read. If there
|
* If we finished all bytes in the request we are done now.
|
||||||
* are leftovers and there is some kind of error
|
|
||||||
* (result != 0), retry the rest.
|
|
||||||
*/
|
*/
|
||||||
if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL)
|
if (!blk_end_request(req, error, good_bytes))
|
||||||
return;
|
goto next_command;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kill remainder if no retrys.
|
||||||
|
*/
|
||||||
|
if (error && scsi_noretry_cmd(cmd)) {
|
||||||
|
blk_end_request_all(req, error);
|
||||||
|
goto next_command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there had been no error, but we have leftover bytes in the
|
||||||
|
* requeues just queue the command up again.
|
||||||
|
*/
|
||||||
|
if (result == 0)
|
||||||
|
goto requeue;
|
||||||
|
|
||||||
error = __scsi_error_from_host_byte(cmd, result);
|
error = __scsi_error_from_host_byte(cmd, result);
|
||||||
|
|
||||||
@ -966,7 +913,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
case ACTION_FAIL:
|
case ACTION_FAIL:
|
||||||
/* Give up and fail the remainder of the request */
|
/* Give up and fail the remainder of the request */
|
||||||
scsi_release_buffers(cmd);
|
|
||||||
if (!(req->cmd_flags & REQ_QUIET)) {
|
if (!(req->cmd_flags & REQ_QUIET)) {
|
||||||
if (description)
|
if (description)
|
||||||
scmd_printk(KERN_INFO, cmd, "%s\n",
|
scmd_printk(KERN_INFO, cmd, "%s\n",
|
||||||
@ -976,12 +922,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
|
|||||||
scsi_print_sense("", cmd);
|
scsi_print_sense("", cmd);
|
||||||
scsi_print_command(cmd);
|
scsi_print_command(cmd);
|
||||||
}
|
}
|
||||||
if (blk_end_request_err(req, error))
|
if (!blk_end_request_err(req, error))
|
||||||
scsi_requeue_command(q, cmd);
|
goto next_command;
|
||||||
else
|
/*FALLTHRU*/
|
||||||
scsi_next_command(cmd);
|
|
||||||
break;
|
|
||||||
case ACTION_REPREP:
|
case ACTION_REPREP:
|
||||||
|
requeue:
|
||||||
/* Unprep the request and put it back at the head of the queue.
|
/* Unprep the request and put it back at the head of the queue.
|
||||||
* A new command will be prepared and issued.
|
* A new command will be prepared and issued.
|
||||||
*/
|
*/
|
||||||
@ -997,6 +942,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
|
|||||||
__scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY, 0);
|
__scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
next_command:
|
||||||
|
scsi_release_buffers(cmd);
|
||||||
|
scsi_next_command(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
|
static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user