[Stgt-devel] [PATCH 4/7] iser bidi alloc read buf
Pete Wyckoff
pw
Mon Jul 30 21:00:23 CEST 2007
Allocate the read buffer for bidirectional commands in the transport,
to pass down to devices. A device can fill and return this buffer in
task->uaddr, and thus choose to do the read or write processing in any
order. Unfortunately, this allocation can not be combined with the
task and task->data allocation as the bidi read size is not known until
after AHS processing.
Necessary for iscsi RDMA transport to be able to provide its own buffers
too.
Signed-off-by: Pete Wyckoff <pw at osc.edu>
---
usr/iscsi/iscsid.c | 27 +++++++++++++++++++--------
usr/tgtd.h | 2 ++
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
index e092462..be0f449 100644
--- a/usr/iscsi/iscsid.c
+++ b/usr/iscsi/iscsid.c
@@ -987,6 +987,8 @@ void iscsi_free_task(struct iscsi_task *task)
{
struct iscsi_connection *conn = task->conn;
+ if (task->addr && task->addr != (unsigned long) task->data)
+ free((void *) (unsigned long) task->addr);
free(task);
/* from alloc */
conn_put(conn);
@@ -1002,10 +1004,6 @@ static void iscsi_free_cmd_task(struct iscsi_task *task)
target_cmd_done(&task->scmd);
list_del(&task->c_hlist);
- if (task->data) {
- if ((unsigned long) task->data != task->addr)
- free((void *) (unsigned long) task->addr);
- }
iscsi_free_task(task);
}
@@ -1066,7 +1064,6 @@ static int iscsi_target_cmd_queue(struct iscsi_task *task)
struct scsi_cmd *scmd = &task->scmd;
struct iscsi_connection *conn = task->conn;
struct iscsi_cmd *req = (struct iscsi_cmd *) &task->req;
- unsigned long uaddr = (unsigned long) task->data;
uint32_t data_len;
uint8_t *ahs;
int ahslen;
@@ -1109,18 +1106,32 @@ static int iscsi_target_cmd_queue(struct iscsi_task *task)
/* figure out incoming (write) and outgoing (read) sizes */
data_len = 0;
+ scmd->bidi_uaddr = 0;
+ scmd->bidi_len = 0;
+ task->read_len = 0;
task->write_len = 0;
+
if (task->dir == WRITE || task->dir == BIDIRECTIONAL) {
task->write_len = ntohl(req->data_length);
data_len = task->write_len;
}
- task->read_len = 0;
if (task->dir == BIDIRECTIONAL && ahslen >= 8) {
struct iscsi_rlength_ahdr *ahs_bidi = (void *) ahs;
if (ahs_bidi->ahstype == ISCSI_AHSTYPE_RLENGTH) {
task->read_len = ntohl(ahs_bidi->read_length);
dprintf("bidi read len %u\n", task->read_len);
}
+ if (task->read_len) {
+ uint32_t len;
+ void *buf;
+
+ len = roundup(task->read_len, 4);
+ buf = malloc(len);
+ if (!buf)
+ return -ENOMEM;
+ scmd->bidi_uaddr = (unsigned long) buf;
+ scmd->bidi_len = task->read_len;
+ }
}
if (task->dir == READ) {
task->read_len = ntohl(req->data_length);
@@ -1129,10 +1140,10 @@ static int iscsi_target_cmd_queue(struct iscsi_task *task)
memcpy(scmd->lun, task->req.lun, sizeof(scmd->lun));
scmd->rw = req->flags & ISCSI_FLAG_CMD_WRITE;
- scmd->len = ntohl(req->data_length);
+ scmd->len = data_len;
scmd->attribute = cmd_attr(task);
scmd->tag = req->itt;
- scmd->uaddr = uaddr;
+ scmd->uaddr = (unsigned long) task->data;
return target_cmd_queue(conn->session->target->tid, scmd);
}
diff --git a/usr/tgtd.h b/usr/tgtd.h
index f2ca458..2e50aac 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -129,6 +129,8 @@ struct scsi_cmd {
uint64_t uaddr;
uint32_t len;
+ uint64_t bidi_uaddr; /* for read part when bidi */
+ uint32_t bidi_len;
int mmapped;
struct scsi_lu *dev;
unsigned long state;
--
1.5.2.4
More information about the stgt
mailing list