I updated the multiple text pdus patch. Seems it works for me. Can you try this? Thanks, = From: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx> Subject: [PATCH] iscsi: support multiple text pdus Signed-off-by: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx> --- usr/iscsi/conn.c | 1 + usr/iscsi/iscsid.c | 43 ++++++++++++++++++++++++++++++++----------- usr/iscsi/iscsid.h | 5 +++++ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/usr/iscsi/conn.c b/usr/iscsi/conn.c index 61b570e..ba7a58f 100644 --- a/usr/iscsi/conn.c +++ b/usr/iscsi/conn.c @@ -54,6 +54,7 @@ int conn_init(struct iscsi_connection *conn) free(conn->req_buffer); return -ENOMEM; } + conn->rsp_buffer_size = INCOMING_BUFSIZE; conn->refcount = 1; conn->state = STATE_FREE; diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c index 114c680..047b38e 100644 --- a/usr/iscsi/iscsid.c +++ b/usr/iscsi/iscsid.c @@ -161,21 +161,23 @@ void text_key_add(struct iscsi_connection *conn, char *key, char *value) if (conn->state == STATE_FULL) max_len = conn->session_param[ISCSI_PARAM_MAX_XMIT_DLENGTH].val; else - max_len = INCOMING_BUFSIZE; + max_len = conn->rsp_buffer_size; if (!conn->rsp.datasize) conn->rsp.data = conn->rsp_buffer; buffer = conn->rsp_buffer; - if (conn->rsp.datasize + len > max_len) + if (conn->rsp.datasize + len > max_len && + (conn->req.bhs.opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_TEXT) goto drop; - if (conn->rsp.datasize + len > INCOMING_BUFSIZE) { + if (conn->rsp.datasize + len > conn->rsp_buffer_size) { buffer = realloc(buffer, conn->rsp.datasize + len); if (buffer) { conn->rsp_buffer = buffer; conn->rsp.data = conn->rsp_buffer; + conn->rsp_buffer_size = conn->rsp.datasize + len; } else goto drop; } @@ -806,26 +808,45 @@ static void cmnd_exec_text(struct iscsi_connection *conn) { struct iscsi_text *req = (struct iscsi_text *)&conn->req.bhs; struct iscsi_text_rsp *rsp = (struct iscsi_text_rsp *)&conn->rsp.bhs; + int max_len = conn->session_param[ISCSI_PARAM_MAX_XMIT_DLENGTH].val; memset(rsp, 0, BHS_SIZE); - if (be32_to_cpu(req->ttt) != 0xffffffff) { - /* reject */; - } rsp->opcode = ISCSI_OP_TEXT_RSP; rsp->itt = req->itt; - /* rsp->ttt = rsp->ttt; */ - rsp->ttt = 0xffffffff; conn->exp_cmd_sn = be32_to_cpu(req->cmdsn); if (!(req->opcode & ISCSI_OP_IMMEDIATE)) conn->exp_cmd_sn++; - dprintf("Text request: %d\n", conn->state); - text_scan_text(conn); + if (be32_to_cpu(req->ttt) == ISCSI_RESERVED_TAG) { + conn->text_datasize = 0; + + text_scan_text(conn); + + conn->text_rsp_buffer = conn->rsp_buffer; + conn->text_datasize = conn->rsp.datasize; + + if (conn->text_datasize > max_len) { + conn->ttt++; + if (conn->ttt == ISCSI_RESERVED_TAG) + conn->ttt++; + } else + conn->ttt = ISCSI_RESERVED_TAG; + } else if (!conn->text_datasize || conn->ttt != be32_to_cpu(req->ttt)) { + /* reject */ + return; + } - if (req->flags & ISCSI_FLAG_CMD_FINAL) + if (conn->text_datasize <= max_len) rsp->flags = ISCSI_FLAG_CMD_FINAL; + conn->rsp.datasize = min(max_len, conn->text_datasize); + conn->rsp.data = conn->text_rsp_buffer; + conn->text_rsp_buffer += conn->rsp.datasize; + conn->text_datasize -= conn->rsp.datasize; + + rsp->ttt = cpu_to_be32(conn->ttt); + rsp->statsn = cpu_to_be32(conn->stat_sn++); rsp->exp_cmdsn = cpu_to_be32(conn->exp_cmd_sn); rsp->max_cmdsn = cpu_to_be32(conn->max_cmd_sn); diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h index b301c78..02caad2 100644 --- a/usr/iscsi/iscsid.h +++ b/usr/iscsi/iscsid.h @@ -165,11 +165,16 @@ struct iscsi_connection { void *req_buffer; struct iscsi_pdu rsp; void *rsp_buffer; + int rsp_buffer_size; unsigned char *rx_buffer; unsigned char *tx_buffer; int rx_size; int tx_size; + uint32_t ttt; + int text_datasize; + void *text_rsp_buffer; + struct iscsi_task *rx_task; struct iscsi_task *tx_task; -- 1.6.0.6 -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html