aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/iscsi
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2013-06-14 19:46:16 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-06-25 01:36:29 -0400
commit64534aa79496a3bc4f750a695fe9e978ab46e91d (patch)
tree6e3bf0ab5bb001c541e76bd425742802c8c8c8b1 /drivers/target/iscsi
parent778de368964c5b7e8100cde9f549992d521e9c89 (diff)
iscsi-target: Refactor ISCSI_OP_TEXT RX handling
This patch refactors ISCSI_OP_TEXT handling within iscsi-target in order to handle iscsi_text payloads in a transport specific manner. This includes splitting current iscsit_handle_text_cmd() into iscsit_setup_text_cmd() and iscsit_process_text_cmd() calls, and makes iscsit_handle_text_cmd be only used internally by traditional iscsi socket calls. 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/iscsi')
-rw-r--r--drivers/target/iscsi/iscsi_target.c158
1 files changed, 90 insertions, 68 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index f684627244bf..ae312c5d8a45 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1960,45 +1960,93 @@ attach:
1960EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd); 1960EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd);
1961 1961
1962/* #warning FIXME: Support Text Command parameters besides SendTargets */ 1962/* #warning FIXME: Support Text Command parameters besides SendTargets */
1963static int iscsit_handle_text_cmd( 1963int
1964 struct iscsi_conn *conn, 1964iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1965 unsigned char *buf) 1965 struct iscsi_text *hdr)
1966{ 1966{
1967 char *text_ptr, *text_in; 1967 u32 payload_length = ntoh24(hdr->dlength);
1968 int cmdsn_ret, niov = 0, rx_got, rx_size;
1969 u32 checksum = 0, data_crc = 0, payload_length;
1970 u32 padding = 0, pad_bytes = 0, text_length = 0;
1971 struct iscsi_cmd *cmd;
1972 struct kvec iov[3];
1973 struct iscsi_text *hdr;
1974
1975 hdr = (struct iscsi_text *) buf;
1976 payload_length = ntoh24(hdr->dlength);
1977 1968
1978 if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { 1969 if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
1979 pr_err("Unable to accept text parameter length: %u" 1970 pr_err("Unable to accept text parameter length: %u"
1980 "greater than MaxXmitDataSegmentLength %u.\n", 1971 "greater than MaxXmitDataSegmentLength %u.\n",
1981 payload_length, conn->conn_ops->MaxXmitDataSegmentLength); 1972 payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
1982 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, 1973 return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
1983 buf, conn); 1974 1, 0, (unsigned char *)hdr, cmd);
1984 } 1975 }
1985 1976
1986 pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x," 1977 pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x,"
1987 " ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn, 1978 " ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn,
1988 hdr->exp_statsn, payload_length); 1979 hdr->exp_statsn, payload_length);
1989 1980
1990 rx_size = text_length = payload_length; 1981 cmd->iscsi_opcode = ISCSI_OP_TEXT;
1991 if (text_length) { 1982 cmd->i_state = ISTATE_SEND_TEXTRSP;
1992 text_in = kzalloc(text_length, GFP_KERNEL); 1983 cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
1984 conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
1985 cmd->targ_xfer_tag = 0xFFFFFFFF;
1986 cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
1987 cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
1988 cmd->data_direction = DMA_NONE;
1989
1990 return 0;
1991}
1992EXPORT_SYMBOL(iscsit_setup_text_cmd);
1993
1994int
1995iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1996 struct iscsi_text *hdr)
1997{
1998 int cmdsn_ret;
1999
2000 spin_lock_bh(&conn->cmd_lock);
2001 list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
2002 spin_unlock_bh(&conn->cmd_lock);
2003
2004 iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
2005
2006 if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
2007 cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
2008 if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
2009 return iscsit_add_reject_from_cmd(
2010 ISCSI_REASON_PROTOCOL_ERROR,
2011 1, 0, (unsigned char *)hdr, cmd);
2012 return 0;
2013 }
2014
2015 return iscsit_execute_cmd(cmd, 0);
2016}
2017EXPORT_SYMBOL(iscsit_process_text_cmd);
2018
2019static int
2020iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
2021 unsigned char *buf)
2022{
2023 struct iscsi_text *hdr = (struct iscsi_text *)buf;
2024 char *text_in = NULL;
2025 u32 payload_length = ntoh24(hdr->dlength);
2026 int rx_size, rc;
2027
2028 rc = iscsit_setup_text_cmd(conn, cmd, hdr);
2029 if (rc < 0)
2030 return rc;
2031
2032 rx_size = payload_length;
2033 if (payload_length) {
2034 char *text_ptr;
2035 u32 checksum = 0, data_crc = 0;
2036 u32 padding = 0, pad_bytes = 0;
2037 int niov = 0, rx_got;
2038 struct kvec iov[3];
2039
2040 text_in = kzalloc(payload_length, GFP_KERNEL);
1993 if (!text_in) { 2041 if (!text_in) {
1994 pr_err("Unable to allocate memory for" 2042 pr_err("Unable to allocate memory for"
1995 " incoming text parameters\n"); 2043 " incoming text parameters\n");
1996 return -1; 2044 goto reject;
1997 } 2045 }
1998 2046
1999 memset(iov, 0, 3 * sizeof(struct kvec)); 2047 memset(iov, 0, 3 * sizeof(struct kvec));
2000 iov[niov].iov_base = text_in; 2048 iov[niov].iov_base = text_in;
2001 iov[niov++].iov_len = text_length; 2049 iov[niov++].iov_len = payload_length;
2002 2050
2003 padding = ((-payload_length) & 3); 2051 padding = ((-payload_length) & 3);
2004 if (padding != 0) { 2052 if (padding != 0) {
@@ -2015,14 +2063,12 @@ static int iscsit_handle_text_cmd(
2015 } 2063 }
2016 2064
2017 rx_got = rx_data(conn, &iov[0], niov, rx_size); 2065 rx_got = rx_data(conn, &iov[0], niov, rx_size);
2018 if (rx_got != rx_size) { 2066 if (rx_got != rx_size)
2019 kfree(text_in); 2067 goto reject;
2020 return -1;
2021 }
2022 2068
2023 if (conn->conn_ops->DataDigest) { 2069 if (conn->conn_ops->DataDigest) {
2024 iscsit_do_crypto_hash_buf(&conn->conn_rx_hash, 2070 iscsit_do_crypto_hash_buf(&conn->conn_rx_hash,
2025 text_in, text_length, 2071 text_in, payload_length,
2026 padding, (u8 *)&pad_bytes, 2072 padding, (u8 *)&pad_bytes,
2027 (u8 *)&data_crc); 2073 (u8 *)&data_crc);
2028 2074
@@ -2034,8 +2080,7 @@ static int iscsit_handle_text_cmd(
2034 pr_err("Unable to recover from" 2080 pr_err("Unable to recover from"
2035 " Text Data digest failure while in" 2081 " Text Data digest failure while in"
2036 " ERL=0.\n"); 2082 " ERL=0.\n");
2037 kfree(text_in); 2083 goto reject;
2038 return -1;
2039 } else { 2084 } else {
2040 /* 2085 /*
2041 * Silently drop this PDU and let the 2086 * Silently drop this PDU and let the
@@ -2050,68 +2095,40 @@ static int iscsit_handle_text_cmd(
2050 } else { 2095 } else {
2051 pr_debug("Got CRC32C DataDigest" 2096 pr_debug("Got CRC32C DataDigest"
2052 " 0x%08x for %u bytes of text data.\n", 2097 " 0x%08x for %u bytes of text data.\n",
2053 checksum, text_length); 2098 checksum, payload_length);
2054 } 2099 }
2055 } 2100 }
2056 text_in[text_length - 1] = '\0'; 2101 text_in[payload_length - 1] = '\0';
2057 pr_debug("Successfully read %d bytes of text" 2102 pr_debug("Successfully read %d bytes of text"
2058 " data.\n", text_length); 2103 " data.\n", payload_length);
2059 2104
2060 if (strncmp("SendTargets", text_in, 11) != 0) { 2105 if (strncmp("SendTargets", text_in, 11) != 0) {
2061 pr_err("Received Text Data that is not" 2106 pr_err("Received Text Data that is not"
2062 " SendTargets, cannot continue.\n"); 2107 " SendTargets, cannot continue.\n");
2063 kfree(text_in); 2108 goto reject;
2064 return -1;
2065 } 2109 }
2066 text_ptr = strchr(text_in, '='); 2110 text_ptr = strchr(text_in, '=');
2067 if (!text_ptr) { 2111 if (!text_ptr) {
2068 pr_err("No \"=\" separator found in Text Data," 2112 pr_err("No \"=\" separator found in Text Data,"
2069 " cannot continue.\n"); 2113 " cannot continue.\n");
2070 kfree(text_in); 2114 goto reject;
2071 return -1;
2072 } 2115 }
2073 if (strncmp("=All", text_ptr, 4) != 0) { 2116 if (strncmp("=All", text_ptr, 4) != 0) {
2074 pr_err("Unable to locate All value for" 2117 pr_err("Unable to locate All value for"
2075 " SendTargets key, cannot continue.\n"); 2118 " SendTargets key, cannot continue.\n");
2076 kfree(text_in); 2119 goto reject;
2077 return -1;
2078 } 2120 }
2079/*#warning Support SendTargets=(iSCSI Target Name/Nothing) values. */
2080 kfree(text_in); 2121 kfree(text_in);
2081 } 2122 }
2082 2123
2083 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); 2124 return iscsit_process_text_cmd(conn, cmd, hdr);
2084 if (!cmd)
2085 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
2086 1, buf, conn);
2087
2088 cmd->iscsi_opcode = ISCSI_OP_TEXT;
2089 cmd->i_state = ISTATE_SEND_TEXTRSP;
2090 cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
2091 conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
2092 cmd->targ_xfer_tag = 0xFFFFFFFF;
2093 cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
2094 cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
2095 cmd->data_direction = DMA_NONE;
2096
2097 spin_lock_bh(&conn->cmd_lock);
2098 list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
2099 spin_unlock_bh(&conn->cmd_lock);
2100
2101 iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
2102 2125
2103 if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { 2126reject:
2104 cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); 2127 kfree(text_in);
2105 if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) 2128 return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
2106 return iscsit_add_reject_from_cmd( 2129 0, 0, buf, cmd);
2107 ISCSI_REASON_PROTOCOL_ERROR,
2108 1, 0, buf, cmd);
2109
2110 return 0;
2111 }
2112
2113 return iscsit_execute_cmd(cmd, 0);
2114} 2130}
2131EXPORT_SYMBOL(iscsit_handle_text_cmd);
2115 2132
2116int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn) 2133int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2117{ 2134{
@@ -3947,7 +3964,12 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
3947 ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf); 3964 ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf);
3948 break; 3965 break;
3949 case ISCSI_OP_TEXT: 3966 case ISCSI_OP_TEXT:
3950 ret = iscsit_handle_text_cmd(conn, buf); 3967 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
3968 if (!cmd)
3969 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
3970 1, buf, conn);
3971
3972 ret = iscsit_handle_text_cmd(conn, cmd, buf);
3951 break; 3973 break;
3952 case ISCSI_OP_LOGOUT: 3974 case ISCSI_OP_LOGOUT:
3953 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); 3975 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);