iscsi: Add an API to return DIF context of SCSI command
Ths patch adds an API spdk_iscsi_get_dif_ctx(). When opcode of BHS is SCSI command, spdk_iscsi_get_dif_ctx() extracts CDB and LUN ID from BHS. When opcode of BHS is Data Out or Data In, spdk_iscsi_get_dif_ctx() extracts TTT and get R2T task corresponding to TTT, and gets CDB and LUN ID from the task. Then spdk_iscsi_get_dif_ctx() gets LUN by using LUN ID and calls spdk_scsi_lun_get_dif_ctx(). Additionally spdk_iscsi_get_dif_ctx() checks the state of the connection and the type of the session is valid before starting decode operation because contents of PDU is not reliable when the state of the connection is invalid. The necessity of the check was found by the Calsoft test tool. Checks and test cases are not matched yet but copying existing checks from spdk_iscsi_conn_execute, spdk_iscsi_op_scsi, and spdk_iscsi_op_data will be enough. The check added for Data Out is not necessary for Data In but it will not be harmful for Data In. Change-Id: Iba09e0ac3e760aa1c5b582a120596c49b9e9d51e Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/446231 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ziye Yang <ziye.yang@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
8697bce7af
commit
b8a51ff5b8
@ -4559,6 +4559,76 @@ spdk_iscsi_execute(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
spdk_iscsi_get_dif_ctx(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu,
|
||||
struct spdk_dif_ctx *dif_ctx)
|
||||
{
|
||||
struct iscsi_bhs *bhs;
|
||||
uint32_t offset = 0;
|
||||
uint8_t *cdb = NULL;
|
||||
uint64_t lun;
|
||||
int lun_id = 0;
|
||||
struct spdk_scsi_lun *lun_dev;
|
||||
|
||||
/* connection is not in full feature phase but non-login opcode
|
||||
* was received.
|
||||
*/
|
||||
if ((!conn->full_feature && conn->state == ISCSI_CONN_STATE_RUNNING) ||
|
||||
conn->state == ISCSI_CONN_STATE_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* SCSI Command is allowed only in normal session */
|
||||
if (conn->sess == NULL ||
|
||||
conn->sess->session_type != SESSION_TYPE_NORMAL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bhs = &pdu->bhs;
|
||||
|
||||
switch (bhs->opcode) {
|
||||
case ISCSI_OP_SCSI: {
|
||||
struct iscsi_bhs_scsi_req *sbhs;
|
||||
|
||||
sbhs = (struct iscsi_bhs_scsi_req *)bhs;
|
||||
offset = 0;
|
||||
cdb = sbhs->cdb;
|
||||
lun = from_be64(&sbhs->lun);
|
||||
lun_id = spdk_islun2lun(lun);
|
||||
break;
|
||||
}
|
||||
case ISCSI_OP_SCSI_DATAIN:
|
||||
case ISCSI_OP_SCSI_DATAOUT: {
|
||||
/* Location of Buffer Offset and TTT in PDU are same
|
||||
* for Data In and Out, so unify them.
|
||||
*/
|
||||
struct iscsi_bhs_data_in *dbhs;
|
||||
struct spdk_iscsi_task *task;
|
||||
int transfer_tag;
|
||||
|
||||
dbhs = (struct iscsi_bhs_data_in *)bhs;
|
||||
offset = from_be32(&dbhs->buffer_offset);
|
||||
transfer_tag = from_be32(&dbhs->ttt);
|
||||
task = spdk_get_transfer_task(conn, transfer_tag);
|
||||
if (task == NULL) {
|
||||
return false;
|
||||
}
|
||||
cdb = task->scsi.cdb;
|
||||
lun_id = task->lun_id;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
lun_dev = spdk_scsi_dev_get_lun(conn->dev, lun_id);
|
||||
if (lun_dev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return spdk_scsi_lun_get_dif_ctx(lun_dev, cdb, offset, dif_ctx);
|
||||
}
|
||||
|
||||
void spdk_free_sess(struct spdk_iscsi_sess *sess)
|
||||
{
|
||||
if (sess == NULL) {
|
||||
|
@ -408,6 +408,8 @@ int spdk_iscsi_execute(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
int spdk_iscsi_build_iovs(struct spdk_iscsi_conn *conn, struct iovec *iovs, int num_iovs,
|
||||
struct spdk_iscsi_pdu *pdu, uint32_t *mapped_length);
|
||||
int spdk_iscsi_read_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu **_pdu);
|
||||
bool spdk_iscsi_get_dif_ctx(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu,
|
||||
struct spdk_dif_ctx *dif_ctx);
|
||||
void spdk_iscsi_task_mgmt_response(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_iscsi_task *task);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user