mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-14 09:11:27 +00:00
Fixed processing of REQUEST SENSE and INQUIRY commands for not existing LUNs
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1462 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -207,7 +207,6 @@ unlock_cont:
|
||||
req_cmnd_release(cmnd);
|
||||
goto out;
|
||||
}
|
||||
EXTRACHECKS_BUG_ON(scst_cmd_get_status(cmnd->scst_cmd) == 0);
|
||||
|
||||
status = SCST_PREPROCESS_STATUS_ERROR_SENSE_SET;
|
||||
} else
|
||||
@@ -3080,9 +3079,6 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
|
||||
|
||||
TRACE_DBG("Prelim completed req %p", req);
|
||||
|
||||
/* To make sure we didn't miss anything above */
|
||||
sBUG_ON(status == 0);
|
||||
|
||||
/*
|
||||
* We could preliminary have finished req before we
|
||||
* knew its device, so check if we return correct sense
|
||||
|
||||
@@ -665,12 +665,130 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL(scst_set_cmd_error_status);
|
||||
|
||||
static int scst_set_lun_not_supported_request_sense(struct scst_cmd *cmd,
|
||||
int key, int asc, int ascq)
|
||||
{
|
||||
int res;
|
||||
int sense_len;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (cmd->status != 0) {
|
||||
TRACE_MGMT_DBG("cmd %p already has status %x set", cmd,
|
||||
cmd->status);
|
||||
res = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((cmd->sg != NULL) && SCST_SENSE_VALID(sg_virt(cmd->sg))) {
|
||||
TRACE_MGMT_DBG("cmd %p already has sense set", cmd);
|
||||
res = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cmd->sg == NULL) {
|
||||
if (cmd->bufflen == 0)
|
||||
cmd->bufflen = cmd->cdb[4];
|
||||
|
||||
cmd->sg = scst_alloc(cmd->bufflen, GFP_ATOMIC, &cmd->sg_cnt);
|
||||
if (cmd->sg == NULL) {
|
||||
PRINT_CRIT_ERROR("Unable to alloc sg"
|
||||
"(sense %x/%x/%x)", key, asc, ascq);
|
||||
res = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_MEM("sg %p alloced for sense for cmd %p (cnt %d, "
|
||||
"len %d)", cmd->sg, cmd, cmd->sg_cnt, cmd->bufflen);
|
||||
|
||||
sense_len = scst_set_sense(sg_virt(cmd->sg),
|
||||
cmd->bufflen, cmd->cdb[1] & 1, key, asc, ascq);
|
||||
scst_set_resp_data_len(cmd, sense_len);
|
||||
|
||||
TRACE_BUFFER("Sense set", sg_virt(cmd->sg), sense_len);
|
||||
|
||||
res = 0;
|
||||
cmd->completed = 1;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int scst_set_lun_not_supported_inquiry(struct scst_cmd *cmd)
|
||||
{
|
||||
int res;
|
||||
uint8_t *buf;
|
||||
int len;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (cmd->status != 0) {
|
||||
TRACE_MGMT_DBG("cmd %p already has status %x set", cmd,
|
||||
cmd->status);
|
||||
res = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cmd->sg == NULL) {
|
||||
if (cmd->bufflen == 0)
|
||||
cmd->bufflen = min_t(int, 36, (cmd->cdb[3] << 8) | cmd->cdb[4]);
|
||||
|
||||
cmd->sg = scst_alloc(cmd->bufflen, GFP_ATOMIC, &cmd->sg_cnt);
|
||||
if (cmd->sg == NULL) {
|
||||
PRINT_CRIT_ERROR("%s", "Unable to alloc sg for INQUIRY "
|
||||
"for not supported LUN");
|
||||
res = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_MEM("sg %p alloced INQUIRY for cmd %p (cnt %d, len %d)",
|
||||
cmd->sg, cmd, cmd->sg_cnt, cmd->bufflen);
|
||||
|
||||
buf = sg_virt(cmd->sg);
|
||||
len = min_t(int, 36, cmd->bufflen);
|
||||
|
||||
memset(buf, 0, len);
|
||||
buf[0] = 0x7F; /* Peripheral qualifier 011b, Peripheral device type 1Fh */
|
||||
|
||||
TRACE_BUFFER("INQUIRY for not supported LUN set", buf, len);
|
||||
|
||||
res = 0;
|
||||
cmd->completed = 1;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
int scst_set_cmd_error(struct scst_cmd *cmd, int key, int asc, int ascq)
|
||||
{
|
||||
int res;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
/*
|
||||
* We need for LOGICAL UNIT NOT SUPPORTED special handling for
|
||||
* REQUEST SENSE and INQUIRY.
|
||||
*/
|
||||
if ((key == ILLEGAL_REQUEST) && (asc == 0x25) && (ascq == 0)) {
|
||||
if (cmd->cdb[0] == REQUEST_SENSE)
|
||||
res = scst_set_lun_not_supported_request_sense(cmd,
|
||||
key, asc, ascq);
|
||||
else if (cmd->cdb[0] == INQUIRY)
|
||||
res = scst_set_lun_not_supported_inquiry(cmd);
|
||||
else
|
||||
goto do_sense;
|
||||
|
||||
if (res > 0)
|
||||
goto do_sense;
|
||||
else
|
||||
goto out;
|
||||
}
|
||||
|
||||
do_sense:
|
||||
res = scst_set_cmd_error_status(cmd, SAM_STAT_CHECK_CONDITION);
|
||||
if (res != 0)
|
||||
goto out;
|
||||
@@ -3465,21 +3583,22 @@ static void scst_release_space(struct scst_cmd *cmd)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (cmd->sgv == NULL)
|
||||
goto out;
|
||||
if (cmd->sgv == NULL) {
|
||||
if ((cmd->sg != NULL) &&
|
||||
!(cmd->tgt_data_buf_alloced || cmd->dh_data_buf_alloced)) {
|
||||
TRACE_MEM("Freeing sg %p for cmd %p (cnt %d)", cmd->sg,
|
||||
cmd, cmd->sg_cnt);
|
||||
scst_free(cmd->sg, cmd->sg_cnt);
|
||||
goto out_zero;
|
||||
} else
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cmd->tgt_data_buf_alloced || cmd->dh_data_buf_alloced) {
|
||||
TRACE_MEM("%s", "*data_buf_alloced set, returning");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sgv_pool_free(cmd->sgv, &cmd->dev->dev_mem_lim);
|
||||
cmd->sgv = NULL;
|
||||
cmd->sg_cnt = 0;
|
||||
cmd->sg = NULL;
|
||||
cmd->bufflen = 0;
|
||||
cmd->data_len = 0;
|
||||
|
||||
if (cmd->in_sgv != NULL) {
|
||||
sgv_pool_free(cmd->in_sgv, &cmd->dev->dev_mem_lim);
|
||||
cmd->in_sgv = NULL;
|
||||
@@ -3488,6 +3607,15 @@ static void scst_release_space(struct scst_cmd *cmd)
|
||||
cmd->in_bufflen = 0;
|
||||
}
|
||||
|
||||
sgv_pool_free(cmd->sgv, &cmd->dev->dev_mem_lim);
|
||||
|
||||
out_zero:
|
||||
cmd->sgv = NULL;
|
||||
cmd->sg_cnt = 0;
|
||||
cmd->sg = NULL;
|
||||
cmd->bufflen = 0;
|
||||
cmd->data_len = 0;
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user