Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d473cc7f authored by Mike Christie's avatar Mike Christie Committed by James Bottomley
Browse files

[SCSI] iscsi: Some fixes in preparation for bidirectional support - exp_datasn



This patch fixes handling of expected datasn/r2tsn as received from
target. It is done according to: T10 rfc3720 section 3.2.2.3. Data Sequencing.

. unify expected datasn/r2tsn into one counter
. calculate than check expected datasn/r2tsn. On error print a message
  and fail the request. (TODO use iscsi retransmits)
. remove the FIXME   ;)
. avoid zero length memset

Signed-off-by: default avatarBoaz Harrosh <bharrosh@panasas.com>
Signed-off-by: default avatarBenny Halevy <bhalevy@panasas.com>
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 8ad5781a
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -229,10 +229,13 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
	if (tcp_conn->in.datalen == 0)
		return 0;

	if (ctask->datasn != datasn)
	if (tcp_ctask->exp_datasn != datasn) {
		debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->datasn(%d)\n",
		          __FUNCTION__, tcp_ctask->exp_datasn, datasn);
		return ISCSI_ERR_DATASN;
	}

	ctask->datasn++;
	tcp_ctask->exp_datasn++;

	tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
	if (tcp_ctask->data_offset + tcp_conn->in.datalen > ctask->total_length)
@@ -365,15 +368,16 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
		return ISCSI_ERR_DATALEN;
	}

	if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn)
	if (tcp_ctask->exp_datasn != r2tsn){
		debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
		          __FUNCTION__, tcp_ctask->exp_datasn, r2tsn);
		return ISCSI_ERR_R2TSN;
	}

	rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
	if (rc)
		return rc;

	/* FIXME: use R2TSN to detect missing R2T */

	/* fill-in new R2T associated with the task */
	spin_lock(&session->lock);
	if (!ctask->sc || ctask->mtask ||
@@ -414,7 +418,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)

	iscsi_solicit_data_init(conn, ctask, r2t);

	tcp_ctask->exp_r2tsn = r2tsn + 1;
	tcp_ctask->exp_datasn = r2tsn + 1;
	__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
	tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
	list_move_tail(&ctask->running, &conn->xmitqueue);
@@ -1284,10 +1288,10 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)

	tcp_ctask->sent = 0;
	tcp_ctask->sg_count = 0;
	tcp_ctask->exp_datasn = 0;

	if (sc->sc_data_direction == DMA_TO_DEVICE) {
		tcp_ctask->xmstate = XMSTATE_W_HDR;
		tcp_ctask->exp_r2tsn = 0;
		BUG_ON(ctask->total_length == 0);

		if (sc->use_sg) {
+1 −1
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ struct iscsi_tcp_cmd_task {
	struct scatterlist	*sg;			/* per-cmd SG list  */
	struct scatterlist	*bad_sg;		/* assert statement */
	int			sg_count;		/* SG's to process  */
	uint32_t		exp_r2tsn;
	uint32_t		exp_datasn;		/* expected target's R2TSN/DataSN */
	int			data_offset;
	struct iscsi_r2t_info	*r2t;			/* in progress R2T    */
	struct iscsi_queue	r2tpool;
+3 −2
Original line number Diff line number Diff line
@@ -120,7 +120,9 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
        session->cmdsn++;
        hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
        memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
        memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len);
	if (sc->cmd_len < MAX_COMMAND_SIZE)
		memset(&hdr->cdb[sc->cmd_len], 0,
			MAX_COMMAND_SIZE - sc->cmd_len);

	ctask->data_count = 0;
	if (sc->sc_data_direction == DMA_TO_DEVICE) {
@@ -165,7 +167,6 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
			/* No unsolicit Data-Out's */
			ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
	} else {
		ctask->datasn = 0;
		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
		zero_data(hdr->dlength);

+0 −1
Original line number Diff line number Diff line
@@ -99,7 +99,6 @@ struct iscsi_cmd_task {
	 */
	struct iscsi_cmd	*hdr;
	int			itt;		/* this ITT */
	int			datasn;		/* DataSN */

	uint32_t		unsol_datasn;
	int			imm_count;	/* imm-data (bytes)   */