Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 124625
b: refs/heads/master
c: 63c62f1
h: refs/heads/master
i:
  124623: 375f1a1
v: v3
  • Loading branch information
Mike Christie authored and James Bottomley committed Dec 29, 2008
1 parent a0c78eb commit 5f260b5
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b29f841378460c37e99a2398d0015d9bd7901a09
refs/heads/master: 63c62f1cb980241513c82cacd5b9f878527c6647
120 changes: 89 additions & 31 deletions trunk/drivers/scsi/iscsi_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ iscsi_tcp_data_recv_prep(struct iscsi_tcp_conn *tcp_conn)
struct iscsi_conn *conn = tcp_conn->iscsi_conn;
struct hash_desc *rx_hash = NULL;

if (conn->datadgst_en)
if (conn->datadgst_en &
!(conn->session->tt->caps & CAP_DIGEST_OFFLOAD))
rx_hash = &tcp_conn->rx_hash;

iscsi_segment_init_linear(&tcp_conn->in.segment,
Expand Down Expand Up @@ -774,7 +775,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
* we move on to the next scatterlist entry and
* update the digest per-entry.
*/
if (conn->datadgst_en)
if (conn->datadgst_en &&
!(conn->session->tt->caps & CAP_DIGEST_OFFLOAD))
rx_hash = &tcp_conn->rx_hash;

debug_tcp("iscsi_tcp_begin_data_in(%p, offset=%d, "
Expand Down Expand Up @@ -902,34 +904,52 @@ iscsi_tcp_hdr_recv_done(struct iscsi_tcp_conn *tcp_conn,
* and go back for more. */
if (conn->hdrdgst_en) {
if (segment->digest_len == 0) {
/*
* Even if we offload the digest processing we
* splice it in so we can increment the skb/segment
* counters in preparation for the data segment.
*/
iscsi_tcp_segment_splice_digest(segment,
segment->recv_digest);
return 0;
}
iscsi_tcp_dgst_header(&tcp_conn->rx_hash, hdr,
segment->total_copied - ISCSI_DIGEST_SIZE,
segment->digest);

if (!iscsi_tcp_dgst_verify(tcp_conn, segment))
return ISCSI_ERR_HDR_DGST;
if (!(conn->session->tt->caps & CAP_DIGEST_OFFLOAD)) {
iscsi_tcp_dgst_header(&tcp_conn->rx_hash, hdr,
segment->total_copied - ISCSI_DIGEST_SIZE,
segment->digest);

if (!iscsi_tcp_dgst_verify(tcp_conn, segment))
return ISCSI_ERR_HDR_DGST;
}
}

tcp_conn->in.hdr = hdr;
return iscsi_tcp_hdr_dissect(conn, hdr);
}

inline int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn)
{
return tcp_conn->in.segment.done == iscsi_tcp_hdr_recv_done;
}

enum {
ISCSI_TCP_SEGMENT_DONE, /* curr seg has been processed */
ISCSI_TCP_SKB_DONE, /* skb is out of data */
ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */
ISCSI_TCP_SUSPENDED, /* conn is suspended */
};

/**
* iscsi_tcp_recv - TCP receive in sendfile fashion
* @rd_desc: read descriptor
* @skb: socket buffer
* iscsi_tcp_recv_skb - Process skb
* @conn: iscsi connection
* @skb: network buffer with header and/or data segment
* @offset: offset in skb
* @len: skb->len - offset
**/
static int
iscsi_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
unsigned int offset, size_t len)
* @offload: bool indicating if transfer was offloaded
*/
int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb,
unsigned int offset, bool offloaded, int *status)
{
struct iscsi_conn *conn = rd_desc->arg.data;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct iscsi_segment *segment = &tcp_conn->in.segment;
struct skb_seq_state seq;
Expand All @@ -940,9 +960,15 @@ iscsi_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,

if (unlikely(conn->suspend_rx)) {
debug_tcp("conn %d Rx suspended!\n", conn->id);
*status = ISCSI_TCP_SUSPENDED;
return 0;
}

if (offloaded) {
segment->total_copied = segment->total_size;
goto segment_done;
}

skb_prepare_seq_read(skb, offset, skb->len, &seq);
while (1) {
unsigned int avail;
Expand All @@ -952,7 +978,9 @@ iscsi_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
if (avail == 0) {
debug_tcp("no more data avail. Consumed %d\n",
consumed);
break;
*status = ISCSI_TCP_SKB_DONE;
skb_abort_seq_read(&seq);
goto skb_done;
}
BUG_ON(segment->copied >= segment->size);

Expand All @@ -962,25 +990,55 @@ iscsi_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
consumed += rc;

if (segment->total_copied >= segment->total_size) {
debug_tcp("segment done\n");
rc = segment->done(tcp_conn, segment);
if (rc != 0) {
skb_abort_seq_read(&seq);
goto error;
}

/* The done() functions sets up the
* next segment. */
skb_abort_seq_read(&seq);
goto segment_done;
}
}
skb_abort_seq_read(&seq);

segment_done:
*status = ISCSI_TCP_SEGMENT_DONE;
debug_tcp("segment done\n");
rc = segment->done(tcp_conn, segment);
if (rc != 0) {
*status = ISCSI_TCP_CONN_ERR;
debug_tcp("Error receiving PDU, errno=%d\n", rc);
iscsi_conn_failure(conn, rc);
return 0;
}
/* The done() functions sets up the next segment. */

skb_done:
conn->rxdata_octets += consumed;
return consumed;
}
EXPORT_SYMBOL_GPL(iscsi_tcp_recv_skb);

error:
debug_tcp("Error receiving PDU, errno=%d\n", rc);
iscsi_conn_failure(conn, rc);
return 0;
/**
* iscsi_tcp_recv - TCP receive in sendfile fashion
* @rd_desc: read descriptor
* @skb: socket buffer
* @offset: offset in skb
* @len: skb->len - offset
**/
static int
iscsi_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
unsigned int offset, size_t len)
{
struct iscsi_conn *conn = rd_desc->arg.data;
unsigned int consumed, total_consumed = 0;
int status;

debug_tcp("in %d bytes\n", skb->len - offset);

do {
status = 0;
consumed = iscsi_tcp_recv_skb(conn, skb, offset, 0, &status);
offset += consumed;
total_consumed += consumed;
} while (consumed != 0 && status != ISCSI_TCP_SKB_DONE);

debug_tcp("read %d bytes status %d\n", skb->len - offset, status);
return total_consumed;
}

static void
Expand Down
5 changes: 3 additions & 2 deletions trunk/include/scsi/iscsi_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,9 @@ enum iscsi_host_param {
#define CAP_TEXT_NEGO 0x80
#define CAP_MARKERS 0x100
#define CAP_FW_DB 0x200
#define CAP_SENDTARGETS_OFFLOAD 0x400
#define CAP_DATA_PATH_OFFLOAD 0x800
#define CAP_SENDTARGETS_OFFLOAD 0x400 /* offload discovery process */
#define CAP_DATA_PATH_OFFLOAD 0x800 /* offload entire IO path */
#define CAP_DIGEST_OFFLOAD 0x1000 /* offload hdr and data digests */

/*
* These flags describes reason of stop_conn() call
Expand Down

0 comments on commit 5f260b5

Please sign in to comment.