mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-21 14:46:23 +00:00
scst_lib: Fix SCSI pass-through error handling
Some but not all SCSI LLD drivers set req->errors. Some SCSI LLD drivers set req->errors to a negative Unix error code and others assign the result of make_status_bytes() to req->errors. The SCSI core finishes failed pass-through requests by calling blk_finish_request(). That function calls req->end_io() without setting req->errors. Hence check both the error argument and req->errors before calling sioc->done(). Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
This commit is contained in:
@@ -355,7 +355,9 @@ static void disk_cmd_done(void *data, char *sense, int result, int resid)
|
||||
TRACE_DBG("work %p, cmd %p, left %d, result %d, sense %p, resid %d",
|
||||
work, work->cmd, work->left, result, sense, resid);
|
||||
|
||||
if (result == SAM_STAT_GOOD)
|
||||
WARN_ON_ONCE(IS_ERR_VALUE(result));
|
||||
|
||||
if (status_byte(result) == GOOD)
|
||||
goto out_complete;
|
||||
|
||||
work->result = result;
|
||||
|
||||
+9
-3
@@ -6740,8 +6740,10 @@ out:
|
||||
static void scsi_end_async(struct request *req, int error)
|
||||
{
|
||||
struct scsi_io_context *sioc = req->end_io_data;
|
||||
int errors;
|
||||
|
||||
TRACE_DBG("sioc %p, cmd %p", sioc, sioc->data);
|
||||
TRACE_DBG("sioc %p, cmd %p, error %d / %d", sioc, sioc->data, error,
|
||||
req->errors);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
|
||||
lockdep_assert_held(req->q->queue_lock);
|
||||
@@ -6750,11 +6752,15 @@ static void scsi_end_async(struct request *req, int error)
|
||||
lockdep_assert_held(req->q->queue_lock);
|
||||
#endif
|
||||
|
||||
errors = req->errors && !IS_ERR_VALUE(req->errors) ? req->errors :
|
||||
IS_ERR_VALUE(req->errors) || error ?
|
||||
SAM_STAT_CHECK_CONDITION : 0;
|
||||
|
||||
if (sioc->done)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30)
|
||||
sioc->done(sioc->data, sioc->sense, req->errors, req->data_len);
|
||||
sioc->done(sioc->data, sioc->sense, errors, req->data_len);
|
||||
#else
|
||||
sioc->done(sioc->data, sioc->sense, req->errors, req->resid_len);
|
||||
sioc->done(sioc->data, sioc->sense, errors, req->resid_len);
|
||||
#endif
|
||||
|
||||
kmem_cache_free(scsi_io_context_cache, sioc);
|
||||
|
||||
@@ -1724,6 +1724,8 @@ static void scst_do_cmd_done(struct scst_cmd *cmd, int result,
|
||||
|
||||
scst_set_exec_time(cmd);
|
||||
|
||||
WARN_ON_ONCE(IS_ERR_VALUE(result));
|
||||
|
||||
cmd->status = result & 0xff;
|
||||
cmd->msg_status = msg_byte(result);
|
||||
cmd->host_status = host_byte(result);
|
||||
|
||||
Reference in New Issue
Block a user