iscsi-target: Refactor ISCSI_OP_TEXT_RSP TX handling
authorNicholas Bellinger <nab@linux-iscsi.org>
Sat, 15 Jun 2013 01:49:55 +0000 (18:49 -0700)
committerNicholas Bellinger <nab@linux-iscsi.org>
Wed, 26 Jun 2013 07:33:32 +0000 (00:33 -0700)
This patch refactoring existing iscsit_send_text_rsp() in order
to handle iscsi_text_rsp payloads in a transport specific manner.

This includes the addition of iscsit_build_text_rsp() to build
the response payload and initialize ISCSI_OP_TEXT_RSP.

v2: Make iscsit_build_text_rsp() determine extra padding bytes, and
    drop legacy padding calculation for traditional iSCSI text
    responses within iscsit_send_text_rsp()

Reported-by: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/iscsi/iscsi_target.c
include/target/iscsi/iscsi_transport.h

index ae312c5..1f79a16 100644 (file)
@@ -3461,52 +3461,62 @@ eob:
        return payload_len;
 }
 
-/*
- *     FIXME: Add support for F_BIT and C_BIT when the length is longer than
- *     MaxRecvDataSegmentLength.
- */
-static int iscsit_send_text_rsp(
-       struct iscsi_cmd *cmd,
-       struct iscsi_conn *conn)
+int
+iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
+                     struct iscsi_text_rsp *hdr)
 {
-       struct iscsi_text_rsp *hdr;
-       struct kvec *iov;
-       u32 padding = 0, tx_size = 0;
-       int text_length, iov_count = 0;
+       int text_length, padding;
 
        text_length = iscsit_build_sendtargets_response(cmd);
        if (text_length < 0)
                return text_length;
 
+       hdr->opcode = ISCSI_OP_TEXT_RSP;
+       hdr->flags |= ISCSI_FLAG_CMD_FINAL;
        padding = ((-text_length) & 3);
-       if (padding != 0) {
-               memset(cmd->buf_ptr + text_length, 0, padding);
-               pr_debug("Attaching %u additional bytes for"
-                       " padding.\n", padding);
-       }
-
-       hdr                     = (struct iscsi_text_rsp *) cmd->pdu;
-       memset(hdr, 0, ISCSI_HDR_LEN);
-       hdr->opcode             = ISCSI_OP_TEXT_RSP;
-       hdr->flags              |= ISCSI_FLAG_CMD_FINAL;
        hton24(hdr->dlength, text_length);
-       hdr->itt                = cmd->init_task_tag;
-       hdr->ttt                = cpu_to_be32(cmd->targ_xfer_tag);
-       cmd->stat_sn            = conn->stat_sn++;
-       hdr->statsn             = cpu_to_be32(cmd->stat_sn);
+       hdr->itt = cmd->init_task_tag;
+       hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
+       cmd->stat_sn = conn->stat_sn++;
+       hdr->statsn = cpu_to_be32(cmd->stat_sn);
 
        iscsit_increment_maxcmdsn(cmd, conn->sess);
-       hdr->exp_cmdsn          = cpu_to_be32(conn->sess->exp_cmd_sn);
-       hdr->max_cmdsn          = cpu_to_be32(conn->sess->max_cmd_sn);
+       hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
+       hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
 
-       iov = &cmd->iov_misc[0];
+       pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x,"
+               " Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn,
+               text_length, conn->cid);
+
+       return text_length + padding;
+}
+EXPORT_SYMBOL(iscsit_build_text_rsp);
 
+/*
+ *     FIXME: Add support for F_BIT and C_BIT when the length is longer than
+ *     MaxRecvDataSegmentLength.
+ */
+static int iscsit_send_text_rsp(
+       struct iscsi_cmd *cmd,
+       struct iscsi_conn *conn)
+{
+       struct iscsi_text_rsp *hdr = (struct iscsi_text_rsp *)cmd->pdu;
+       struct kvec *iov;
+       u32 tx_size = 0;
+       int text_length, iov_count = 0, rc;
+
+       rc = iscsit_build_text_rsp(cmd, conn, hdr);
+       if (rc < 0)
+               return rc;
+
+       text_length = rc;
+       iov = &cmd->iov_misc[0];
        iov[iov_count].iov_base = cmd->pdu;
        iov[iov_count++].iov_len = ISCSI_HDR_LEN;
        iov[iov_count].iov_base = cmd->buf_ptr;
-       iov[iov_count++].iov_len = text_length + padding;
+       iov[iov_count++].iov_len = text_length;
 
-       tx_size += (ISCSI_HDR_LEN + text_length + padding);
+       tx_size += (ISCSI_HDR_LEN + text_length);
 
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
@@ -3522,7 +3532,7 @@ static int iscsit_send_text_rsp(
 
        if (conn->conn_ops->DataDigest) {
                iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               cmd->buf_ptr, (text_length + padding),
+                               cmd->buf_ptr, text_length,
                                0, NULL, (u8 *)&cmd->data_crc);
 
                iov[iov_count].iov_base = &cmd->data_crc;
@@ -3530,16 +3540,13 @@ static int iscsit_send_text_rsp(
                tx_size += ISCSI_CRC_LEN;
 
                pr_debug("Attaching DataDigest for %u bytes of text"
-                       " data, CRC 0x%08x\n", (text_length + padding),
+                       " data, CRC 0x%08x\n", text_length,
                        cmd->data_crc);
        }
 
        cmd->iov_misc_count = iov_count;
        cmd->tx_size = tx_size;
 
-       pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x,"
-               " Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn,
-                       text_length, conn->cid);
        return 0;
 }
 
index 90f3b60..ce991ba 100644 (file)
@@ -63,6 +63,8 @@ extern void iscsit_build_nopin_rsp(struct iscsi_cmd *, struct iscsi_conn *,
                                struct iscsi_nopin *, bool);
 extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *,
                                struct iscsi_tm_rsp *);
+extern int iscsit_build_text_rsp(struct iscsi_cmd *, struct iscsi_conn *,
+                               struct iscsi_text_rsp *);
 extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *,
                                struct iscsi_reject *);
 extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *,