[Stgt-devel] [PATCH] save stag & va for a scsi command on the task object
Erez Zilber
erezz
Thu Aug 16 16:44:33 CEST 2007
When a command PDU is received, the iSER header contains the read/write
va & stag. This data was saved on the conn_info object. If another command PDU
was received before this data was used, its va & stag were written over the
data for the previous command. This fix saves the va & stag on the task object.
Signed-off-by: Erez Zilber <erezz at voltaire.com>
---
usr/iscsi/iscsi_rdma.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
usr/iscsi/iscsi_tcp.c | 6 ++++++
usr/iscsi/iscsid.c | 10 +++++++++-
usr/iscsi/iscsid.h | 3 +++
usr/iscsi/transport.h | 2 ++
5 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/usr/iscsi/iscsi_rdma.c b/usr/iscsi/iscsi_rdma.c
index cc3d836..0e4a080 100644
--- a/usr/iscsi/iscsi_rdma.c
+++ b/usr/iscsi/iscsi_rdma.c
@@ -119,6 +119,12 @@ struct rdmalist {
struct iscsi_task *task;
};
+struct iser_task {
+ /* read and write from the initiator's point of view */
+ uint32_t rem_read_stag, rem_write_stag;
+ uint64_t rem_read_va, rem_write_va;
+};
+
/*
* One of these for each iscsi_connection, adds more fields needed for iser.
*/
@@ -1230,6 +1236,7 @@ static int iser_rdma_write(int ind, struct iscsi_pdu *rsp,
struct conn_info *ci = &cl.conn[ind];
struct iscsi_data_rsp *datain = (struct iscsi_data_rsp *) &rsp->bhs;
int last_rdma = (task->offset == task->len);
+ struct iser_task *itask = (struct iser_task *)task->trans_data;
iser_out(4, "in %s size %d, %p", __func__, rsp->datasize, rsp);
@@ -1249,10 +1256,13 @@ static int iser_rdma_write(int ind, struct iscsi_pdu *rsp,
dprintf("offset %d len %d last %d\n", task->offset, task->len,
last_rdma);
+ iser_out(4, "%s() posting RDMA write req: "
+ "rem_read_stag %x rem_read_va %lx", __func__,
+ itask->rem_read_stag, itask->rem_read_va);
ret = iser_post_rdma_wr(ci, rdmal, rsp->datasize, IBV_WR_RDMA_WRITE,
last_rdma ? IBV_SEND_SIGNALED : 0,
- ci->rem_read_va + offset, ci->rem_read_stag,
- task);
+ itask->rem_read_va + offset,
+ itask->rem_read_stag, task);
if (ret < 0) {
eprintf("iser_post_rdma_wr failed\n");
@@ -1279,6 +1289,7 @@ static int iser_rdma_read(int ind, struct iscsi_pdu *rsp)
struct conn_info *ci = &cl.conn[ind];
struct iscsi_connection *conn = ci->iscsi_conn;
struct iscsi_task *task = conn->tx_task;
+ struct iser_task *itask = (struct iser_task *)task->trans_data;
struct iscsi_r2t_rsp *r2t = (struct iscsi_r2t_rsp *) &rsp->bhs;
uint8_t *buf;
uint32_t len;
@@ -1295,9 +1306,13 @@ static int iser_rdma_read(int ind, struct iscsi_pdu *rsp)
return -1;
}
+ iser_out(4, "%s() posting RDMA read req: "
+ "rem_read_stag %x rem_read_va %lx", __func__,
+ itask->rem_write_stag, itask->rem_write_va);
+
ret = iser_post_rdma_wr(ci, rdma, len, IBV_WR_RDMA_READ,
- IBV_SEND_SIGNALED, ci->rem_write_va,
- ci->rem_write_stag, task);
+ IBV_SEND_SIGNALED, itask->rem_write_va,
+ itask->rem_write_stag, task);
if (ret < 0) {
iser_out(4, "iser_post_rdma_wr failed");
return ret;
@@ -1447,10 +1462,34 @@ static void iser_event_modify(int ep, int events)
}
}
+void iscsi_iser_task_init(struct iscsi_task *task)
+{
+ struct conn_info *ci;
+ struct iser_task *itask;
+
+ iser_out(8, "%s() Entry", __func__);
+
+ ci = &cl.conn[task->conn->fd];
+ if (!ci->valid) {
+ eprintf("conn %d not valid\n", task->conn->fd);
+ exit(1);
+ }
+
+ itask = (struct iser_task *)task->trans_data;
+
+ /* copy the remote va & stag that were temporarily saved in conn_info */
+ itask->rem_read_stag = ci->rem_read_stag;
+ itask->rem_read_va = ci->rem_read_va;
+ itask->rem_write_stag = ci->rem_write_stag;
+ itask->rem_write_va = ci->rem_write_va;
+}
+
struct iscsi_transport iscsi_iser = {
.name = "iser",
.rdma = 1,
+ .trans_data_len = sizeof(struct iser_task),
.ep_init = iscsi_iser_init,
+ .ep_task_init = iscsi_iser_task_init,
.ep_read = iscsi_iser_read,
.ep_write_begin = iscsi_iser_write_begin,
.ep_write_end = iscsi_iser_write_end,
diff --git a/usr/iscsi/iscsi_tcp.c b/usr/iscsi/iscsi_tcp.c
index e7f5989..b6e9630 100644
--- a/usr/iscsi/iscsi_tcp.c
+++ b/usr/iscsi/iscsi_tcp.c
@@ -251,10 +251,16 @@ void iscsi_tcp_free(void *buf)
free(buf);
}
+void iscsi_tcp_task_init(struct iscsi_task *task)
+{
+}
+
struct iscsi_transport iscsi_tcp = {
.name = "iscsi",
.rdma = 0,
+ .trans_data_len = 0,
.ep_init = iscsi_tcp_init,
+ .ep_task_init = iscsi_tcp_task_init,
.ep_read = iscsi_tcp_read,
.ep_write_begin = iscsi_tcp_write_begin,
.ep_write_end = iscsi_tcp_write_end,
diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
index a3fa6af..c174b98 100644
--- a/usr/iscsi/iscsid.c
+++ b/usr/iscsi/iscsid.c
@@ -1022,11 +1022,17 @@ iscsi_alloc_task(struct iscsi_connection *conn, int ext_len)
struct iscsi_hdr *req = (struct iscsi_hdr *) &conn->req.bhs;
struct iscsi_task *task;
- task = conn->tp->ep_malloc(sizeof(*task) + ext_len);
+ task = conn->tp->ep_malloc(sizeof(*task) + conn->tp->trans_data_len +
+ ext_len);
if (!task)
return NULL;
memset(task, 0, sizeof(*task));
+ if (conn->tp->trans_data_len) {
+ task->trans_data = (void *)((unsigned long)&task[1] + ext_len);
+ memset(task->trans_data, 0, conn->tp->trans_data_len);
+ }
+
memcpy(&task->req, req, sizeof(*req));
task->conn = conn;
INIT_LIST_HEAD(&task->c_hlist);
@@ -1470,6 +1476,8 @@ static int iscsi_scsi_cmd_rx_start(struct iscsi_connection *conn)
else
return -ENOMEM;
+ conn->tp->ep_task_init(task);
+
task->tag = req->itt;
if (ahs_len) {
diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
index 95540f2..ae4490a 100644
--- a/usr/iscsi/iscsid.h
+++ b/usr/iscsi/iscsid.h
@@ -128,6 +128,9 @@ struct iscsi_task {
void *ahs;
void *data;
+ /* Transport specific data */
+ void *trans_data;
+
struct scsi_cmd scmd;
unsigned long extdata[0];
diff --git a/usr/iscsi/transport.h b/usr/iscsi/transport.h
index ebb9a23..54f8cd6 100644
--- a/usr/iscsi/transport.h
+++ b/usr/iscsi/transport.h
@@ -7,8 +7,10 @@ struct iscsi_task;
struct iscsi_transport {
const char *name;
int rdma;
+ int trans_data_len;
int (*ep_init) (void);
+ void (*ep_task_init) (struct iscsi_task *task);
size_t (*ep_read) (int ep, void *buf, size_t nbytes);
size_t (*ep_write_begin) (int ep, void *buf, size_t nbytes);
void (*ep_write_end)(int ep);
--
1.5.2
More information about the stgt
mailing list