This patch breaks the dependence of iscsi login/text code on the static structures within struct iscsi_conn. Most of the changes are concerned with the following two issues: 1. changed function prototypes, to include pointers to the relevant pdu or bhs structures or data buffers. These changes ultimately start with the new prototype of cmnd_execute(), to which two new arguments: struct iscsi_pdu *req_pdu, *rsp_pdu are added. All other functions called from this point and on are changed according to their needs. 2. struct login_state is defined and added to iscsi_conn. It encapsulates login/text specific data and status. All login/text data buffers are copied to the buffers internal to this new structure. When necessary, data from multiple pdus is accumulated in a single request buffer, and conversely, a long response buffer can be sent piecewise within multiple pdus. These changes enable using dynamically allocated pdus and their immediate release after processing by the login/text code. Such scheme is to be employed by the new iser code, i.e. it's the first step towards its integration. Verified: discovery and login (auth=None, auth=CHAP) Signed-off-by: Alexander Nezhinsky <alexandern at voltaire.com> --- usr/iscsi/conn.c | 21 +++ usr/iscsi/iscsi_proto.h | 2 +- usr/iscsi/iscsid.c | 313 +++++++++++++++++++++++++++++++---------------- usr/iscsi/iscsid.h | 25 ++++- 4 files changed, 254 insertions(+), 107 deletions(-) diff --git a/usr/iscsi/conn.c b/usr/iscsi/conn.c index ba7a58f..afc6dd9 100644 --- a/usr/iscsi/conn.c +++ b/usr/iscsi/conn.c @@ -56,6 +56,14 @@ int conn_init(struct iscsi_connection *conn) } conn->rsp_buffer_size = INCOMING_BUFSIZE; + conn->login.rsp_buf = malloc(INCOMING_BUFSIZE); + if (!conn->login.rsp_buf) { + free(conn->req_buffer); + free(conn->rsp_buffer); + return -ENOMEM; + } + conn->login.rsp_buf_sz = INCOMING_BUFSIZE; + conn->refcount = 1; conn->state = STATE_FREE; param_set_defaults(conn->session_param, session_keys); @@ -75,6 +83,10 @@ void conn_exit(struct iscsi_connection *conn) free(conn->req_buffer); free(conn->rsp_buffer); free(conn->initiator); + if (conn->login.req_buf) + free(conn->login.req_buf); + if (conn->login.rsp_buf) + free(conn->login.rsp_buf); if (session) session_put(session); @@ -175,6 +187,15 @@ void conn_close(struct iscsi_connection *conn) continue; iscsi_free_task(task); } + + if (conn->login.req_buf) { + free(conn->login.req_buf); + conn->login.req_buf = NULL; + } + if (conn->login.rsp_buf) { + free(conn->login.rsp_buf); + conn->login.rsp_buf = NULL; + } done: conn_put(conn); } diff --git a/usr/iscsi/iscsi_proto.h b/usr/iscsi/iscsi_proto.h index d5e58df..17e481f 100644 --- a/usr/iscsi/iscsi_proto.h +++ b/usr/iscsi/iscsi_proto.h @@ -589,7 +589,7 @@ struct iscsi_reject { #define VALUE_MAXLEN 255 #define TARGET_NAME_MAXLEN VALUE_MAXLEN -#define DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH 8192 +#define LOGIN_MAX_RECV_DATA_SEG_LEN 8192 /************************* RFC 3720 End *****************************/ diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c index facc999..306e15a 100644 --- a/usr/iscsi/iscsid.c +++ b/usr/iscsi/iscsid.c @@ -99,12 +99,10 @@ static struct iscsi_key login_keys[] = { char *text_key_find(struct iscsi_connection *conn, char *searchKey) { - char *data, *key, *value; - int keylen, datasize; - - keylen = strlen(searchKey); - data = conn->req.data; - datasize = conn->req.datasize; + char *data = conn->login.req_buf; + int datasize = conn->login.req_buf_sz; + int keylen = strlen(searchKey); + char *key, *value; while (1) { for (key = data; datasize > 0 && *data != '='; data++, datasize--) @@ -154,6 +152,22 @@ static char *next_key(char **data, int *datasize, char **value) return key; } +static char *buffer_resize(char **buffer, int *size, int add_size) +{ + int new_size = *size + add_size; + char *new_ptr; + + if (!*size) + new_ptr = malloc(new_size); + else + new_ptr = realloc(*buffer, new_size); + if (new_ptr) { + *buffer = new_ptr; + *size = new_size; + } + return new_ptr; +} + void text_key_add(struct iscsi_connection *conn, char *key, char *value) { int keylen = strlen(key); @@ -165,34 +179,26 @@ 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 = conn->rsp_buffer_size; - - if (!conn->rsp.datasize) - conn->rsp.data = conn->rsp_buffer; - - buffer = conn->rsp_buffer; + max_len = LOGIN_MAX_RECV_DATA_SEG_LEN; - if (conn->rsp.datasize + len > max_len && + if (conn->login.rsp_data_sz + len > max_len && (conn->req.bhs.opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_TEXT) goto drop; - 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 + if (conn->login.rsp_data_sz + len > conn->login.rsp_buf_sz) { + buffer = buffer_resize(&conn->login.rsp_buf, + &conn->login.rsp_buf_sz, + max_len); + if (!buffer) goto drop; } - - buffer += conn->rsp.datasize; - conn->rsp.datasize += len; - + buffer = conn->login.rsp_buf + conn->login.rsp_data_sz; strcpy(buffer, key); buffer += keylen; *buffer++ = '='; strcpy(buffer, value); + conn->login.rsp_data_sz += len; + dprintf("%s=%s (tx)\n", key, value); return; drop: log_warning("Dropping key (%s=%s)", key, value); @@ -204,16 +210,14 @@ static void text_key_add_reject(struct iscsi_connection *conn, char *key) text_key_add(conn, key, "Reject"); } -static void text_scan_security(struct iscsi_connection *conn) +static void text_scan_security(struct iscsi_connection *conn, + struct iscsi_login_rsp *rsp) { - struct iscsi_login_rsp *rsp = (struct iscsi_login_rsp *)&conn->rsp.bhs; - char *key, *value, *data, *nextValue; - int datasize; + char *req_buf = conn->login.req_buf; + int req_size = conn->login.req_buf_sz; + char *key, *value, *nextValue; - data = conn->req.data; - datasize = conn->req.datasize; - - while ((key = next_key(&data, &datasize, &value))) { + while ((key = next_key(&req_buf, &req_size, &value))) { if (!(param_index_by_name(key, login_keys) < 0)) ; else if (!strcmp(key, "AuthMethod")) { @@ -249,10 +253,10 @@ static void text_scan_security(struct iscsi_connection *conn) } } -static void login_security_done(struct iscsi_connection *conn) +static void login_security_done(struct iscsi_connection *conn, + struct iscsi_login *req, + struct iscsi_login_rsp *rsp) { - struct iscsi_login *req = (struct iscsi_login *)&conn->req.bhs; - struct iscsi_login_rsp *rsp = (struct iscsi_login_rsp *) &conn->rsp.bhs; struct iscsi_session *session; if (!conn->tid) @@ -299,16 +303,16 @@ static void login_security_done(struct iscsi_connection *conn) } } -static void text_scan_login(struct iscsi_connection *conn) +static void text_scan_login(struct iscsi_connection *conn, + struct iscsi_login_rsp *rsp) { - char *key, *value, *data; - int datasize, idx, is_rdma = 0; - struct iscsi_login_rsp *rsp = (struct iscsi_login_rsp *)&conn->rsp.bhs; + char *key, *value; + int idx, is_rdma = 0; + char *req_buf = conn->login.req_buf; + int req_size = conn->login.req_buf_sz; - data = conn->req.data; - datasize = conn->req.datasize; - - while ((key = next_key(&data, &datasize, &value))) { + while ((key = next_key(&req_buf, &req_size, &value))) { + dprintf("%s=%s (rx)\n", key, value); if (!(param_index_by_name(key, login_keys) < 0)) ; else if (!strcmp(key, "AuthMethod")) @@ -424,10 +428,10 @@ static int text_check_param(struct iscsi_connection *conn) return cnt; } -static void login_start(struct iscsi_connection *conn) +static void login_start(struct iscsi_connection *conn, + struct iscsi_login *req, + struct iscsi_login_rsp *rsp) { - struct iscsi_login *req = (struct iscsi_login *)&conn->req.bhs; - struct iscsi_login_rsp *rsp = (struct iscsi_login_rsp *)&conn->rsp.bhs; char *name, *alias, *session_type, *target_name; struct iscsi_target *target; @@ -541,6 +545,26 @@ static void login_start(struct iscsi_connection *conn) text_key_add(conn, "TargetPortalGroupTag", "1"); } +static void login_cleanup(struct iscsi_connection *conn) +{ + int max_len = conn->session_param[ISCSI_PARAM_MAX_XMIT_DLENGTH].val; + + if (conn->login.req_buf) { + free(conn->login.req_buf); + conn->login.req_buf = NULL; + conn->login.req_buf_sz = 0; + } + conn->login.req_data_sz = 0; + /* leave enough space for text responces */ + if (conn->login.rsp_buf && conn->login.rsp_buf_sz > max_len) { + conn->login.rsp_buf = realloc(conn->login.rsp_buf, max_len); + conn->login.rsp_buf_sz = max_len; + } + conn->login.rsp_data_sz = 0; + conn->login.rsp_offset = 0; + conn->login.status = LOGIN_NONE; +} + static void login_finish(struct iscsi_connection *conn) { struct iscsi_login_rsp *rsp = (struct iscsi_login_rsp *) &conn->rsp.bhs; @@ -612,9 +636,12 @@ static int cmnd_exec_auth(struct iscsi_connection *conn) return res; } -static void cmnd_reject(struct iscsi_connection *conn, uint8_t reason) +static void cmnd_reject(struct iscsi_connection *conn, + struct iscsi_pdu *req_pdu, + struct iscsi_pdu *rsp_pdu, + uint8_t reason) { - struct iscsi_reject *rsp = (struct iscsi_reject *)&conn->rsp.bhs; + struct iscsi_reject *rsp = (struct iscsi_reject *)&rsp_pdu->bhs; memset(rsp, 0, BHS_SIZE); @@ -627,24 +654,59 @@ static void cmnd_reject(struct iscsi_connection *conn, uint8_t reason) rsp->exp_cmdsn = cpu_to_be32(conn->exp_cmd_sn); rsp->max_cmdsn = cpu_to_be32(conn->max_cmd_sn); - conn->rsp.data = conn->rsp_buffer; - conn->rsp.datasize = BHS_SIZE; - memcpy(conn->rsp.data, &conn->req.bhs, BHS_SIZE); + memcpy(conn->login.rsp_buf, &req_pdu->bhs, BHS_SIZE); + rsp_pdu->datasize = BHS_SIZE; } -static void cmnd_exec_login(struct iscsi_connection *conn) +static int add_req_login_text_data(struct iscsi_connection *conn, + char *req_data, + int data_size) { - struct iscsi_login *req = (struct iscsi_login *)&conn->req.bhs; - struct iscsi_login_rsp *rsp = (struct iscsi_login_rsp *)&conn->rsp.bhs; + char *buffer; + + if (!data_size) + return 0; + if (conn->login.req_data_sz + data_size > conn->login.req_buf_sz) { + buffer = buffer_resize(&conn->login.req_buf, + &conn->login.req_buf_sz, + INCOMING_BUFSIZE); + if (!buffer) + return -ENOMEM; + } + buffer = conn->login.req_buf + conn->login.req_data_sz; + memcpy(buffer, req_data, data_size); + conn->login.req_data_sz += data_size; + return 0; +} + +static void cmnd_exec_login(struct iscsi_connection *conn, + struct iscsi_pdu *req_pdu, + struct iscsi_pdu *rsp_pdu) +{ + struct iscsi_login *req = (struct iscsi_login *)&req_pdu->bhs; + struct iscsi_login_rsp *rsp = (struct iscsi_login_rsp *)&rsp_pdu->bhs; int stay = 0, nsg_disagree = 0; memset(rsp, 0, BHS_SIZE); if ((req->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_LOGIN || !(req->opcode & ISCSI_OP_IMMEDIATE)) { - cmnd_reject(conn, ISCSI_REASON_PROTOCOL_ERROR); + cmnd_reject(conn, req_pdu, rsp_pdu, + ISCSI_REASON_PROTOCOL_ERROR); + return; + } + + if (add_req_login_text_data(conn, req_pdu->data, req_pdu->datasize)) { + rsp->status_class = ISCSI_STATUS_CLS_TARGET_ERR; + rsp->status_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES; + conn->state = STATE_EXIT; return; } + if (conn->login.status != LOGIN_IN_PROGRESS) { + conn->login.rsp_data_sz = 0; + conn->login.rsp_offset = 0; + } + rsp->opcode = ISCSI_OP_LOGIN_RSP; rsp->max_version = ISCSI_DRAFT20_VERSION; rsp->active_version = ISCSI_DRAFT20_VERSION; @@ -667,12 +729,12 @@ static void cmnd_exec_login(struct iscsi_connection *conn) switch (conn->state) { case STATE_FREE: conn->state = STATE_SECURITY; - login_start(conn); + login_start(conn, req, rsp); if (rsp->status_class) return; /* fall through */ case STATE_SECURITY: - text_scan_security(conn); + text_scan_security(conn, rsp); if (rsp->status_class) return; if (conn->auth_method != AUTH_NONE) { @@ -705,18 +767,18 @@ static void cmnd_exec_login(struct iscsi_connection *conn) case STATE_FREE: conn->state = STATE_LOGIN; - login_start(conn); + login_start(conn, req, rsp); if (account_available(conn->tid, AUTH_DIR_INCOMING)) goto auth_err; if (rsp->status_class) return; - text_scan_login(conn); + text_scan_login(conn, rsp); if (rsp->status_class) return; stay = text_check_param(conn); break; case STATE_LOGIN: - text_scan_login(conn); + text_scan_login(conn, rsp); if (rsp->status_class) return; stay = text_check_param(conn); @@ -741,7 +803,7 @@ static void cmnd_exec_login(struct iscsi_connection *conn) case STATE_SECURITY: case STATE_SECURITY_DONE: conn->state = STATE_SECURITY_LOGIN; - login_security_done(conn); + login_security_done(conn, req, rsp); break; default: goto init_err; @@ -757,7 +819,7 @@ static void cmnd_exec_login(struct iscsi_connection *conn) break; } conn->state = STATE_SECURITY_FULL; - login_security_done(conn); + login_security_done(conn, req, rsp); break; case STATE_LOGIN: if (stay) @@ -780,6 +842,11 @@ static void cmnd_exec_login(struct iscsi_connection *conn) rsp->flags |= nsg | (stay ? 0 : ISCSI_FLAG_LOGIN_TRANSIT); } + conn->login.req_data_sz = 0; /* done with the request */ + if (conn->login.status == LOGIN_NONE) + conn->login.status = LOGIN_LAST_TX; + rsp_pdu->datasize = conn->login.rsp_data_sz; /* single response */ + memcpy(rsp->isid, conn->isid, sizeof(rsp->isid)); rsp->tsih = conn->tsih; rsp->statsn = cpu_to_be32(conn->stat_sn++); @@ -805,10 +872,11 @@ static void text_scan_text(struct iscsi_connection *conn) char *key, *value, *data; int datasize; - data = conn->req.data; - datasize = conn->req.datasize; + data = conn->login.req_buf; + datasize = conn->login.req_buf_sz; while ((key = next_key(&data, &datasize, &value))) { + dprintf("%s=%s (rx)\n", key, value); if (!strcmp(key, "SendTargets")) { struct sockaddr_storage ss; socklen_t slen, blen; @@ -855,60 +923,74 @@ static void text_scan_text(struct iscsi_connection *conn) } } -static void cmnd_exec_text(struct iscsi_connection *conn) +static void cmnd_exec_text(struct iscsi_connection *conn, + struct iscsi_pdu *req_pdu, + struct iscsi_pdu *rsp_pdu) { - struct iscsi_text *req = (struct iscsi_text *)&conn->req.bhs; - struct iscsi_text_rsp *rsp = (struct iscsi_text_rsp *)&conn->rsp.bhs; + struct iscsi_text *req = (struct iscsi_text *)&req_pdu->bhs; + struct iscsi_text_rsp *rsp = (struct iscsi_text_rsp *)&rsp_pdu->bhs; int max_len = conn->session_param[ISCSI_PARAM_MAX_XMIT_DLENGTH].val; + int rsp_left; - memset(rsp, 0, BHS_SIZE); + dprintf("Text request: %d %d\n", conn->state, max_len); + + if (add_req_login_text_data(conn, req_pdu->data, req_pdu->datasize)) { + cmnd_reject(conn, req_pdu, rsp_pdu, + ISCSI_REASON_OUT_OF_RESOURCES); + return; + } + if (conn->login.status != TEXT_IN_PROGRESS) { + conn->login.rsp_data_sz = 0; + conn->login.rsp_offset = 0; + } + + memset(rsp, 0, BHS_SIZE); rsp->opcode = ISCSI_OP_TEXT_RSP; rsp->itt = req->itt; conn->exp_cmd_sn = be32_to_cpu(req->cmdsn); if (!(req->opcode & ISCSI_OP_IMMEDIATE)) conn->exp_cmd_sn++; - if (be32_to_cpu(req->ttt) == ISCSI_RESERVED_TAG) { - conn->text_datasize = 0; - + if (be32_to_cpu(req->ttt) == ISCSI_RESERVED_TAG) { /* new request */ text_scan_text(conn); - - conn->text_rsp_buffer = conn->rsp_buffer; - conn->text_datasize = conn->rsp.datasize; - - if (conn->text_datasize > max_len) { + if (conn->login.rsp_data_sz <= max_len) + conn->ttt = ISCSI_RESERVED_TAG; + else { 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)) { - cmnd_reject(conn, ISCSI_REASON_INVALID_PDU_FIELD); + } + } else if (conn->login.status != TEXT_IN_PROGRESS || + conn->ttt != be32_to_cpu(req->ttt)) { + cmnd_reject(conn, req_pdu, rsp_pdu, + ISCSI_REASON_INVALID_PDU_FIELD); return; } - if (conn->text_datasize <= max_len) { + rsp_left = conn->login.rsp_data_sz - conn->login.rsp_offset; + if (rsp_left <= max_len) { + rsp_pdu->datasize = rsp_left; rsp->flags = ISCSI_FLAG_CMD_FINAL; - conn->ttt = ISCSI_RESERVED_TAG; + conn->login.status = TEXT_LAST_TX; + conn->login.req_data_sz = 0; /* done with the request */ + } else { + rsp_pdu->datasize = max_len; + conn->login.status = TEXT_IN_PROGRESS; } - 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); } -static void cmnd_exec_logout(struct iscsi_connection *conn) +static void cmnd_exec_logout(struct iscsi_connection *conn, + struct iscsi_pdu *req_pdu, + struct iscsi_pdu *rsp_pdu) { - struct iscsi_logout *req = (struct iscsi_logout *)&conn->req.bhs; - struct iscsi_logout_rsp *rsp = (struct iscsi_logout_rsp *)&conn->rsp.bhs; + struct iscsi_logout *req = (struct iscsi_logout *)&req_pdu->bhs; + struct iscsi_logout_rsp *rsp = (struct iscsi_logout_rsp *)&rsp_pdu->bhs; memset(rsp, 0, BHS_SIZE); rsp->opcode = ISCSI_OP_LOGOUT_RSP; @@ -923,28 +1005,46 @@ static void cmnd_exec_logout(struct iscsi_connection *conn) rsp->max_cmdsn = cpu_to_be32(conn->max_cmd_sn); } -static int cmnd_execute(struct iscsi_connection *conn) +static void finalize_text_rsp_pdu(struct iscsi_connection *conn, + struct iscsi_pdu *rsp_pdu) +{ + struct iscsi_hdr *rsp = &rsp_pdu->bhs; + + rsp->hlength = rsp_pdu->ahssize / 4; + + rsp_pdu->data = conn->login.rsp_buf + conn->login.rsp_offset; + conn->login.rsp_offset += rsp_pdu->datasize; + hton24(rsp->dlength, rsp_pdu->datasize); +} + +static int cmnd_execute(struct iscsi_connection *conn, + struct iscsi_pdu *req_pdu, + struct iscsi_pdu *rsp_pdu) { + struct iscsi_hdr *req = &req_pdu->bhs; + struct iscsi_hdr *rsp = &rsp_pdu->bhs; int res = 0; - switch (conn->req.bhs.opcode & ISCSI_OPCODE_MASK) { + switch (req->opcode & ISCSI_OPCODE_MASK) { case ISCSI_OP_LOGIN: - cmnd_exec_login(conn); - conn->rsp.bhs.hlength = conn->rsp.ahssize / 4; - hton24(conn->rsp.bhs.dlength, conn->rsp.datasize); + cmnd_exec_login(conn, req_pdu, rsp_pdu); + finalize_text_rsp_pdu(conn, rsp_pdu); + /* clean up on error, otherwise decided internally */ + if (conn->state == STATE_EXIT) + login_cleanup(conn); break; case ISCSI_OP_TEXT: - cmnd_exec_text(conn); - conn->rsp.bhs.hlength = conn->rsp.ahssize / 4; - hton24(conn->rsp.bhs.dlength, conn->rsp.datasize); + cmnd_exec_text(conn, req_pdu, rsp_pdu); + finalize_text_rsp_pdu(conn, rsp_pdu); break; case ISCSI_OP_LOGOUT: - cmnd_exec_logout(conn); - conn->rsp.bhs.hlength = conn->rsp.ahssize / 4; - hton24(conn->rsp.bhs.dlength, conn->rsp.datasize); + cmnd_exec_logout(conn, req_pdu, rsp_pdu); + rsp->hlength = rsp_pdu->ahssize / 4; + hton24(rsp->dlength, rsp_pdu->datasize); break; default: - cmnd_reject(conn, ISCSI_REASON_CMD_NOT_SUPPORTED); + cmnd_reject(conn, req_pdu, rsp_pdu, + ISCSI_REASON_CMD_NOT_SUPPORTED); res = 1; break; } @@ -964,11 +1064,16 @@ static void cmnd_finish(struct iscsi_connection *conn) case STATE_SECURITY_FULL: /* fall through */ case STATE_LOGIN_FULL: + login_cleanup(conn); if (conn->session_type == SESSION_NORMAL) conn->state = STATE_KERNEL; else conn->state = STATE_FULL; break; + case STATE_FULL: + if (conn->login.status == TEXT_LAST_TX) + login_cleanup(conn); + break; } } @@ -2066,7 +2171,7 @@ again: } else { conn_write_pdu(conn); conn->tp->ep_event_modify(conn, EPOLLOUT); - ret = cmnd_execute(conn); + ret = cmnd_execute(conn, &conn->req, &conn->rsp); if (ret) conn->state = STATE_CLOSE; } diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h index 35bb068..1de8580 100644 --- a/usr/iscsi/iscsid.h +++ b/usr/iscsi/iscsid.h @@ -132,6 +132,27 @@ struct iscsi_task { unsigned long extdata[0]; }; +enum login_status { + LOGIN_NONE = 0, + LOGIN_IN_PROGRESS, + LOGIN_LAST_TX, + TEXT_IN_PROGRESS, + TEXT_LAST_TX +}; + +struct login_state { + char *req_buf; + int req_buf_sz; + int req_data_sz; + + char *rsp_buf; + int rsp_buf_sz; + int rsp_data_sz; + int rsp_offset; + + enum login_status status; +}; + struct iscsi_connection { int state; @@ -173,8 +194,8 @@ struct iscsi_connection { int tx_size; uint32_t ttt; - int text_datasize; - void *text_rsp_buffer; + + struct login_state login; struct iscsi_task *rx_task; struct iscsi_task *tx_task; -- 1.6.5 -- 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 |