diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-06-20 01:43:11 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-07-03 22:43:23 -0400 |
commit | 9864ca9d27f75d2716d09dd02b3d62d241194576 (patch) | |
tree | f8b3232edaa52a337e1d83a7862d8d559a7bb559 /drivers/target | |
parent | dbf738a1a6f93c634e368e74a1943acb93696b22 (diff) |
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 | |||
1995 | iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | 1995 | iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, |
1996 | struct iscsi_text *hdr) | 1996 | struct iscsi_text *hdr) |
1997 | { | 1997 | { |
1998 | unsigned char *text_in = cmd->text_in_ptr, *text_ptr; | ||
1998 | int cmdsn_ret; | 1999 | int cmdsn_ret; |
1999 | 2000 | ||
2001 | if (!text_in) { | ||
2002 | pr_err("Unable to locate text_in buffer for sendtargets" | ||
2003 | " discovery\n"); | ||
2004 | goto reject; | ||
2005 | } | ||
2006 | if (strncmp("SendTargets", text_in, 11) != 0) { | ||
2007 | pr_err("Received Text Data that is not" | ||
2008 | " SendTargets, cannot continue.\n"); | ||
2009 | goto reject; | ||
2010 | } | ||
2011 | text_ptr = strchr(text_in, '='); | ||
2012 | if (!text_ptr) { | ||
2013 | pr_err("No \"=\" separator found in Text Data," | ||
2014 | " cannot continue.\n"); | ||
2015 | goto reject; | ||
2016 | } | ||
2017 | if (!strncmp("=All", text_ptr, 4)) { | ||
2018 | cmd->cmd_flags |= IFC_SENDTARGETS_ALL; | ||
2019 | } else { | ||
2020 | pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr); | ||
2021 | goto reject; | ||
2022 | } | ||
2023 | |||
2000 | spin_lock_bh(&conn->cmd_lock); | 2024 | spin_lock_bh(&conn->cmd_lock); |
2001 | list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); | 2025 | list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); |
2002 | spin_unlock_bh(&conn->cmd_lock); | 2026 | spin_unlock_bh(&conn->cmd_lock); |
@@ -2013,6 +2037,10 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2013 | } | 2037 | } |
2014 | 2038 | ||
2015 | return iscsit_execute_cmd(cmd, 0); | 2039 | return iscsit_execute_cmd(cmd, 0); |
2040 | |||
2041 | reject: | ||
2042 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | ||
2043 | 0, 0, (unsigned char *)hdr, cmd); | ||
2016 | } | 2044 | } |
2017 | EXPORT_SYMBOL(iscsit_process_text_cmd); | 2045 | EXPORT_SYMBOL(iscsit_process_text_cmd); |
2018 | 2046 | ||
@@ -2031,7 +2059,6 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2031 | 2059 | ||
2032 | rx_size = payload_length; | 2060 | rx_size = payload_length; |
2033 | if (payload_length) { | 2061 | if (payload_length) { |
2034 | char *text_ptr; | ||
2035 | u32 checksum = 0, data_crc = 0; | 2062 | u32 checksum = 0, data_crc = 0; |
2036 | u32 padding = 0, pad_bytes = 0; | 2063 | u32 padding = 0, pad_bytes = 0; |
2037 | int niov = 0, rx_got; | 2064 | int niov = 0, rx_got; |
@@ -2043,6 +2070,7 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2043 | " incoming text parameters\n"); | 2070 | " incoming text parameters\n"); |
2044 | goto reject; | 2071 | goto reject; |
2045 | } | 2072 | } |
2073 | cmd->text_in_ptr = text_in; | ||
2046 | 2074 | ||
2047 | memset(iov, 0, 3 * sizeof(struct kvec)); | 2075 | memset(iov, 0, 3 * sizeof(struct kvec)); |
2048 | iov[niov].iov_base = text_in; | 2076 | iov[niov].iov_base = text_in; |
@@ -2101,30 +2129,13 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2101 | text_in[payload_length - 1] = '\0'; | 2129 | text_in[payload_length - 1] = '\0'; |
2102 | pr_debug("Successfully read %d bytes of text" | 2130 | pr_debug("Successfully read %d bytes of text" |
2103 | " data.\n", payload_length); | 2131 | " data.\n", payload_length); |
2104 | |||
2105 | if (strncmp("SendTargets", text_in, 11) != 0) { | ||
2106 | pr_err("Received Text Data that is not" | ||
2107 | " SendTargets, cannot continue.\n"); | ||
2108 | goto reject; | ||
2109 | } | ||
2110 | text_ptr = strchr(text_in, '='); | ||
2111 | if (!text_ptr) { | ||
2112 | pr_err("No \"=\" separator found in Text Data," | ||
2113 | " cannot continue.\n"); | ||
2114 | goto reject; | ||
2115 | } | ||
2116 | if (strncmp("=All", text_ptr, 4) != 0) { | ||
2117 | pr_err("Unable to locate All value for" | ||
2118 | " SendTargets key, cannot continue.\n"); | ||
2119 | goto reject; | ||
2120 | } | ||
2121 | kfree(text_in); | ||
2122 | } | 2132 | } |
2123 | 2133 | ||
2124 | return iscsit_process_text_cmd(conn, cmd, hdr); | 2134 | return iscsit_process_text_cmd(conn, cmd, hdr); |
2125 | 2135 | ||
2126 | reject: | 2136 | reject: |
2127 | kfree(text_in); | 2137 | kfree(cmd->text_in_ptr); |
2138 | cmd->text_in_ptr = NULL; | ||
2128 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 2139 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, |
2129 | 0, 0, buf, cmd); | 2140 | 0, 0, buf, cmd); |
2130 | } | 2141 | } |
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 { | |||
133 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, | 133 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, |
134 | ICF_OOO_CMDSN = 0x00000080, | 134 | ICF_OOO_CMDSN = 0x00000080, |
135 | ICF_REJECT_FAIL_CONN = 0x00000100, | 135 | ICF_REJECT_FAIL_CONN = 0x00000100, |
136 | IFC_SENDTARGETS_ALL = 0x00000200, | ||
136 | }; | 137 | }; |
137 | 138 | ||
138 | /* struct iscsi_cmd->i_state */ | 139 | /* struct iscsi_cmd->i_state */ |
@@ -427,6 +428,8 @@ struct iscsi_cmd { | |||
427 | u32 tx_size; | 428 | u32 tx_size; |
428 | /* Buffer used for various purposes */ | 429 | /* Buffer used for various purposes */ |
429 | void *buf_ptr; | 430 | void *buf_ptr; |
431 | /* Used by SendTargets=[iqn.,eui.] discovery */ | ||
432 | void *text_in_ptr; | ||
430 | /* See include/linux/dma-mapping.h */ | 433 | /* See include/linux/dma-mapping.h */ |
431 | enum dma_data_direction data_direction; | 434 | enum dma_data_direction data_direction; |
432 | /* iSCSI PDU Header + CRC */ | 435 | /* 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) | |||
681 | kfree(cmd->seq_list); | 681 | kfree(cmd->seq_list); |
682 | kfree(cmd->tmr_req); | 682 | kfree(cmd->tmr_req); |
683 | kfree(cmd->iov_data); | 683 | kfree(cmd->iov_data); |
684 | kfree(cmd->text_in_ptr); | ||
684 | 685 | ||
685 | kmem_cache_free(lio_cmd_cache, cmd); | 686 | kmem_cache_free(lio_cmd_cache, cmd); |
686 | } | 687 | } |