diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-06-20 07:43:11 +0200 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-07-04 04:43:23 +0200 |
commit | 9864ca9d27f75d2716d09dd02b3d62d241194576 (patch) | |
tree | f8b3232edaa52a337e1d83a7862d8d559a7bb559 /drivers/target | |
parent | iscsi-target: Allow ->MaxXmitDataSegmentLength assignment for iser discovery (diff) | |
download | linux-9864ca9d27f75d2716d09dd02b3d62d241194576.tar.xz linux-9864ca9d27f75d2716d09dd02b3d62d241194576.zip |
iscsi-target: Move sendtargets parsing into iscsit_process_text_cmd
This patch moves ISCSI_OP_TEXT PDU buffer sanity checks to
iscsit_process_text_cmd() code, so that it can be shared
with iser-target code.
It adds IFC_SENDTARGETS_ALL + iscsi_cmd->text_in_ptr in order
to save text payload for ISCSI_OP_TEXT_RSP, and updates
iscsit_release_cmd() to assigned memory.
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 51 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 3 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 1 |
3 files changed, 35 insertions, 20 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 1f79a168f1c1..30ca1887516b 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1995,8 +1995,32 @@ int iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, struct iscsi_text *hdr) { + unsigned char *text_in = cmd->text_in_ptr, *text_ptr; int cmdsn_ret; + if (!text_in) { + pr_err("Unable to locate text_in buffer for sendtargets" + " discovery\n"); + goto reject; + } + if (strncmp("SendTargets", text_in, 11) != 0) { + pr_err("Received Text Data that is not" + " SendTargets, cannot continue.\n"); + goto reject; + } + text_ptr = strchr(text_in, '='); + if (!text_ptr) { + pr_err("No \"=\" separator found in Text Data," + " cannot continue.\n"); + goto reject; + } + if (!strncmp("=All", text_ptr, 4)) { + cmd->cmd_flags |= IFC_SENDTARGETS_ALL; + } else { + pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr); + goto reject; + } + spin_lock_bh(&conn->cmd_lock); list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); @@ -2013,6 +2037,10 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, } return iscsit_execute_cmd(cmd, 0); + +reject: + return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, + 0, 0, (unsigned char *)hdr, cmd); } EXPORT_SYMBOL(iscsit_process_text_cmd); @@ -2031,7 +2059,6 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, rx_size = payload_length; if (payload_length) { - char *text_ptr; u32 checksum = 0, data_crc = 0; u32 padding = 0, pad_bytes = 0; int niov = 0, rx_got; @@ -2043,6 +2070,7 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, " incoming text parameters\n"); goto reject; } + cmd->text_in_ptr = text_in; memset(iov, 0, 3 * sizeof(struct kvec)); iov[niov].iov_base = text_in; @@ -2101,30 +2129,13 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, text_in[payload_length - 1] = '\0'; pr_debug("Successfully read %d bytes of text" " data.\n", payload_length); - - if (strncmp("SendTargets", text_in, 11) != 0) { - pr_err("Received Text Data that is not" - " SendTargets, cannot continue.\n"); - goto reject; - } - text_ptr = strchr(text_in, '='); - if (!text_ptr) { - pr_err("No \"=\" separator found in Text Data," - " cannot continue.\n"); - goto reject; - } - if (strncmp("=All", text_ptr, 4) != 0) { - pr_err("Unable to locate All value for" - " SendTargets key, cannot continue.\n"); - goto reject; - } - kfree(text_in); } return iscsit_process_text_cmd(conn, cmd, hdr); reject: - kfree(text_in); + kfree(cmd->text_in_ptr); + cmd->text_in_ptr = NULL; return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, 0, 0, buf, cmd); } diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 60ec4b92be03..ad46e73dab4c 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -133,6 +133,7 @@ enum cmd_flags_table { ICF_ATTACHED_TO_RQUEUE = 0x00000040, ICF_OOO_CMDSN = 0x00000080, ICF_REJECT_FAIL_CONN = 0x00000100, + IFC_SENDTARGETS_ALL = 0x00000200, }; /* struct iscsi_cmd->i_state */ @@ -427,6 +428,8 @@ struct iscsi_cmd { u32 tx_size; /* Buffer used for various purposes */ void *buf_ptr; + /* Used by SendTargets=[iqn.,eui.] discovery */ + void *text_in_ptr; /* See include/linux/dma-mapping.h */ enum dma_data_direction data_direction; /* iSCSI PDU Header + CRC */ diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 08a3bacef0c5..fe712d6cc478 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -681,6 +681,7 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) kfree(cmd->seq_list); kfree(cmd->tmr_req); kfree(cmd->iov_data); + kfree(cmd->text_in_ptr); kmem_cache_free(lio_cmd_cache, cmd); } |