Custom parse improvements

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3281 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2011-03-15 13:09:13 +00:00
parent 519d556580
commit 5cd8982545
5 changed files with 36 additions and 7 deletions

View File

@@ -850,6 +850,7 @@ struct scst_user_scsi_cmd_reply_parse
uint32_t op_flags;
int32_t data_len;
int32_t bufflen;
int32_t out_bufflen;
},
where:
@@ -857,7 +858,7 @@ where:
- queue_type - SCSI task attribute (queue type). NOTE! In current
implementation setting changing this field from the provided value
affects commands execution only when then produced by iSCSI-SCST
target. With al other target drivers, this field is ignored. This is
target. With all other target drivers, this field is ignored. This is
because for them commands queueing is set before parse() called.
- data_direction - command's data flow direction, one of SCST_DATA_*
@@ -866,11 +867,17 @@ where:
- cdb_len - length of CDB
- op_flags - commands flags, one or more scst_cdb_flags bits, see above.
At least SCST_INFO_VALID must be set for correct processing.
SCST_IMPLICIT_HQ not implemented (yet) for single stage init target
drivers (all, except iSCSI), because custom parse can reorder
commands due to multithreaded processing.
- data_len - command's data length
- bufflen - command's buffer length
- out_bufflen - command's out buffer length (for bidirectional commands)
struct scst_user_scsi_cmd_reply_alloc_mem
{

View File

@@ -227,6 +227,7 @@ struct scst_user_scsi_cmd_reply_parse {
uint32_t op_flags;
int32_t data_len;
int32_t bufflen;
int32_t out_bufflen;
};
struct {
uint8_t sense_len;

View File

@@ -1272,12 +1272,16 @@ static int dev_user_process_reply_parse(struct scst_user_cmd *ucmd,
(preply->bufflen == 0)))
goto out_inval;
if (unlikely((preply->bufflen < 0) || (preply->data_len < 0)))
if (unlikely((preply->bufflen < 0) || (preply->out_bufflen < 0) ||
(preply->data_len < 0)))
goto out_inval;
if (unlikely(preply->cdb_len > cmd->cdb_len))
goto out_inval;
if (!(preply->op_flags & SCST_INFO_VALID))
goto out_inval;
TRACE_DBG("ucmd %p, queue_type %x, data_direction, %x, bufflen %d, "
"data_len %d, pbuf %llx, cdb_len %d, op_flags %x", ucmd,
preply->queue_type, preply->data_direction, preply->bufflen,
@@ -1287,11 +1291,11 @@ static int dev_user_process_reply_parse(struct scst_user_cmd *ucmd,
cmd->queue_type = preply->queue_type;
cmd->data_direction = preply->data_direction;
cmd->bufflen = preply->bufflen;
cmd->out_bufflen = preply->out_bufflen;
cmd->data_len = preply->data_len;
if (preply->cdb_len > 0)
cmd->cdb_len = preply->cdb_len;
if (preply->op_flags & SCST_INFO_VALID)
cmd->op_flags = preply->op_flags;
cmd->op_flags = preply->op_flags;
out_process:
scst_post_parse(cmd);

View File

@@ -3845,8 +3845,15 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
if (unlikely(failure))
goto out_busy;
if (unlikely(scst_pre_parse(cmd) != 0))
goto out;
/*
* SCST_IMPLICIT_HQ for unknown commands not implemented for
* case when set_sn_on_restart_cmd not set, because custom parse
* can reorder commands due to multithreaded processing. To
* implement it we need to implement all unknown commands as
* ORDERED in the beginning and post parse reprocess of
* queue_type to change it if needed. ToDo.
*/
scst_pre_parse(cmd);
if (!cmd->set_sn_on_restart_cmd)
scst_cmd_set_sn(cmd);

View File

@@ -192,8 +192,18 @@ static int do_parse(struct vdisk_cmd *vcmd)
reply->data_direction = cmd->expected_data_direction;
reply->data_len = cmd->expected_transfer_len;
reply->bufflen = cmd->expected_transfer_len;
reply->out_bufflen = cmd->expected_out_transfer_len;
reply->cdb_len = cmd->cdb_len;
reply->op_flags = reply->op_flags;
if (cmd->op_flags & SCST_INFO_VALID)
reply->op_flags = cmd->op_flags;
else {
TRACE_DBG_SPECIAL("Extra parse (op %x)", cmd->cdb[0]);
if (reply->data_direction & SCST_DATA_WRITE)
reply->op_flags |= SCST_WRITE_MEDIUM;
reply->op_flags |= SCST_INFO_VALID;
}
out:
TRACE_EXIT_RES(res);