forked from luck/tmp_suning_uos_patched
target/iscsi: split iscsit_check_dataout_hdr()
Split iscsit_check_dataout_hdr() into two functions 1. __iscsit_check_dataout_hdr() - This function validates data out hdr. 2. iscsit_check_dataout_hdr() - This function finds iSCSI cmd using iscsit_find_cmd_from_itt_or_dump(), then it calls __iscsit_check_dataout_hdr() to validate iSCSI hdr. This split is required to support Chelsio T6 iSCSI DDP completion feature. T6 adapters reduce number of completions to host by generating single completion for all directly placed(DDP) iSCSI pdus in a sequence, DDP completion contains iSCSI hdr of the last pdu in a sequence. On receiving DDP completion cxgbit driver will first find iSCSI cmd using iscsit_find_cmd_from_itt_or_dump() then updates cmd->write_data_done, cmd->next_burst_len, cmd->data_sn and calls __iscsit_check_dataout_hdr() to validate iSCSI hdr. (Move XRDSL check ahead of itt lookup / dump - nab) Signed-off-by: Varun Prakash <varun@chelsio.com> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
b2c9652eba
commit
9a584bf9bf
|
@ -1431,36 +1431,17 @@ static void iscsit_do_crypto_hash_buf(
|
|||
}
|
||||
|
||||
int
|
||||
iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
|
||||
struct iscsi_cmd **out_cmd)
|
||||
__iscsit_check_dataout_hdr(struct iscsi_conn *conn, void *buf,
|
||||
struct iscsi_cmd *cmd, u32 payload_length,
|
||||
bool *success)
|
||||
{
|
||||
struct iscsi_data *hdr = (struct iscsi_data *)buf;
|
||||
struct iscsi_cmd *cmd = NULL;
|
||||
struct iscsi_data *hdr = buf;
|
||||
struct se_cmd *se_cmd;
|
||||
u32 payload_length = ntoh24(hdr->dlength);
|
||||
int rc;
|
||||
|
||||
if (!payload_length) {
|
||||
pr_warn("DataOUT payload is ZERO, ignoring.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* iSCSI write */
|
||||
atomic_long_add(payload_length, &conn->sess->rx_data_octets);
|
||||
|
||||
if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
|
||||
pr_err("DataSegmentLength: %u is greater than"
|
||||
" MaxXmitDataSegmentLength: %u\n", payload_length,
|
||||
conn->conn_ops->MaxXmitDataSegmentLength);
|
||||
return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
|
||||
buf);
|
||||
}
|
||||
|
||||
cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt,
|
||||
payload_length);
|
||||
if (!cmd)
|
||||
return 0;
|
||||
|
||||
pr_debug("Got DataOut ITT: 0x%08x, TTT: 0x%08x,"
|
||||
" DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n",
|
||||
hdr->itt, hdr->ttt, hdr->datasn, ntohl(hdr->offset),
|
||||
|
@ -1553,10 +1534,44 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
|
|||
return 0;
|
||||
else if (rc == DATAOUT_CANNOT_RECOVER)
|
||||
return -1;
|
||||
|
||||
*out_cmd = cmd;
|
||||
*success = true;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__iscsit_check_dataout_hdr);
|
||||
|
||||
int
|
||||
iscsit_check_dataout_hdr(struct iscsi_conn *conn, void *buf,
|
||||
struct iscsi_cmd **out_cmd)
|
||||
{
|
||||
struct iscsi_data *hdr = buf;
|
||||
struct iscsi_cmd *cmd;
|
||||
u32 payload_length = ntoh24(hdr->dlength);
|
||||
int rc;
|
||||
bool success = false;
|
||||
|
||||
if (!payload_length) {
|
||||
pr_warn_ratelimited("DataOUT payload is ZERO, ignoring.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
|
||||
pr_err_ratelimited("DataSegmentLength: %u is greater than"
|
||||
" MaxXmitDataSegmentLength: %u\n", payload_length,
|
||||
conn->conn_ops->MaxXmitDataSegmentLength);
|
||||
return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, buf);
|
||||
}
|
||||
|
||||
cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt, payload_length);
|
||||
if (!cmd)
|
||||
return 0;
|
||||
|
||||
rc = __iscsit_check_dataout_hdr(conn, buf, cmd, payload_length, &success);
|
||||
|
||||
if (success)
|
||||
*out_cmd = cmd;
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(iscsit_check_dataout_hdr);
|
||||
|
||||
static int
|
||||
|
|
|
@ -417,6 +417,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(
|
|||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(iscsit_find_cmd_from_itt_or_dump);
|
||||
|
||||
struct iscsi_cmd *iscsit_find_cmd_from_ttt(
|
||||
struct iscsi_conn *conn,
|
||||
|
|
|
@ -55,8 +55,12 @@ extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *,
|
|||
extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *);
|
||||
extern int iscsit_process_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *,
|
||||
struct iscsi_scsi_req *);
|
||||
extern int iscsit_check_dataout_hdr(struct iscsi_conn *, unsigned char *,
|
||||
struct iscsi_cmd **);
|
||||
extern int
|
||||
__iscsit_check_dataout_hdr(struct iscsi_conn *, void *,
|
||||
struct iscsi_cmd *, u32, bool *);
|
||||
extern int
|
||||
iscsit_check_dataout_hdr(struct iscsi_conn *conn, void *buf,
|
||||
struct iscsi_cmd **out_cmd);
|
||||
extern int iscsit_check_dataout_payload(struct iscsi_cmd *, struct iscsi_data *,
|
||||
bool);
|
||||
extern int iscsit_setup_nop_out(struct iscsi_conn *, struct iscsi_cmd *,
|
||||
|
@ -125,6 +129,9 @@ extern void iscsit_release_cmd(struct iscsi_cmd *);
|
|||
extern void iscsit_free_cmd(struct iscsi_cmd *, bool);
|
||||
extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *,
|
||||
struct iscsi_conn *, u8);
|
||||
extern struct iscsi_cmd *
|
||||
iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *conn,
|
||||
itt_t init_task_tag, u32 length);
|
||||
|
||||
/*
|
||||
* From iscsi_target_nego.c
|
||||
|
|
Loading…
Reference in New Issue
Block a user