Commit 889c8a68 authored by Nicholas Bellinger's avatar Nicholas Bellinger
Browse files

iscsi-target: Refactor ISCSI_OP_TEXT_RSP TX handling



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: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 64534aa7
Loading
Loading
Loading
Loading
+42 −35
Original line number Diff line number Diff line
@@ -3461,34 +3461,19 @@ 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;

	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;
	padding = ((-text_length) & 3);
	hton24(hdr->dlength, text_length);
	hdr->itt = cmd->init_task_tag;
	hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
@@ -3499,14 +3484,39 @@ static int iscsit_send_text_rsp(
	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;
}

+2 −0
Original line number Diff line number Diff line
@@ -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 *,