"Alex Aizman <itn780@yahoo.com>");
MODULE_DESCRIPTION("iSCSI/TCP data-path");
MODULE_LICENSE("GPL");
-
+MODULE_VERSION("0:4.409");
/* #define DEBUG_TCP */
/* #define DEBUG_SCSI */
#define DEBUG_ASSERT
}
static inline void
-iscsi_buf_init_hdr(struct iscsi_conn *conn, struct iscsi_buf *ibuf,
- char *vbuf, u8 *crc)
+iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf,
+ u8* crc)
{
- iscsi_buf_init_virt(ibuf, vbuf, sizeof(struct iscsi_hdr));
- if (conn->hdrdgst_en) {
- crypto_digest_digest(conn->tx_tfm, &ibuf->sg, 1, crc);
- ibuf->sg.length += sizeof(uint32_t);
- }
+ crypto_digest_digest(conn->tx_tfm, &buf->sg, 1, crc);
+ buf->sg.length += sizeof(uint32_t);
}
static void
r2t->sent = 0;
- iscsi_buf_init_hdr(conn, &r2t->headbuf, (char*)hdr,
- (u8 *)dtask->hdrext);
+ iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr,
+ sizeof(struct iscsi_hdr));
r2t->dtask = dtask;
conn->data_copied = 0;
/* read AHS */
- conn->in.ahslen = hdr->hlength*(4*sizeof(__u16));
+ conn->in.ahslen = hdr->hlength * 4;
conn->in.offset += conn->in.ahslen;
conn->in.copy -= conn->in.ahslen;
if (conn->in.copy < 0) {
else
rc = ISCSI_ERR_PROTO;
break;
- case ISCSI_OP_NOOP_IN:
- case ISCSI_OP_TEXT_RSP:
- case ISCSI_OP_LOGOUT_RSP:
- case ISCSI_OP_ASYNC_EVENT:
- case ISCSI_OP_REJECT:
- rc = iscsi_check_assign_cmdsn(session,
- (struct iscsi_nopin*)hdr);
- if (rc)
- break;
-
- /* update ExpStatSN */
- conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
- if (!conn->in.datalen) {
- struct iscsi_mgmt_task *mtask;
-
- rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,
- NULL, 0);
- mtask = (struct iscsi_mgmt_task *)
- session->mgmt_cmds[conn->in.itt -
- ISCSI_MGMT_ITT_OFFSET];
- if (conn->login_mtask != mtask) {
- spin_lock(&session->lock);
- __kfifo_put(session->mgmtpool.queue,
- (void*)&mtask, sizeof(void*));
- spin_unlock(&session->lock);
- }
- }
- break;
default:
rc = ISCSI_ERR_BAD_OPCODE;
break;
switch(conn->in.opcode) {
case ISCSI_OP_LOGIN_RSP:
case ISCSI_OP_TEXT_RSP:
+ case ISCSI_OP_LOGOUT_RSP:
rc = iscsi_check_assign_cmdsn(session,
(struct iscsi_nopin*)hdr);
if (rc)
(void*)&mtask, sizeof(void*));
conn->tmabort_state =
((struct iscsi_tm_rsp *)hdr)->
- response == SCSI_TCP_TM_RESP_COMPLETE ?
+ response == ISCSI_TMF_RSP_COMPLETE ?
TMABORT_SUCCESS:TMABORT_FAILED;
/* unblock eh_abort() */
wake_up(&conn->ehwait);
}
spin_unlock(&session->lock);
break;
+ case ISCSI_OP_NOOP_IN:
+ if (hdr->ttt != ISCSI_RESERVED_TAG) {
+ rc = ISCSI_ERR_PROTO;
+ break;
+ }
+ rc = iscsi_check_assign_cmdsn(session,
+ (struct iscsi_nopin*)hdr);
+ if (rc)
+ break;
+ conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
+
+ if (!conn->in.datalen) {
+ struct iscsi_mgmt_task *mtask;
+
+ rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,
+ NULL, 0);
+ mtask = (struct iscsi_mgmt_task *)
+ session->mgmt_cmds[conn->in.itt -
+ ISCSI_MGMT_ITT_OFFSET];
+ if (conn->login_mtask != mtask) {
+ spin_lock(&session->lock);
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*));
+ spin_unlock(&session->lock);
+ }
+ }
+ break;
default:
rc = ISCSI_ERR_BAD_OPCODE;
break;
}
} else if (conn->in.itt == ISCSI_RESERVED_TAG) {
- if (conn->in.opcode == ISCSI_OP_NOOP_IN && !conn->in.datalen) {
- rc = iscsi_check_assign_cmdsn(session,
+ switch(conn->in.opcode) {
+ case ISCSI_OP_NOOP_IN:
+ if (!conn->in.datalen) {
+ rc = iscsi_check_assign_cmdsn(session,
(struct iscsi_nopin*)hdr);
- if (!rc)
- rc = iscsi_recv_pdu(iscsi_handle(conn),
- hdr, NULL, 0);
- }
- else
+ if (!rc && hdr->ttt != ISCSI_RESERVED_TAG)
+ rc = iscsi_recv_pdu(iscsi_handle(conn),
+ hdr, NULL, 0);
+ } else
+ rc = ISCSI_ERR_PROTO;
+ break;
+ case ISCSI_OP_REJECT:
+ /* we need sth like iscsi_reject_rsp()*/
+ case ISCSI_OP_ASYNC_EVENT:
+ /* we need sth like iscsi_async_event_rsp() */
rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ default:
+ rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ }
} else
rc = ISCSI_ERR_BAD_ITT;
{
int rc;
struct iscsi_conn *conn = rd_desc->arg.data;
- int start = skb_headlen(skb);
int processed;
char pad[ISCSI_PAD_LEN];
struct scatterlist sg;
* Save current SKB and its offset in the corresponding
* connection context.
*/
- conn->in.copy = start - offset;
+ conn->in.copy = skb->len - offset;
conn->in.offset = offset;
conn->in.skb = skb;
conn->in.len = conn->in.copy;
BUG_ON(buf->sent + size > buf->sg.length);
if (size > *count)
size = *count;
- if (buf->sent + size != buf->sg.length)
+ if (buf->sent + size != buf->sg.length || *count != size)
flags |= MSG_MORE;
res = iscsi_send(sk, buf, size, flags);
}
conn->dataout_pdus_cnt++;
- iscsi_buf_init_hdr(conn, &r2t->headbuf, (char*)hdr,
- (u8 *)dtask->hdrext);
+ iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr,
+ sizeof(struct iscsi_hdr));
r2t->dtask = dtask;
hdr->flags = ISCSI_FLAG_CMD_FINAL;
}
- iscsi_buf_init_hdr(conn, &ctask->headbuf, (char*)hdr,
- (u8 *)dtask->hdrext);
+ iscsi_buf_init_virt(&ctask->headbuf, (char*)hdr,
+ sizeof(struct iscsi_hdr));
list_add(&dtask->item, &ctask->dataqueue);
zero_data(ctask->hdr.dlength);
}
- iscsi_buf_init_hdr(conn, &ctask->headbuf, (char*)&ctask->hdr,
- (u8 *)ctask->hdrext);
+ iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr,
+ sizeof(struct iscsi_hdr));
conn->scsicmd_pdus_cnt++;
}
mtask->xmstate &= ~XMSTATE_IMM_HDR;
if (mtask->data_count)
mtask->xmstate |= XMSTATE_IMM_DATA;
+ if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
+ conn->stop_stage != STOP_CONN_RECOVER &&
+ conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &mtask->headbuf,
+ (u8*)mtask->hdrext);
if (iscsi_sendhdr(conn, &mtask->headbuf, mtask->data_count)) {
mtask->xmstate |= XMSTATE_IMM_HDR;
if (mtask->data_count)
handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
ctask->xmstate &= ~XMSTATE_R_HDR;
+ if (conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) {
BUG_ON(ctask->xmstate != XMSTATE_IDLE);
return 0; /* wait for Data-In */
handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
ctask->xmstate &= ~XMSTATE_W_HDR;
+ if (conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) {
ctask->xmstate |= XMSTATE_W_HDR;
return -EAGAIN;
iscsi_unsolicit_data_init(conn, ctask);
BUG_ON(!ctask->dtask);
dtask = ctask->dtask;
-
+ if (conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &ctask->headbuf,
+ (u8*)dtask->hdrext);
ctask->xmstate &= ~XMSTATE_UNS_INIT;
}
if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->data_count)) {
sizeof(void*));
solicit_head_again:
r2t = ctask->r2t;
-
+ if (conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &r2t->headbuf,
+ (u8*)r2t->dtask->hdrext);
if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) {
ctask->xmstate &= ~XMSTATE_SOL_DATA;
ctask->xmstate |= XMSTATE_SOL_HDR;
memcpy(&mtask->hdr, hdr, sizeof(struct iscsi_hdr));
- if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE ||
- conn->stop_stage == STOP_CONN_RECOVER)
- iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr,
+ iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr,
sizeof(struct iscsi_hdr));
- else
- /* this will update header digest */
- iscsi_buf_init_hdr(conn, &mtask->headbuf, (char*)&mtask->hdr,
- (u8 *)mtask->hdrext);
spin_unlock_bh(&session->lock);