[stgt] Strange sendtargets behaviour
FUJITA Tomonori
fujita.tomonori at lab.ntt.co.jp
Thu Sep 10 05:49:58 CEST 2009
On Mon, 7 Sep 2009 11:38:49 +0100
Chris Webb <chris at arachsys.com> wrote:
> FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp> writes:
>
> > Ok, I hacked up a patch to support multiple PDUs in SendTarget
> > session. Can you try this with the default
> > discovery.sendtargets.iscsi.MaxRecvDataSegmentLength?
>
> Hi. Many thanks for this. I'll deploy it to a test VM and try it now.
Sorry, I think that there is a bug in the patch (might send corrupted
SendTarget buffer). Let me know this works.
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 79c6e2d..5bde3a5 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) {
- buffer = realloc(buffer, conn->rsp.datasize + len);
- if (buffer)
+ if (conn->rsp.datasize + len > conn->rsp_buffer_size) {
+ buffer = realloc(buffer, conn->rsp_buffer_size * 2);
+ if (buffer) {
conn->rsp_buffer = buffer;
- else
+ conn->rsp_buffer_size *= 2;
+ } else
goto drop;
}
@@ -805,26 +807,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;
+ conn->text_rsp_buffer = conn->rsp_buffer;
+
+ text_scan_text(conn);
+
+ 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;
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list