提交 dbdb016d 编写于 作者: M Mike Christie 提交者: James Bottomley

[SCSI] iscsi_tcp: fix handling of data buffer padding

If we got the padding, data and header in different skbs,
we were not handling the padding correctly because we attributed it
to the data's skb. This resulted in the initiator reading from
pad bytes + skb offset instead of the correct offset.

If you could not connect with the open solaris target, this
will fix the lock up problem you were hitting.
Signed-off-by: NMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 1548271e
......@@ -896,11 +896,27 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
}
}
if (tcp_conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
if (tcp_conn->in_progress == IN_PROGRESS_DDIGEST_RECV &&
tcp_conn->in.copy) {
uint32_t recv_digest;
debug_tcp("extra data_recv offset %d copy %d\n",
tcp_conn->in.offset, tcp_conn->in.copy);
if (!tcp_conn->data_copied) {
if (tcp_conn->in.padding) {
debug_tcp("padding -> %d\n",
tcp_conn->in.padding);
memset(pad, 0, tcp_conn->in.padding);
sg_init_one(&sg, pad, tcp_conn->in.padding);
crypto_hash_update(&tcp_conn->rx_hash,
&sg, sg.length);
}
crypto_hash_final(&tcp_conn->rx_hash,
(u8 *) &tcp_conn->in.datadgst);
debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
}
rc = iscsi_tcp_copy(conn, sizeof(uint32_t));
if (rc) {
if (rc == -EAGAIN)
......@@ -925,8 +941,7 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
}
if (tcp_conn->in_progress == IN_PROGRESS_DATA_RECV &&
tcp_conn->in.copy) {
tcp_conn->in.copy) {
debug_tcp("data_recv offset %d copy %d\n",
tcp_conn->in.offset, tcp_conn->in.copy);
......@@ -937,24 +952,32 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
return 0;
}
tcp_conn->in.copy -= tcp_conn->in.padding;
tcp_conn->in.offset += tcp_conn->in.padding;
if (conn->datadgst_en) {
if (tcp_conn->in.padding) {
debug_tcp("padding -> %d\n",
tcp_conn->in.padding);
memset(pad, 0, tcp_conn->in.padding);
sg_init_one(&sg, pad, tcp_conn->in.padding);
crypto_hash_update(&tcp_conn->rx_hash,
&sg, sg.length);
}
crypto_hash_final(&tcp_conn->rx_hash,
(u8 *) &tcp_conn->in.datadgst);
debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
if (tcp_conn->in.padding)
tcp_conn->in_progress = IN_PROGRESS_PAD_RECV;
else if (conn->datadgst_en)
tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
tcp_conn->data_copied = 0;
} else
else
tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
tcp_conn->data_copied = 0;
}
if (tcp_conn->in_progress == IN_PROGRESS_PAD_RECV &&
tcp_conn->in.copy) {
int copylen = min(tcp_conn->in.padding - tcp_conn->data_copied,
tcp_conn->in.copy);
tcp_conn->in.copy -= copylen;
tcp_conn->in.offset += copylen;
tcp_conn->data_copied += copylen;
if (tcp_conn->data_copied != tcp_conn->in.padding)
tcp_conn->in_progress = IN_PROGRESS_PAD_RECV;
else if (conn->datadgst_en)
tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
else
tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
tcp_conn->data_copied = 0;
}
debug_tcp("f, processed %d from out of %d padding %d\n",
......
......@@ -29,6 +29,7 @@
#define IN_PROGRESS_HEADER_GATHER 0x1
#define IN_PROGRESS_DATA_RECV 0x2
#define IN_PROGRESS_DDIGEST_RECV 0x3
#define IN_PROGRESS_PAD_RECV 0x4
/* xmit state machine */
#define XMSTATE_IDLE 0x0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册