summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rw-r--r--include/iscsi_u.h85
-rw-r--r--kernel/iscsi_if.h22
-rw-r--r--kernel/iscsi_tcp.c45
-rw-r--r--kernel/iscsi_tcp.h1
-rw-r--r--kernel/iscsi_u.c389
-rw-r--r--usr/ctldev.c59
-rw-r--r--usr/discovery.c10
-rw-r--r--usr/idbm.c2
-rw-r--r--usr/idbm.h6
-rw-r--r--usr/initiator.c361
-rw-r--r--usr/initiator.h37
-rw-r--r--usr/io.c60
-rw-r--r--usr/login.c60
14 files changed, 793 insertions, 348 deletions
diff --git a/TODO b/TODO
index 0350b2e..0774ef7 100644
--- a/TODO
+++ b/TODO
@@ -31,3 +31,7 @@ fixme:
* support residual_count in case of scatter-gather Data-In. As of today, only
non-sg Scsi_Cmnd's are working. But I can amazing some target which will
send residual_count in the middle of scatter-gather Data-In.
+
+* daemon should manage its own ITT-space
+* send_pdu() should use new "anon" poll of mtasks. the anon-mtask will be freed
+ right after its xmited
diff --git a/include/iscsi_u.h b/include/iscsi_u.h
index a160248..9a327fd 100644
--- a/include/iscsi_u.h
+++ b/include/iscsi_u.h
@@ -29,9 +29,27 @@
#define UEVENT_BASE 10
#define KEVENT_BASE 100
-/* up events */
+typedef enum {
+ ISCSI_PARAM_MAX_RECV_DLENGTH = 0,
+ ISCSI_PARAM_MAX_XMIT_DLENGTH = 1,
+ ISCSI_PARAM_HDRDGST_EN = 2,
+ ISCSI_PARAM_DATADGST_EN = 3,
+ ISCSI_PARAM_INITIAL_R2T_EN = 4,
+ ISCSI_PARAM_MAX_R2T = 5,
+ ISCSI_PARAM_IMM_DATA_EN = 6,
+ ISCSI_PARAM_FIRST_BURST = 7,
+ ISCSI_PARAM_MAX_BURST = 8,
+ ISCSI_PARAM_PDU_INORDER_EN = 9,
+ ISCSI_PARAM_DATASEQ_INORDER_EN = 10,
+ ISCSI_PARAM_ERL = 11,
+ ISCSI_PARAM_IFMARKER_EN = 12,
+ ISCSI_PARAM_OFMARKER_EN = 13,
+} iscsi_param_e;
+
typedef enum iscsi_uevent_e {
ISCSI_UEVENT_UNKNOWN = 0,
+
+ /* down events */
ISCSI_UEVENT_CREATE_SESSION = UEVENT_BASE + 1,
ISCSI_UEVENT_DESTROY_SESSION = UEVENT_BASE + 2,
ISCSI_UEVENT_CREATE_CNX = UEVENT_BASE + 3,
@@ -39,14 +57,16 @@ typedef enum iscsi_uevent_e {
ISCSI_UEVENT_BIND_CNX = UEVENT_BASE + 5,
ISCSI_UEVENT_SEND_PDU_BEGIN = UEVENT_BASE + 6,
ISCSI_UEVENT_SEND_PDU_END = UEVENT_BASE + 7,
-} iscsi_uevent_e;
+ ISCSI_UEVENT_RECV_PDU_BEGIN = UEVENT_BASE + 8,
+ ISCSI_UEVENT_RECV_PDU_END = UEVENT_BASE + 9,
+ ISCSI_UEVENT_RECV_REQ = UEVENT_BASE + 10,
+ ISCSI_UEVENT_SET_PARAM = UEVENT_BASE + 11,
+ ISCSI_UEVENT_START_CNX = UEVENT_BASE + 12,
-/* down events */
-typedef enum iscsi_kevent_e {
- ISCSI_KEVENT_UNKNOWN = 0,
- ISCSI_KEVENT_CNX_ERROR = KEVENT_BASE + 1,
- ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 2,
-} iscsi_kevent_e;
+ /* up events */
+ ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
+ ISCSI_KEVENT_CNX_ERROR = KEVENT_BASE + 2,
+} iscsi_uevent_e;
typedef struct iscsi_uevent {
int type; /* k/u events type */
@@ -55,7 +75,7 @@ typedef struct iscsi_uevent {
union {
/* messages u -> k */
struct msg_create_session {
- ulong_t handle;
+ ulong_t session_handle;
unsigned int sid;
unsigned int initial_cmdsn;
} c_session;
@@ -64,7 +84,7 @@ typedef struct iscsi_uevent {
} d_session;
struct msg_create_cnx {
ulong_t session_handle;
- ulong_t handle;
+ ulong_t cnx_handle;
int socket_fd;
unsigned int cid;
} c_cnx;
@@ -84,32 +104,39 @@ typedef struct iscsi_uevent {
struct msg_sp_end {
ulong_t cnx_handle;
} sp_end;
+ struct msg_rp_begin {
+ ulong_t cpcnx_handle;
+ ulong_t recv_handle;
+ } rp_begin;
+ struct msg_rp_end_req {
+ ulong_t cpcnx_handle;
+ ulong_t pdu_handle;
+ } rp_end;
+ struct msg_set_param {
+ ulong_t cnx_handle;
+ iscsi_param_e param;
+ unsigned int value;
+ } set_param;
+ struct msg_start_cnx {
+ ulong_t cnx_handle;
+ } start_cnx;
} u;
union {
- /* results */
+ /* messages k -> u */
ulong_t handle;
int retcode;
- } r;
-} iscsi_uevent_t;
-
-typedef struct iscsi_kevent {
- int type; /* k/u events type */
-
- union {
- /* messages k -> u */
+ struct msg_recv_req {
+ ulong_t recv_handle;
+ ulong_t cnx_handle;
+ } recv_req;
struct msg_cnx_error {
unsigned int cid;
} cnxerror;
- struct msg_recv_pdu {
- unsigned int cid;
- unsigned int pdulen;
- } recvpdu;
- } u;
- union {
- /* results */
- ulong_t handle;
- int retcode;
+ struct msg_rp_begin_rsp {
+ ulong_t pdu_handle;
+ unsigned int pdu_size;
+ } rp_begin;
} r;
-} iscsi_kevent_t;
+} iscsi_uevent_t;
#endif /* ISCSI_U_H */
diff --git a/kernel/iscsi_if.h b/kernel/iscsi_if.h
index 4730250..9aa471d 100644
--- a/kernel/iscsi_if.h
+++ b/kernel/iscsi_if.h
@@ -21,10 +21,10 @@
#include <net/tcp.h>
#include <iscsi_proto.h>
+#include <iscsi_u.h>
typedef void* iscsi_snx_h; /* iSCSI Data-Path session handle */
typedef void* iscsi_cnx_h; /* iSCSI Data-Path connection handle */
-typedef void* iscsi_pdu_h; /* iSCSI Control-Path PDU handle */
typedef enum {
ISCSI_STATE_FREE = 1,
@@ -32,23 +32,6 @@ typedef enum {
ISCSI_STATE_FAILED = 3,
} iscsi_session_state_e;
-typedef enum {
- ISCSI_PARAM_MAX_RECV_DLENGH = 0,
- ISCSI_PARAM_MAX_XMIT_DLENGH = 1,
- ISCSI_PARAM_HDRDGST_EN = 2,
- ISCSI_PARAM_DATADGST_EN = 3,
- ISCSI_PARAM_INITIAL_R2T_EN = 4,
- ISCSI_PARAM_MAX_R2T = 5,
- ISCSI_PARAM_IMM_DATA_EN = 6,
- ISCSI_PARAM_FIRST_BURST = 7,
- ISCSI_PARAM_MAX_BURST = 8,
- ISCSI_PARAM_PDU_INORDER_EN = 9,
- ISCSI_PARAM_DATASEQ_INORDER_EN = 10,
- ISCSI_PARAM_ERL = 11,
- ISCSI_PARAM_IFMARKER_EN = 12,
- ISCSI_PARAM_OFMARKER_EN = 13,
-} iscsi_param_e;
-
#define ISCSI_CTRL_ERR_BASE 100
#define ISCSI_DP_ERR_BASE 1000
@@ -139,7 +122,8 @@ typedef struct iscsi_ops {
int data_size);
} iscsi_ops_t;
-int iscsi_control_recv_pdu(iscsi_cnx_h cp_cnx, iscsi_hdr_t *hdr, char *data);
+int iscsi_control_recv_pdu(iscsi_cnx_h cp_cnx, iscsi_hdr_t *hdr,
+ char *data, int data_size);
void iscsi_control_cnx_error(iscsi_cnx_h cp_cnx, int error);
/* FIXME: generic register/unregister interface needed */
diff --git a/kernel/iscsi_tcp.c b/kernel/iscsi_tcp.c
index 33abb04..119a013 100644
--- a/kernel/iscsi_tcp.c
+++ b/kernel/iscsi_tcp.c
@@ -997,7 +997,6 @@ iscsi_hdr_recv(iscsi_conn_t *conn)
* placeholder */
memcpy(&conn->hdr, conn->in.hdr,
sizeof(iscsi_hdr_t));
- conn->data_copied = 0;
}
} else if (cstate == IN_PROGRESS_WRITE) {
rc = iscsi_cmd_rsp(conn, ctask);
@@ -1024,15 +1023,13 @@ iscsi_hdr_recv(iscsi_conn_t *conn)
iscsi_mgmt_task_t *mtask;
rc = iscsi_control_recv_pdu(
- conn->handle, hdr, NULL);
+ conn->handle, hdr, NULL, 0);
mtask = (iscsi_mgmt_task_t *)
session->imm_cmds[conn->in.itt -
ISCSI_IMM_ITT_OFFSET];
if (conn->c_stage == ISCSI_CNX_STARTED) {
iscsi_enqueue(&session->immpool, mtask);
}
- } else {
- conn->data_copied = 0;
}
break;
default:
@@ -1047,19 +1044,18 @@ iscsi_hdr_recv(iscsi_conn_t *conn)
ISCSI_IMM_ITT_OFFSET];
debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n",
- hdr->opcode, conn->id, mtask->itt, conn->in.datalen);
+ conn->in.opcode, conn->id, mtask->itt,
+ conn->in.datalen);
switch(conn->in.opcode) {
case ISCSI_OP_LOGIN_RSP:
case ISCSI_OP_TEXT_RSP:
if (!conn->in.datalen) {
rc = iscsi_control_recv_pdu(
- conn->handle, hdr, NULL);
+ conn->handle, hdr, NULL, 0);
if (conn->c_stage == ISCSI_CNX_STARTED) {
iscsi_enqueue(&session->immpool, mtask);
}
- } else {
- conn->data_copied = 0;
}
break;
default:
@@ -1067,11 +1063,10 @@ iscsi_hdr_recv(iscsi_conn_t *conn)
break;
}
} else if (conn->in.itt == ISCSI_RESERVED_TAG) {
- conn->data_copied = 0;
if (conn->in.opcode == ISCSI_OP_NOOP_IN &&
!conn->in.datalen) {
rc = iscsi_control_recv_pdu(
- conn->handle, hdr, NULL);
+ conn->handle, hdr, NULL, 0);
} else {
rc = ISCSI_ERR_BAD_OPCODE;
}
@@ -1187,12 +1182,13 @@ iscsi_data_recv(iscsi_conn_t *conn)
}
rc = iscsi_control_recv_pdu(conn->handle,
- conn->in.hdr, conn->data);
+ conn->in.hdr, conn->data, conn->in.datalen);
if (mtask && conn->c_stage == ISCSI_CNX_STARTED) {
iscsi_enqueue(&session->immpool, mtask);
}
}
+ break;
default:
__BUG_ON(1);
}
@@ -1450,6 +1446,7 @@ iscsi_mtask_xmit(iscsi_conn_t *conn, iscsi_mgmt_task_t *mtask)
}
if (mtask->data_count == 0 &&
mtask->hdr.itt == ISCSI_RESERVED_TAG) {
+ up(&mtask->xmitsema);
return 0;
} else if (mtask->data_count) {
mtask->in_progress = IN_PROGRESS_IMM_DATA;
@@ -1469,6 +1466,7 @@ iscsi_mtask_xmit(iscsi_conn_t *conn, iscsi_mgmt_task_t *mtask)
} while (mtask->data_count);
}
+ up(&mtask->xmitsema);
return 0;
}
@@ -1708,9 +1706,9 @@ iscsi_data_xmit(iscsi_conn_t *conn)
/* process immediate queue */
while ((mtask = __dequeue(&conn->immqueue)) != NULL) {
- iscsi_session_t *session = conn->session;
+// iscsi_session_t *session = conn->session;
- __enqueue(&session->immpool, mtask);
+// __enqueue(&session->immpool, mtask);
if (conn->c_stage == ISCSI_CNX_STOPPED) {
__insert(&conn->immqueue, mtask);
spin_unlock_bh(&conn->lock);
@@ -1893,12 +1891,12 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
debug_scsi("abort [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
if (iscsi_control_recv_pdu(conn->handle,
- (iscsi_hdr_t*)&ctask->hdr, NULL)) {
+ (iscsi_hdr_t*)&ctask->hdr, NULL, 0)) {
return FAILED;
}
#if 0
- iscsi_session_t *session = conn->session;
iscsi_mgmt_task_t *mtask;
+ iscsi_session_t *session = conn->session;
debug_scsi("abort [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
@@ -1915,7 +1913,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
iscsi_enqueue(&conn->immqueue, mtask);
schedule_work(&conn->xmitwork);
- down(&session->tmsema);
+ down(&mtask->xmitsema);
#endif
return SUCCESS;
}
@@ -2057,6 +2055,10 @@ iscsi_conn_create(iscsi_snx_h snxh, iscsi_cnx_h handle,
conn->exp_statsn = 0;
conn->handle = handle;
+ /* some initial operational parameters */
+ conn->hdr_size = sizeof(iscsi_hdr_t);
+ conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+
spin_lock_init(&conn->lock);
/* initialize xmit PDU commands queue */
@@ -2253,11 +2255,10 @@ iscsi_send_immpdu(iscsi_cnx_h cnxh, iscsi_hdr_t *hdr, char *data,
sizeof(iscsi_hdr_t));
if (mtask->data_count) {
- iscsi_buf_init_virt(&mtask->sendbuf, (char*)&mtask->data,
+ iscsi_buf_init_virt(&mtask->sendbuf, (char*)mtask->data,
mtask->data_count);
/* FIXME: implement convertion of mtask->data into 1st
- * mtask->sendbuf.
- * Keep in mind that virtual buffer
+ * mtask->sendbuf. Keep in mind that virtual buffer
* spreaded accross multiple pages... */
if(mtask->sendbuf.offset + mtask->data_count > PAGE_SIZE) {
if (conn->c_stage == ISCSI_CNX_STARTED) {
@@ -2269,6 +2270,7 @@ iscsi_send_immpdu(iscsi_cnx_h cnxh, iscsi_hdr_t *hdr, char *data,
iscsi_enqueue(&conn->immqueue, mtask);
schedule_work(&conn->xmitwork);
+ down(&mtask->xmitsema);
return 0;
}
@@ -2423,6 +2425,7 @@ iscsi_session_create(iscsi_snx_h handle, int host_no, int initial_cmdsn)
/* pre-format immediate cmds pool with ITT */
for (cmd_i=0; cmd_i<session->imm_max; cmd_i++) {
session->imm_cmds[cmd_i]->itt = ISCSI_IMM_ITT_OFFSET + cmd_i;
+ init_MUTEX_LOCKED(&session->imm_cmds[cmd_i]->xmitsema);
}
if (iscsi_r2tpool_alloc(session)) {
@@ -2480,10 +2483,10 @@ iscsi_set_param(iscsi_cnx_h cnxh, iscsi_param_e param, int value)
if (conn->c_stage == ISCSI_CNX_INITIAL_STAGE) {
switch(param) {
- case ISCSI_PARAM_MAX_RECV_DLENGH:
+ case ISCSI_PARAM_MAX_RECV_DLENGTH:
conn->max_recv_dlength = value;
break;
- case ISCSI_PARAM_MAX_XMIT_DLENGH:
+ case ISCSI_PARAM_MAX_XMIT_DLENGTH:
conn->max_xmit_dlength = value;
break;
case ISCSI_PARAM_HDRDGST_EN:
diff --git a/kernel/iscsi_tcp.h b/kernel/iscsi_tcp.h
index f0939cb..5324ace 100644
--- a/kernel/iscsi_tcp.h
+++ b/kernel/iscsi_tcp.h
@@ -233,6 +233,7 @@ typedef struct iscsi_mgmt_task {
iscsi_buf_t sendbuf; /* in progress buffer */
int sent;
uint32_t itt; /* this ITT */
+ struct semaphore xmitsema;
} iscsi_mgmt_task_t;
typedef union iscsi_union_task {
diff --git a/kernel/iscsi_u.c b/kernel/iscsi_u.c
index 1a89248..f6780f7 100644
--- a/kernel/iscsi_u.c
+++ b/kernel/iscsi_u.c
@@ -24,123 +24,127 @@
#include <linux/poll.h>
#include <asm/uaccess.h>
-/* Must go: for scsi_transport... */
-#include <scsi/scsi_host.h>
-
#include "iscsi_proto.h"
#include "iscsi_if.h"
#include "iscsi_u.h"
+#define CTRL_RECV_ALLOWED 16
+
typedef struct iscsi_kprovider {
char name[ISCSI_PROVIDER_NAME_MAXLEN];
iscsi_ops_t ops;
iscsi_caps_t caps;
} iscsi_kprovider_t;
+static iscsi_kprovider_t provider_table[ISCSI_PROVIDER_MAX];
-typedef enum sp_state_e {
- SP_STATE_INVALID = 0,
- SP_STATE_BUSY = 1,
- SP_STATE_READY = 2,
-} sp_state_e;
-
-typedef struct sp_item {
- struct list_head item;
- sp_state_e state;
- char pdu[DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH+sizeof(iscsi_hdr_t)+4];
-} sp_item_t;
+typedef enum pdu_state_e {
+ PDU_STATE_INVALID = 0,
+ PDU_STATE_READY = 1,
+ PDU_STATE_BUSY = 2,
+} pdu_state_e;
-typedef struct sp_context {
+typedef struct xmit_context {
ulong_t cnxh;
- sp_state_e state;
- sp_item_t *spb;
+ pdu_state_e state;
+ char *pdu;
int hdr_size;
int data_size;
int curr_off;
-} sp_context_t;
-
-static struct list_head sp_head;
-static sp_context_t sp_ctxt;
-static iscsi_kprovider_t provider_table[ISCSI_PROVIDER_MAX];
-static spinlock_t event_queue_lock = SPIN_LOCK_UNLOCKED;
-static LIST_HEAD(event_queue);
-DECLARE_WAIT_QUEUE_HEAD(event_wait);
-
-typedef struct kevent {
- iscsi_uevent_t ev;
- struct list_head list;
-} kevent_t;
-
-int
-iscsi_control_recv_pdu(iscsi_cnx_h cp_cnx, iscsi_hdr_t *hdr, char *data)
-{
- BUG_ON(1);
- return 0;
-}
-
-void
-iscsi_control_cnx_error(iscsi_cnx_h cp_cnx, int error)
-{
-}
+} xmit_context_t;
-kevent_t*
-iscsi_event_get(int del)
+typedef struct recv_context {
+ struct list_head item;
+ iscsi_uevent_e type;
+ ulong_t cp_cnxh;
+ char *pdu;
+ int pdu_size;
+ pdu_state_e state;
+ int curr_off;
+} recv_context_t;
+
+static xmit_context_t xmit;
+static recv_context_t *recv = NULL;
+static struct list_head evqueue;
+static struct list_head evqueue_busy;
+static spinlock_t evqueue_lock;
+static int recv_entry_cnt = 0;
+DECLARE_WAIT_QUEUE_HEAD(evwait);
+
+static recv_context_t*
+recv_entry_get(int del)
{
- kevent_t *kevent = ERR_PTR(-EAGAIN);
+ recv_context_t *entry = ERR_PTR(-EAGAIN);
- spin_lock(&event_queue_lock);
- if (list_empty(&event_queue))
+ spin_lock_bh(&evqueue_lock);
+ if (list_empty(&evqueue))
goto out;
- kevent = list_entry(event_queue.next, kevent_t, list);
- if (del)
- list_del(&kevent->list);
+ entry = list_entry(evqueue.next, recv_context_t, item);
+ if (del) {
+ list_del(&entry->item);
+ recv_entry_cnt--;
+ }
out:
- spin_unlock(&event_queue_lock);
+ spin_unlock_bh(&evqueue_lock);
- return kevent;
+ return entry;
}
int
-iscsi_event_put(iscsi_uevent_e type, int atomic)
+iscsi_control_recv_pdu(iscsi_cnx_h cp_cnx, iscsi_hdr_t *hdr,
+ char *data, int data_size)
{
- kevent_t *kevent;
+ recv_context_t *entry;
- if (atomic) {
- kevent = kmalloc(sizeof(*kevent), GFP_ATOMIC);
- if (!kevent)
- return -ENOMEM;
- } else {
- do {
- kevent = kmalloc(sizeof(*kevent), GFP_KERNEL);
- if (!kevent)
- yield();
- } while (!kevent);
- }
-
- memset(kevent, 0, sizeof(*kevent));
- INIT_LIST_HEAD(&kevent->list);
+ if (recv_entry_cnt >= CTRL_RECV_ALLOWED)
+ return -EPERM;
- kevent->ev.type = type;
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+ if (!entry)
+ return -ENOMEM;
+ memset(entry, 0, sizeof(*entry));
- spin_lock(&event_queue_lock);
- list_add(&kevent->list, &event_queue);
- spin_unlock(&event_queue_lock);
+ entry->pdu = kmalloc(data_size + sizeof(iscsi_hdr_t), GFP_KERNEL);
+ if (!entry->pdu) {
+ kfree(entry);
+ return -ENOMEM;
+ }
+ memcpy(entry->pdu, hdr, sizeof(iscsi_hdr_t));
+ if (data)
+ memcpy(entry->pdu + sizeof(iscsi_hdr_t), data, data_size);
+ entry->type = ISCSI_KEVENT_RECV_PDU;
+ entry->state = PDU_STATE_BUSY;
+ entry->curr_off = 0;
+ entry->cp_cnxh = (ulong_t)cp_cnx;
+ entry->pdu_size = sizeof(iscsi_hdr_t) + data_size;
+
+ spin_lock_bh(&evqueue_lock);
+ recv_entry_cnt++;
+ list_add(&entry->item, &evqueue);
+ spin_unlock_bh(&evqueue_lock);
return 0;
}
+void
+iscsi_control_cnx_error(iscsi_cnx_h cp_cnx, int error)
+{
+}
+
static ssize_t
write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
- if (sp_ctxt.state != SP_STATE_BUSY)
+ if (xmit.state != PDU_STATE_BUSY)
return -EBUSY;
- if (sp_ctxt.curr_off + count > sp_ctxt.hdr_size + sp_ctxt.data_size)
+ if (xmit.curr_off + count > xmit.hdr_size + xmit.data_size)
return -EPERM;
- if (copy_from_user(&sp_ctxt.spb->pdu[sp_ctxt.curr_off], buf, count))
- count = -EFAULT;
- sp_ctxt.curr_off += count;
+ if (copy_from_user(&xmit.pdu[xmit.curr_off], buf, count)) {
+ count = -EFAULT;
+ } else {
+ xmit.curr_off += count;
+ }
return count;
}
@@ -148,19 +152,12 @@ write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
static ssize_t
read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
- kevent_t *kevent;
-
- if (count != sizeof(iscsi_uevent_t))
- return -EIO;
-
- kevent = iscsi_event_get(1);
- if (IS_ERR(kevent))
- return -EAGAIN;
-
- if (copy_to_user(buf, &kevent->ev, count))
+ if (copy_to_user(buf, recv->pdu +
+ recv->curr_off, count)) {
count = -EFAULT;
-
- kfree(kevent);
+ } else {
+ recv->curr_off += count;
+ }
return count;
}
@@ -180,9 +177,9 @@ close(struct inode *inode, struct file *file)
static unsigned int
poll(struct file *filp, poll_table *wait)
{
- poll_wait(filp, &event_wait, wait);
+ poll_wait(filp, &evwait, wait);
- return IS_ERR(iscsi_event_get(0)) ? 0 : POLLIN | POLLRDNORM;
+ return IS_ERR(recv_entry_get(0)) ? 0 : POLLIN | POLLRDNORM;
}
static iscsi_kprovider_t*
@@ -207,7 +204,7 @@ __create_session(unsigned long ptr)
return -EEXIST;
handle = (ulong_t)provider->ops.create_session(
- (void*)ev.u.c_session.handle, ev.u.c_session.sid,
+ (void*)ev.u.c_session.session_handle, ev.u.c_session.sid,
ev.u.c_session.initial_cmdsn);
if (!handle) {
return -EIO;
@@ -242,7 +239,7 @@ __create_cnx(unsigned long ptr)
}
handle = (ulong_t)provider->ops.create_cnx(
- (void*)ev.u.c_cnx.session_handle, (void*)ev.u.c_cnx.handle,
+ (void*)ev.u.c_cnx.session_handle, (void*)ev.u.c_cnx.cnx_handle,
sock, ev.u.c_cnx.cid);
if (!handle) {
return -EIO;
@@ -290,38 +287,24 @@ __send_pdu_begin(unsigned long ptr)
{
int rc;
iscsi_uevent_t ev;
- struct list_head *lh;
if ((rc = copy_from_user(&ev, (void *)ptr, sizeof(ev))) < 0)
return rc;
- if (ev.u.sp_begin.hdr_size + ev.u.sp_begin.data_size >
- DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH + sizeof(iscsi_hdr_t) + 4)
- return -EPERM;
-
- if (sp_ctxt.state != SP_STATE_READY)
+ if (xmit.state != PDU_STATE_READY)
return -EBUSY;
- sp_ctxt.spb = NULL;
- list_for_each(lh, &sp_head) {
- sp_item_t *spb;
- spb = list_entry(lh, sp_item_t, item);
- if (spb && spb->state == SP_STATE_READY) {
- spb->state = SP_STATE_BUSY;
- sp_ctxt.spb = spb;
- break;
- }
- }
- if (sp_ctxt.spb == NULL) {
- /* FIXME: allocate up to configured max. */
+ xmit.pdu = kmalloc(ev.u.sp_begin.hdr_size + ev.u.sp_begin.data_size,
+ GFP_KERNEL);
+ if (xmit.pdu == NULL) {
return -ENOMEM;
}
- sp_ctxt.cnxh = ev.u.sp_begin.cnx_handle;
- sp_ctxt.state = SP_STATE_BUSY;
- sp_ctxt.hdr_size = ev.u.sp_begin.hdr_size;
- sp_ctxt.data_size = ev.u.sp_begin.data_size;
- sp_ctxt.curr_off = 0;
+ xmit.cnxh = ev.u.sp_begin.cnx_handle;
+ xmit.state = PDU_STATE_BUSY;
+ xmit.hdr_size = ev.u.sp_begin.hdr_size;
+ xmit.data_size = ev.u.sp_begin.data_size;
+ xmit.curr_off = 0;
return 0;
}
@@ -339,19 +322,22 @@ __send_pdu_end(unsigned long ptr)
if ((provider = __provider_lookup(ev.provider_id)) == NULL)
return -EEXIST;
- if (sp_ctxt.state != SP_STATE_BUSY)
+ if (xmit.state != PDU_STATE_BUSY)
return -EPERM;
- if (sp_ctxt.cnxh != ev.u.sp_end.cnx_handle)
+ if (xmit.cnxh != ev.u.sp_end.cnx_handle)
return -EPERM;
rc = (ulong_t)provider->ops.send_immpdu(
- (void*)ev.u.sp_end.cnx_handle, (iscsi_hdr_t*)sp_ctxt.spb->pdu,
- sp_ctxt.spb->pdu + sp_ctxt.hdr_size, sp_ctxt.data_size);
+ (void*)ev.u.sp_end.cnx_handle, (iscsi_hdr_t*)xmit.pdu,
+ xmit.pdu + xmit.hdr_size, xmit.data_size);
if (rc) {
return -EIO;
}
+ kfree(xmit.pdu);
+ xmit.state = PDU_STATE_READY;
+
if ((rc = copy_to_user(&((iscsi_uevent_t*)ptr)->r.retcode, &rc,
sizeof(int))) < 0) {
return rc;
@@ -361,6 +347,138 @@ __send_pdu_end(unsigned long ptr)
}
static int
+__recv_pdu_begin(unsigned long ptr)
+{
+ int rc;
+ iscsi_uevent_t ev;
+ recv_context_t *entry = NULL;
+ struct list_head *lh;
+
+ if ((rc = copy_from_user(&ev, (void *)ptr, sizeof(ev))) < 0)
+ return rc;
+
+ list_for_each(lh, &evqueue_busy) {
+ entry = list_entry(lh, recv_context_t, item);
+ if (entry && entry == (void*)ev.u.rp_begin.recv_handle) {
+ spin_lock_bh(&evqueue_lock);
+ list_del(&entry->item);
+ spin_unlock_bh(&evqueue_lock);
+ break;
+ }
+ }
+ if (entry != (void*)ev.u.rp_begin.recv_handle)
+ return -EIO;
+
+ ev.r.rp_begin.pdu_handle = (ulong_t)entry->pdu;
+ ev.r.rp_begin.pdu_size = entry->pdu_size;
+
+ if ((rc = copy_to_user((void*)ptr, &ev, sizeof(ev))) < 0) {
+ spin_lock_bh(&evqueue_lock);
+ list_add(&entry->item, &evqueue_busy);
+ spin_unlock_bh(&evqueue_lock);
+ return rc;
+ }
+
+ recv = entry;
+
+ return 0;
+}
+
+static int
+__recv_pdu_end(unsigned long ptr)
+{
+ int rc;
+ iscsi_uevent_t ev;
+
+ if (recv == NULL)
+ return -EIO;
+
+ if ((rc = copy_from_user(&ev, (void *)ptr, sizeof(ev))) < 0)
+ return rc;
+
+ if (ev.u.rp_end.cpcnx_handle != (ulong_t)recv->cp_cnxh)
+ return -EPERM;
+
+ if (ev.u.rp_end.pdu_handle != (ulong_t)recv->pdu)
+ return -EPERM;
+
+ kfree(recv->pdu);
+ kfree(recv);
+ recv = NULL;
+
+ return 0;
+}
+
+static int
+__recv_req(unsigned long ptr)
+{
+ int rc;
+ iscsi_uevent_t ev;
+ recv_context_t *entry;
+
+ if ((rc = copy_from_user(&ev, (void *)ptr, sizeof(ev))) < 0)
+ return rc;
+
+ entry = recv_entry_get(1);
+ if (IS_ERR(entry))
+ return -EPERM;
+
+ spin_lock_bh(&evqueue_lock);
+ list_add(&entry->item, &evqueue_busy);
+ spin_unlock_bh(&evqueue_lock);
+
+ ev.type = entry->type;
+ ev.r.recv_req.recv_handle = (ulong_t)entry;
+ ev.r.recv_req.cnx_handle = (ulong_t)entry->cp_cnxh;
+
+ if ((rc = copy_to_user((void*)ptr, &ev, sizeof(ev))) < 0)
+ return rc;
+
+ return 0;
+}
+
+static int
+__set_param(unsigned long ptr)
+{
+ int rc;
+ iscsi_uevent_t ev;
+ iscsi_kprovider_t *provider;
+
+ if ((rc = copy_from_user(&ev, (void *)ptr, sizeof(ev))) < 0)
+ return rc;
+
+ if ((provider = __provider_lookup(ev.provider_id)) == NULL)
+ return -EEXIST;
+
+ rc = provider->ops.set_param((void*)ev.u.set_param.cnx_handle,
+ ev.u.set_param.param, ev.u.set_param.value);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
+static int
+__start_cnx(unsigned long ptr)
+{
+ int rc;
+ iscsi_uevent_t ev;
+ iscsi_kprovider_t *provider;
+
+ if ((rc = copy_from_user(&ev, (void *)ptr, sizeof(ev))) < 0)
+ return rc;
+
+ if ((provider = __provider_lookup(ev.provider_id)) == NULL)
+ return -EEXIST;
+
+ rc = provider->ops.start_cnx((void*)ev.u.set_param.cnx_handle);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
+static int
ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -376,6 +494,11 @@ ioctl(struct inode *inode, struct file *file,
case ISCSI_UEVENT_BIND_CNX: return __bind_cnx(arg);
case ISCSI_UEVENT_SEND_PDU_BEGIN: return __send_pdu_begin(arg);
case ISCSI_UEVENT_SEND_PDU_END: return __send_pdu_end(arg);
+ case ISCSI_UEVENT_RECV_PDU_BEGIN: return __recv_pdu_begin(arg);
+ case ISCSI_UEVENT_RECV_PDU_END: return __recv_pdu_end(arg);
+ case ISCSI_UEVENT_RECV_REQ: return __recv_req(arg);
+ case ISCSI_UEVENT_SET_PARAM: return __set_param(arg);
+ case ISCSI_UEVENT_START_CNX: return __start_cnx(arg);
default: return -EPERM;
}
@@ -399,25 +522,17 @@ static int __init
iscsi_init(void)
{
int rc;
- sp_item_t *spb;
printk(KERN_INFO "Open-iSCSI Provider Manager, version "
ISCSI_VERSION_STR " variant (" ISCSI_DATE_STR ")\n");
- INIT_LIST_HEAD(&sp_head);
-
- spb = kmalloc(sizeof(sp_item_t), GFP_KERNEL);
- if (spb == NULL) {
- printk("failed to allocate send pdu buffer\n");
- return -ENOMEM;
- }
- list_add(&spb->item, &sp_head);
- spb->state = SP_STATE_READY;
- sp_ctxt.state = SP_STATE_READY;
+ INIT_LIST_HEAD(&evqueue);
+ INIT_LIST_HEAD(&evqueue_busy);
+ evqueue_lock = SPIN_LOCK_UNLOCKED;
+ xmit.state = PDU_STATE_READY;
ctr_major = register_chrdev(0, ctr_name, &ctr_fops);
if (ctr_major < 0) {
- kfree(spb);
printk("failed to register the control device %d\n", ctr_major);
return ctr_major;
}
@@ -427,7 +542,6 @@ iscsi_init(void)
rc = iscsi_tcp_register(&provider_table[0].ops,
&provider_table[0].caps);
if (rc) {
- kfree(spb);
unregister_chrdev(ctr_major, ctr_name);
return rc;
}
@@ -438,17 +552,8 @@ iscsi_init(void)
static void __exit
iscsi_exit(void)
{
- struct list_head *lh, *n;
iscsi_tcp_unregister();
unregister_chrdev(ctr_major, ctr_name);
- list_for_each_safe(lh, n, &sp_head) {
- sp_item_t *spb;
- spb = list_entry(lh, sp_item_t, item);
- if (spb) {
- list_del(&spb->item);
- kfree(spb);
- }
- }
}
module_init(iscsi_init);
diff --git a/usr/ctldev.c b/usr/ctldev.c
index 08a5c5a..4ffca5b 100644
--- a/usr/ctldev.c
+++ b/usr/ctldev.c
@@ -37,29 +37,50 @@
int
ctldev_handle(int fd)
{
- iscsi_uevent_t event;
- int res;
-
- while (1) {
- res = read(fd, &event, sizeof(event));
- if (res < 0) {
- if (errno == EAGAIN)
- return 0;
- if (errno == EINTR)
- continue;
- log_error("got error (%d) when read ctrl_fd", errno);
- return 1;
+ int rc;
+ iscsi_uevent_t ev;
+ struct qelem *item;
+ iscsi_session_t *session = NULL;
+ iscsi_conn_t *conn = NULL;
+
+ if ((rc = ioctl(fd, ISCSI_UEVENT_RECV_REQ, &ev)) < 0) {
+ log_error("can't fetch recv event information "
+ "(%d), retcode %d", errno, rc);
+ return rc;
+ }
+
+ if (ev.type == ISCSI_KEVENT_RECV_PDU) {
+
+ /* verify connection */
+ item = provider[0].sessions.q_forw;
+ while (item != &provider[0].sessions) {
+ int i;
+ session = (iscsi_session_t *)item;
+ for (i=0; i<ISCSI_CNX_MAX; i++) {
+ if (&session->cnx[i] == (iscsi_conn_t*)
+ ev.r.recv_req.cnx_handle) {
+ conn = &session->cnx[i];
+ break;
+ }
+ }
+ item = item->q_forw;
+ }
+ if (conn == NULL) {
+ log_error("could not verify connection 0x%llx for "
+ "event RECV_PDU", (uint64_t)(ulong_t)conn);
+ return -ENXIO;
}
- log_debug(1, "got event, type %u", event.type);
+ /* produce an event, so session manager will handle */
+ queue_produce(session->queue, EV_CNX_RECV_PDU, conn,
+ sizeof(ulong_t), (void*)&ev.r.recv_req.recv_handle);
+ actor_schedule(&session->mainloop);
- switch (event.type) {
- default:
- log_error("%s(%d) %u\n", __FUNCTION__, __LINE__,
- event.type);
- return -1;
- }
+ } else if (ev.type == ISCSI_KEVENT_CNX_ERROR) {
+ } else {
+ log_error("unknown kernel event %d", ev.type);
}
+
return 0;
}
diff --git a/usr/discovery.c b/usr/discovery.c
index 3a793f2..b230f17 100644
--- a/usr/discovery.c
+++ b/usr/discovery.c
@@ -671,12 +671,10 @@ init_new_session(struct iscsi_sendtargets_config *config)
session->cnx[0].ping_timeout = config->cnx_timeo.ping_timeout;
session->send_async_text = config->continuous ?
config->send_async_text : -1;
- session->cnx[0].header_digest = ISCSI_DIGEST_NONE;
- session->cnx[0].data_digest = ISCSI_DIGEST_NONE;
- session->cnx[0].max_recv_data_segment_len =
- DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
- session->cnx[0].max_xmit_data_segment_len =
- DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+ session->cnx[0].hdrdgst_en = ISCSI_DIGEST_NONE;
+ session->cnx[0].datadgst_en = ISCSI_DIGEST_NONE;
+ session->cnx[0].max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+ session->cnx[0].max_xmit_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
/* OUI and uniqifying number */
session->isid[0] = DRIVER_ISID_0;
diff --git a/usr/idbm.c b/usr/idbm.c
index a3c102d..d24d224 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -24,6 +24,8 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/file.h>
+#define DB_DBM_HSEARCH 1
+#include <db.h>
#include "idbm.h"
#include "log.h"
diff --git a/usr/idbm.h b/usr/idbm.h
index 30e9ccd..e18aedc 100644
--- a/usr/idbm.h
+++ b/usr/idbm.h
@@ -21,8 +21,6 @@
#define IDBM_H
#include <sys/types.h>
-#define DB_DBM_HSEARCH 1
-#include <db.h>
#include "initiator.h"
#include "config.h"
@@ -46,8 +44,8 @@ typedef struct recinfo {
} recinfo_t;
typedef struct idbm {
- DBM *discdb;
- DBM *nodedb;
+ void *discdb;
+ void *nodedb;
char *configfile;
node_rec_t nrec;
recinfo_t ninfo[MAX_KEYS];
diff --git a/usr/initiator.c b/usr/initiator.c
index 8e31dca..48c9e68 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -17,6 +17,7 @@
* See the file COPYING included with this distribution for more details.
*/
+#include <search.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
@@ -232,16 +233,15 @@ session_cnx_create(iscsi_session_t *session, int cid)
conn->ping_timeout = cnx->timeo.ping_timeout;
/* operational parameters */
- conn->max_recv_data_segment_len =
+ conn->max_recv_dlength =
cnx->iscsi.MaxRecvDataSegmentLength;
/*
* iSCSI default, unless declared otherwise by the
* target during login
*/
- conn->max_xmit_data_segment_len =
- DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
- conn->header_digest = cnx->iscsi.HeaderDigest;
- conn->data_digest = cnx->iscsi.DataDigest;
+ conn->max_xmit_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+ conn->hdrdgst_en = cnx->iscsi.HeaderDigest;
+ conn->datadgst_en = cnx->iscsi.DataDigest;
/* TCP options */
conn->tcp_window_size = cnx->tcp.window_size;
@@ -344,10 +344,10 @@ session_create(node_rec_t *rec)
actor_schedule(&session->mainloop);
/* session's operational parameters */
- session->initial_r2t = rec->session.iscsi.InitialR2T;
- session->immediate_data = rec->session.iscsi.ImmediateData;
- session->first_burst_len = rec->session.iscsi.FirstBurstLength;
- session->max_burst_len = rec->session.iscsi.MaxBurstLength;
+ session->initial_r2t_en = rec->session.iscsi.InitialR2T;
+ session->imm_data_en = rec->session.iscsi.ImmediateData;
+ session->first_burst = rec->session.iscsi.FirstBurstLength;
+ session->max_burst = rec->session.iscsi.MaxBurstLength;
session->def_time2wait = rec->session.iscsi.DefaultTime2Wait;
session->def_time2retain = rec->session.iscsi.DefaultTime2Retain;
session->portal_group_tag = rec->tpgt;
@@ -368,12 +368,15 @@ session_create(node_rec_t *rec)
/* setup authentication variables for the session*/
setup_authentication(session, &rec->session.auth);
+ insque(&session->item, &provider[0].sessions);
+
return session;
}
void
session_destroy(iscsi_session_t *session)
{
+ remque(&session->item);
queue_flush(session->queue);
queue_destroy(session->queue);
actor_delete(&session->mainloop);
@@ -390,7 +393,7 @@ __ksession_create(iscsi_session_t *session)
ev.type = ISCSI_UEVENT_CREATE_SESSION;
ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.c_session.handle = (ulong_t)session;
+ ev.u.c_session.session_handle = (ulong_t)session;
ev.u.c_session.sid = session->id;
ev.u.c_session.initial_cmdsn = session->nrec.session.initial_cmdsn;
@@ -418,7 +421,7 @@ __ksession_cnx_create(iscsi_session_t *session, iscsi_conn_t *conn)
ev.type = ISCSI_UEVENT_CREATE_CNX;
ev.provider_id = 0; /* FIXME: hardcoded */
ev.u.c_cnx.session_handle = session->handle;
- ev.u.c_cnx.handle = (ulong_t)conn;
+ ev.u.c_cnx.cnx_handle = (ulong_t)conn;
ev.u.c_cnx.socket_fd = conn->socket_fd;
ev.u.c_cnx.cid = conn->id;
@@ -569,8 +572,280 @@ __ksession_send_pdu_end(iscsi_session_t *session, iscsi_conn_t *conn)
#endif
static void
+__session_ipc_login_cleanup(queue_task_t *qtask, ipc_err_e err)
+{
+ iscsi_conn_t *conn = qtask->conn;
+ iscsi_session_t *session = conn->session;
+
+ qtask->u.login.rsp.err = err;
+ write(qtask->u.login.ipc_fd, &qtask->u.login.rsp,
+ sizeof(qtask->u.login.rsp));
+ close(qtask->u.login.ipc_fd);
+ free(qtask);
+ if (conn->login_context.buffer)
+ free(conn->login_context.buffer);
+ session_cnx_destroy(session, conn->id);
+ if (conn->id == 0)
+ session_destroy(session);
+}
+
+static int
+__ksession_set_param(iscsi_conn_t *conn, iscsi_param_e param, uint32_t value)
+{
+ int rc;
+ iscsi_uevent_t ev;
+
+ memset(&ev, 0, sizeof(iscsi_uevent_t));
+
+ ev.type = ISCSI_UEVENT_SET_PARAM;
+ ev.provider_id = 0; /* FIXME: hardcoded */
+ ev.u.set_param.cnx_handle = (ulong_t)conn->handle;
+ ev.u.set_param.param = param;
+ ev.u.set_param.value = value;
+
+ if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_SET_PARAM, &ev)) < 0) {
+ log_error("can't set operational parameter %d for cnx with "
+ "id = %d (%d)", param, conn->id, errno);
+ return rc;
+ }
+
+ log_debug(3, "set operational parameter %d to %u",
+ param, value);
+
+ return 0;
+}
+
+static int
+__ksession_start_cnx(iscsi_conn_t *conn)
+{
+ int rc;
+ iscsi_uevent_t ev;
+
+ memset(&ev, 0, sizeof(iscsi_uevent_t));
+
+ ev.type = ISCSI_UEVENT_SET_PARAM;
+ ev.provider_id = 0; /* FIXME: hardcoded */
+ ev.u.start_cnx.cnx_handle = (ulong_t)conn->handle;
+
+ if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_START_CNX, &ev)) < 0) {
+ log_error("can't start connection 0x%llx with "
+ "id = %d (%d)", (uint64_t)conn->handle,
+ conn->id, errno);
+ return rc;
+ }
+
+ log_debug(3, "connection 0x%llx operational now",
+ (uint64_t)conn->handle);
+
+ return 0;
+}
+
+static int
+__ksession_recv_pdu_begin(iscsi_conn_t *conn, ulong_t recv_handle,
+ ulong_t *pdu_handle, int *pdu_size)
+{
+ int rc;
+ iscsi_uevent_t ev;
+
+ memset(&ev, 0, sizeof(iscsi_uevent_t));
+
+ ev.type = ISCSI_UEVENT_RECV_PDU_BEGIN;
+ ev.provider_id = 0; /* FIXME: hardcoded */
+ ev.u.rp_begin.cpcnx_handle = (ulong_t)conn;
+ ev.u.rp_begin.recv_handle = recv_handle;
+
+ if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_RECV_PDU_BEGIN, &ev)) < 0) {
+ log_error("can't initiate recv PDU operation for cnx with "
+ "id = %d (%d)", conn->id, errno);
+ return rc;
+ }
+
+ *pdu_handle = ev.r.rp_begin.pdu_handle;
+ *pdu_size = ev.r.rp_begin.pdu_size;
+
+ log_debug(3, "recv PDU began, pdu handle 0x%llx size %d",
+ (uint64_t)*pdu_handle, *pdu_size);
+
+ return 0;
+}
+
+static int
+__ksession_recv_pdu_end(iscsi_conn_t *conn, ulong_t pdu_handle)
+{
+ int rc;
+ iscsi_uevent_t ev;
+
+ memset(&ev, 0, sizeof(iscsi_uevent_t));
+
+ ev.type = ISCSI_UEVENT_RECV_PDU_END;
+ ev.provider_id = 0; /* FIXME: hardcoded */
+ ev.u.rp_end.cpcnx_handle = (ulong_t)conn;
+ ev.u.rp_end.pdu_handle = pdu_handle;
+
+ if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_RECV_PDU_END, &ev)) < 0) {
+ log_error("can't finish recv PDU operation for cnx with "
+ "id = %d (%d)", conn->id, errno);
+ return rc;
+ }
+
+ log_debug(3, "recv PDU finished for pdu handle 0x%llx",
+ (uint64_t)pdu_handle);
+
+ return 0;
+}
+
+static void
__session_cnx_recv_pdu(queue_item_t *item)
{
+ ulong_t recv_handle = *(ulong_t*)queue_item_data(item);
+ iscsi_conn_t *conn = item->context;
+ iscsi_session_t *session = conn->session;
+
+ if (conn->state == STATE_WAIT_LOGIN_RSP) {
+ iscsi_login_context_t *c = &conn->login_context;
+
+ conn->recv_handle = recv_handle;
+
+ if (iscsi_login_rsp(session, c)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+
+ if (conn->current_stage != ISCSI_FULL_FEATURE_PHASE) {
+ /* more nego. needed! */
+ conn->state = STATE_WAIT_LOGIN_RSP;
+ if (iscsi_login_req(session, c)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ } else {
+ /* almost! entered full-feature phase */
+
+ if (login_response_status(conn, c->ret) !=
+ CNX_LOGIN_SUCCESS) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+
+ /* check the login status */
+ if (check_iscsi_status_class(session, conn->id,
+ c->status_class, c->status_detail) !=
+ CNX_LOGIN_SUCCESS) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+
+ /* Entered full-feature phase! */
+
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_MAX_RECV_DLENGTH,
+ conn->max_recv_dlength)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_MAX_XMIT_DLENGTH,
+ conn->max_xmit_dlength)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_HDRDGST_EN, conn->hdrdgst_en)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_DATADGST_EN, conn->datadgst_en)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (conn->id == 0) {
+ /* setup session's op. parameters just once */
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_INITIAL_R2T_EN,
+ session->initial_r2t_en)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_MAX_R2T,
+ 1 /* FIXME: session->max_r2t */)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_IMM_DATA_EN,
+ session->imm_data_en)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_FIRST_BURST,
+ session->first_burst)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_MAX_BURST,
+ session->max_burst)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_PDU_INORDER_EN,
+ session->pdu_inorder_en)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_DATASEQ_INORDER_EN,
+ session->dataseq_inorder_en)) {
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_ERL,
+ 0 /* FIXME: session->erl */)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_IFMARKER_EN,
+ 0 /* FIXME: session->ifmarker_en */)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+ if (__ksession_set_param(conn,
+ ISCSI_PARAM_OFMARKER_EN,
+ 0 /* FIXME: session->ofmarker_en */)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
+ }
+
+ }
+
+ if (__ksession_start_cnx(conn)) {
+ __session_ipc_login_cleanup(c->qtask,
+ IPC_ERR_INTERNAL);
+ return;
+ }
+ }
+ }
}
static void
@@ -592,68 +867,67 @@ __session_cnx_poll(queue_item_t *item)
/* connected! */
+ memset(c, 0, sizeof(iscsi_login_context_t));
+
actor_delete(&conn->connect_timer);
if (conn->id == 0 && __ksession_create(session)) {
- qtask->u.login.rsp.err = IPC_ERR_INTERNAL;
- goto err;
+ __session_ipc_login_cleanup(qtask,
+ IPC_ERR_INTERNAL);
+ return;
}
if (__ksession_cnx_create(session, conn)) {
- qtask->u.login.rsp.err = IPC_ERR_INTERNAL;
- goto err;
+ __session_ipc_login_cleanup(qtask,
+ IPC_ERR_INTERNAL);
+ return;
}
if (__ksession_cnx_bind(session, conn)) {
- qtask->u.login.rsp.err = IPC_ERR_INTERNAL;
- goto err;
+ __session_ipc_login_cleanup(qtask,
+ IPC_ERR_INTERNAL);
+ return;
}
conn->kernel_io = 1;
conn->ctrl_fd = ctrl_fd;
conn->send_pdu_begin = __ksession_send_pdu_begin;
conn->send_pdu_end = __ksession_send_pdu_end;
+ conn->recv_pdu_begin = __ksession_recv_pdu_begin;
+ conn->recv_pdu_end = __ksession_recv_pdu_end;
+ c->qtask = qtask;
c->cid = conn->id;
c->buffer = calloc(1,
DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH);
if (!c->buffer) {
log_error("failed to allocate recv "
"data buffer");
- qtask->u.login.rsp.err = IPC_ERR_NOMEM;
- goto err;
+ __session_ipc_login_cleanup(qtask,
+ IPC_ERR_NOMEM);
+ return;
}
c->bufsize = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
if (iscsi_login_begin(session, c)) {
- qtask->u.login.rsp.err = IPC_ERR_LOGIN_FAILURE;
- goto err;
+ __session_ipc_login_cleanup(qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
}
+ conn->state = STATE_WAIT_LOGIN_RSP;
if (iscsi_login_req(session, c)) {
- qtask->u.login.rsp.err = IPC_ERR_LOGIN_FAILURE;
- goto err;
+ __session_ipc_login_cleanup(qtask,
+ IPC_ERR_LOGIN_FAILURE);
+ return;
}
- conn->state = STATE_WAIT_PDU_RSP;
} else {
actor_delete(&conn->connect_timer);
/* error during connect */
- qtask->u.login.rsp.err = IPC_ERR_TCP_FAILURE;
- goto err;
+ __session_ipc_login_cleanup(qtask,
+ IPC_ERR_TCP_FAILURE);
}
}
-
- return;
-
-err:
- /* clean connection. write rsp. cleanup session if needed */
- write(qtask->u.login.ipc_fd, &qtask->u.login.rsp,
- sizeof(qtask->u.login.rsp));
- close(qtask->u.login.ipc_fd);
- free(qtask);
- session_cnx_destroy(session, conn->id);
- if (conn->id == 0)
- session_destroy(session);
}
static void
@@ -661,18 +935,11 @@ __session_cnx_timer(queue_item_t *item)
{
queue_task_t *qtask = item->context;
iscsi_conn_t *conn = qtask->conn;
- iscsi_session_t *session = conn->session;
if (conn->state == STATE_WAIT_CONNECT) {
/* timeout during connect. clean connection. write rsp */
- qtask->u.login.rsp.err = IPC_ERR_TCP_TIMEOUT;
- write(qtask->u.login.ipc_fd, &qtask->u.login.rsp,
- sizeof(qtask->u.login.rsp));
- close(qtask->u.login.ipc_fd);
- free(qtask);
- session_cnx_destroy(session, conn->id);
- if (conn->id == 0)
- session_destroy(session);
+ __session_ipc_login_cleanup(qtask, IPC_ERR_TCP_TIMEOUT);
+ return;
}
}
diff --git a/usr/initiator.h b/usr/initiator.h
index 39bf562..88e5e22 100644
--- a/usr/initiator.h
+++ b/usr/initiator.h
@@ -61,7 +61,7 @@ enum iscsi_login_status {
typedef enum iscsi_cnx_state_e {
STATE_IDLE = 0,
STATE_WAIT_CONNECT = 1,
- STATE_WAIT_PDU_RSP = 2,
+ STATE_WAIT_LOGIN_RSP = 2,
} iscsi_cnx_state_e;
typedef enum iscsi_event_e {
@@ -76,6 +76,8 @@ typedef struct iscsi_event {
char payload[EVENT_PAYLOAD_MAX];
} iscsi_event_t;
+struct queue_task;
+
typedef struct iscsi_login_context {
int cid;
char *buffer;
@@ -91,6 +93,7 @@ typedef struct iscsi_login_context {
int timeout;
int final;
enum iscsi_login_status ret;
+ struct queue_task *qtask;
} iscsi_login_context_t;
struct iscsi_session;
@@ -100,11 +103,16 @@ typedef int (*send_pdu_begin_f)(struct iscsi_session *session,
struct iscsi_conn *conn, int hdr_size, int data_size);
typedef int (*send_pdu_end_f)(struct iscsi_session *session,
struct iscsi_conn *conn);
+typedef int (*recv_pdu_begin_f)(struct iscsi_conn *conn, ulong_t recv_handle,
+ ulong_t *pdu_handle, int *pdu_size);
+typedef int (*recv_pdu_end_f)(struct iscsi_conn *conn, ulong_t pdu_handle);
/* daemon's connection structure */
typedef struct iscsi_conn {
+ struct qelem item; /* must stay at the top */
int id;
ulong_t handle;
+ ulong_t recv_handle;
struct iscsi_session *session;
iscsi_login_context_t login_context;
uint8_t *rx_buffer;
@@ -115,6 +123,8 @@ typedef struct iscsi_conn {
int ctrl_fd;
send_pdu_begin_f send_pdu_begin;
send_pdu_end_f send_pdu_end;
+ recv_pdu_begin_f recv_pdu_begin;
+ recv_pdu_end_f recv_pdu_end;
/* login state machine */
int current_stage;
@@ -142,10 +152,10 @@ typedef struct iscsi_conn {
uint32_t exp_statsn;
/* negotiated parameters */
- int header_digest;
- int data_digest;
- int max_recv_data_segment_len; /* the value we declare */
- int max_xmit_data_segment_len; /* the value declared by the target */
+ int hdrdgst_en;
+ int datadgst_en;
+ int max_recv_dlength; /* the value we declare */
+ int max_xmit_dlength; /* the value declared by the target */
} iscsi_conn_t;
typedef struct queue_task {
@@ -163,13 +173,14 @@ typedef struct queue_task {
int ipc_fd;
} logout;
/* iSCSI requests originated via CTL */
- struct ctlreq_async_ev {
- } async_ev;
+ struct ctlreq_recv_pdu {
+ } recv_pdu;
} u;
} queue_task_t;
/* daemon's session structure */
typedef struct iscsi_session {
+ struct qelem item; /* must stay at the top */
int id;
ulong_t handle;
node_rec_t nrec; /* copy of original Node record in database */
@@ -180,12 +191,12 @@ typedef struct iscsi_session {
uint32_t cmdsn;
uint32_t exp_cmdsn;
uint32_t max_cmdsn;
- int immediate_data;
- int initial_r2t;
- int first_burst_len;
- int max_burst_len;
- int data_pdu_in_order;
- int data_seq_in_order;
+ int imm_data_en;
+ int initial_r2t_en;
+ int first_burst;
+ int max_burst;
+ int pdu_inorder_en;
+ int dataseq_inorder_en;
int def_time2wait;
int def_time2retain;
int type;
diff --git a/usr/io.c b/usr/io.c
index 96c3c20..029a1cc 100644
--- a/usr/io.c
+++ b/usr/io.c
@@ -434,24 +434,35 @@ iscsi_recv_pdu(iscsi_conn_t *conn, iscsi_hdr_t *hdr,
char *end = data + max_data_length;
struct sigaction action;
struct sigaction old;
+ ulong_t pdu_handle;
+ int pdu_size;
/* set a timeout, since the socket calls may take a long
* time to timeout on their own
*/
- memset(data, 0, max_data_length);
- memset(&action, 0, sizeof (struct sigaction));
- memset(&old, 0, sizeof (struct sigaction));
- action.sa_sigaction = NULL;
- action.sa_flags = 0;
- action.sa_handler = sigalarm_handler;
- sigaction(SIGALRM, &action, &old);
- timedout = 0;
- alarm(timeout);
+ if (!conn->kernel_io) {
+ memset(data, 0, max_data_length);
+ memset(&action, 0, sizeof (struct sigaction));
+ memset(&old, 0, sizeof (struct sigaction));
+ action.sa_sigaction = NULL;
+ action.sa_flags = 0;
+ action.sa_handler = sigalarm_handler;
+ sigaction(SIGALRM, &action, &old);
+ timedout = 0;
+ alarm(timeout);
+ } else {
+ if (conn->recv_pdu_begin(conn, conn->recv_handle,
+ &pdu_handle, &pdu_size)) {
+ failed = 1;
+ goto done;
+ }
+ }
/* read a response header */
do {
rlen =
- read(conn->socket_fd, header, sizeof (*hdr) - h_bytes);
+ read(conn->kernel_io ? conn->ctrl_fd : conn->socket_fd,
+ header, sizeof (*hdr) - h_bytes);
if (timedout) {
log_error("socket %d header read timed out",
conn->socket_fd);
@@ -505,7 +516,8 @@ iscsi_recv_pdu(iscsi_conn_t *conn, iscsi_hdr_t *hdr,
d_bytes = 0;
while (d_bytes < dlength) {
rlen =
- read(conn->socket_fd, data + d_bytes, dlength - d_bytes);
+ read(conn->kernel_io ? conn->ctrl_fd : conn->socket_fd,
+ data + d_bytes, dlength - d_bytes);
if (timedout) {
log_error("socket %d data read timed out",
conn->socket_fd);
@@ -525,9 +537,10 @@ iscsi_recv_pdu(iscsi_conn_t *conn, iscsi_hdr_t *hdr,
}
}
- /* handle PDU data padding */
+ /* handle PDU data padding.
+ * data is padded in case of kernel_io */
pad = dlength % PAD_WORD_LEN;
- if (pad) {
+ if (pad && !conn->kernel_io) {
int pad_bytes = pad = PAD_WORD_LEN - pad;
char bytes[PAD_WORD_LEN];
@@ -590,13 +603,24 @@ iscsi_recv_pdu(iscsi_conn_t *conn, iscsi_hdr_t *hdr,
}
}
- done:
- alarm(0);
- sigaction(SIGALRM, &old, NULL);
+done:
+ if (!conn->kernel_io) {
+ alarm(0);
+ sigaction(SIGALRM, &old, NULL);
+ } else {
+ /* zero Pad area */
+ if (pad)
+ memset(data+dlength, 0, pad);
+ /* finalyze receive transaction */
+ if (conn->recv_pdu_end(conn, pdu_handle)) {
+ failed = 1;
+ }
+ }
+
if (timedout || failed) {
timedout = 0;
return 0;
- } else {
- return h_bytes + ahs_bytes + d_bytes;
}
+
+ return h_bytes + ahs_bytes + d_bytes;
}
diff --git a/usr/login.c b/usr/login.c
index 6c17466..6cf814f 100644
--- a/usr/login.c
+++ b/usr/login.c
@@ -337,9 +337,9 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
&value_end)) {
if (session->type == ISCSI_SESSION_TYPE_NORMAL) {
if (value && (strcmp(value, "Yes") == 0))
- session->initial_r2t = 1;
+ session->initial_r2t_en = 1;
else
- session->initial_r2t = 0;
+ session->initial_r2t_en = 0;
} else
session->irrelevant_keys_bitmap |=
IRRELEVANT_INITIALR2T;
@@ -348,21 +348,21 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
&value_end)) {
if (session->type == ISCSI_SESSION_TYPE_NORMAL) {
if (value && (strcmp(value, "Yes") == 0))
- session->immediate_data = 1;
+ session->imm_data_en = 1;
else
- session->immediate_data = 0;
+ session->imm_data_en = 0;
} else
session->irrelevant_keys_bitmap |=
IRRELEVANT_IMMEDIATEDATA;
text = value_end;
} else if (iscsi_find_key_value("MaxRecvDataSegmentLength", text, end,
&value, &value_end)) {
- conn->max_xmit_data_segment_len = strtoul(value, NULL, 0);
+ conn->max_xmit_dlength = strtoul(value, NULL, 0);
text = value_end;
} else if (iscsi_find_key_value("FirstBurstLength", text, end, &value,
&value_end)) {
if (session->type == ISCSI_SESSION_TYPE_NORMAL)
- session->first_burst_len = strtoul(value, NULL, 0);
+ session->first_burst = strtoul(value, NULL, 0);
else
session->irrelevant_keys_bitmap |=
IRRELEVANT_FIRSTBURSTLENGTH;
@@ -374,7 +374,7 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
* R2Ts, but record it anwyay
*/
if (session->type == ISCSI_SESSION_TYPE_NORMAL)
- session->max_burst_len = strtoul(value, NULL, 0);
+ session->max_burst = strtoul(value, NULL, 0);
else
session->irrelevant_keys_bitmap |=
IRRELEVANT_MAXBURSTLENGTH;
@@ -382,8 +382,8 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
} else if (iscsi_find_key_value("HeaderDigest", text, end, &value,
&value_end)) {
if (strcmp(value, "None") == 0) {
- if (conn->header_digest != ISCSI_DIGEST_CRC32C)
- conn->header_digest = ISCSI_DIGEST_NONE;
+ if (conn->hdrdgst_en != ISCSI_DIGEST_CRC32C)
+ conn->hdrdgst_en = ISCSI_DIGEST_NONE;
else {
log_error("Login negotiation "
"failed, HeaderDigest=CRC32C "
@@ -392,8 +392,8 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
return LOGIN_NEGOTIATION_FAILED;
}
} else if (strcmp(value, "CRC32C") == 0) {
- if (conn->header_digest != ISCSI_DIGEST_NONE)
- conn->header_digest = ISCSI_DIGEST_CRC32C;
+ if (conn->hdrdgst_en != ISCSI_DIGEST_NONE)
+ conn->hdrdgst_en = ISCSI_DIGEST_CRC32C;
else {
log_error("Login negotiation "
"failed, HeaderDigest=None is "
@@ -409,8 +409,8 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
} else if (iscsi_find_key_value("DataDigest", text, end, &value,
&value_end)) {
if (strcmp(value, "None") == 0) {
- if (conn->data_digest != ISCSI_DIGEST_CRC32C)
- conn->data_digest = ISCSI_DIGEST_NONE;
+ if (conn->datadgst_en != ISCSI_DIGEST_CRC32C)
+ conn->datadgst_en = ISCSI_DIGEST_NONE;
else {
log_error("Login negotiation "
"failed, DataDigest=CRC32C "
@@ -418,8 +418,8 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
return LOGIN_NEGOTIATION_FAILED;
}
} else if (strcmp(value, "CRC32C") == 0) {
- if (conn->data_digest != ISCSI_DIGEST_NONE)
- conn->data_digest = ISCSI_DIGEST_CRC32C;
+ if (conn->datadgst_en != ISCSI_DIGEST_NONE)
+ conn->datadgst_en = ISCSI_DIGEST_CRC32C;
else {
log_error("Login negotiation "
"failed, DataDigest=None is "
@@ -460,9 +460,9 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
&value_end)) {
if (session->type == ISCSI_SESSION_TYPE_NORMAL) {
if (value && strcmp(value, "Yes") == 0)
- session->data_pdu_in_order = 1;
+ session->pdu_inorder_en = 1;
else
- session->data_pdu_in_order = 0;
+ session->pdu_inorder_en = 0;
} else
session->irrelevant_keys_bitmap |=
IRRELEVANT_DATAPDUINORDER;
@@ -471,9 +471,9 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
&value, &value_end)) {
if (session->type == ISCSI_SESSION_TYPE_NORMAL)
if (value && strcmp(value, "Yes") == 0)
- session->data_seq_in_order = 1;
+ session->dataseq_inorder_en = 1;
else
- session->data_seq_in_order = 0;
+ session->dataseq_inorder_en = 0;
else
session->irrelevant_keys_bitmap |=
IRRELEVANT_DATASEQUENCEINORDER;
@@ -724,20 +724,20 @@ add_params_normal_session(iscsi_session_t *session, iscsi_hdr_t *pdu,
/* these are only relevant for normal sessions */
if (!iscsi_add_text(pdu, data, max_data_length, "InitialR2T",
- session->initial_r2t ? "Yes" : "No"))
+ session->initial_r2t_en ? "Yes" : "No"))
return 0;
if (!iscsi_add_text(pdu, data, max_data_length,
"ImmediateData",
- session->immediate_data ? "Yes" : "No"))
+ session->imm_data_en ? "Yes" : "No"))
return 0;
- sprintf(value, "%d", session->max_burst_len);
+ sprintf(value, "%d", session->max_burst);
if (!iscsi_add_text(pdu, data, max_data_length,
"MaxBurstLength", value))
return 0;
- sprintf(value, "%d",session->first_burst_len);
+ sprintf(value, "%d",session->first_burst);
if (!iscsi_add_text(pdu, data, max_data_length,
"FirstBurstLength", value))
return 0;
@@ -864,7 +864,7 @@ static int
fill_crc_digest_text(iscsi_conn_t *conn, iscsi_hdr_t *pdu,
char *data, int max_data_length)
{
- switch (conn->header_digest) {
+ switch (conn->hdrdgst_en) {
case ISCSI_DIGEST_NONE:
if (!iscsi_add_text(pdu, data, max_data_length,
"HeaderDigest", "None"))
@@ -888,7 +888,7 @@ fill_crc_digest_text(iscsi_conn_t *conn, iscsi_hdr_t *pdu,
break;
}
- switch (conn->data_digest) {
+ switch (conn->datadgst_en) {
case ISCSI_DIGEST_NONE:
if (!iscsi_add_text(pdu, data, max_data_length,
"DataDigest", "None"))
@@ -939,7 +939,7 @@ fill_op_params_text(iscsi_session_t *session, int cid, iscsi_hdr_t *pdu,
if (!fill_crc_digest_text(conn, pdu, data, max_data_length))
return 0;
- sprintf(value, "%d", conn->max_recv_data_segment_len);
+ sprintf(value, "%d", conn->max_recv_dlength);
if (!iscsi_add_text(pdu, data, max_data_length,
"MaxRecvDataSegmentLength", value))
return 0;
@@ -1039,9 +1039,9 @@ fill_security_params_text(iscsi_session_t *session, int cid, iscsi_hdr_t *pdu,
* keys, or want to offer vendor-specific keys
*/
if (session->type == ISCSI_SESSION_TYPE_DISCOVERY)
- if ((conn->header_digest != ISCSI_DIGEST_NONE) ||
- (conn->data_digest != ISCSI_DIGEST_NONE) ||
- (conn->max_recv_data_segment_len !=
+ if ((conn->hdrdgst_en != ISCSI_DIGEST_NONE) ||
+ (conn->datadgst_en != ISCSI_DIGEST_NONE) ||
+ (conn->max_recv_dlength !=
DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH) ||
session->vendor_specific_keys)
conn->next_stage =
@@ -1365,7 +1365,7 @@ iscsi_login_req(iscsi_session_t *session, iscsi_login_context_t *c)
goto done;
}
- conn->state = STATE_WAIT_PDU_RSP;
+ conn->state = STATE_WAIT_LOGIN_RSP;
return 0;
done: