From: James Bottomley Date: Sat, 23 Sep 2006 20:33:43 +0000 (-0500) Subject: Merge mulgrave-w:git/scsi-misc-2.6 X-Git-Tag: v2.6.19-rc1~1266^2~19 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9802cd9574a80444e689c7525627b40d7dc3a06;p=linux-2.6 Merge mulgrave-w:git/scsi-misc-2.6 Conflicts: drivers/scsi/iscsi_tcp.c drivers/scsi/iscsi_tcp.h Pretty horrible merge between crypto hash consolidation and crypto_digest_...->crypto_hash_... conversion Signed-off-by: James Bottomley --- c9802cd9574a80444e689c7525627b40d7dc3a06 diff --cc drivers/scsi/iscsi_tcp.c index 66a1ae1d69,d91e8949c7..0a9dbc5966 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@@ -108,12 -107,9 +107,9 @@@ iscsi_hdr_digest(struct iscsi_conn *con u8* crc) { struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct hash_desc desc; - desc.tfm = tcp_conn->tx_tfm; - desc.flags = 0; - crypto_hash_digest(&desc, &buf->sg, buf->sg.length, crc); - buf->sg.length += sizeof(uint32_t); - crypto_digest_digest(tcp_conn->tx_tfm, &buf->sg, 1, crc); ++ crypto_hash_digest(&tcp_conn->tx_hash, &buf->sg, buf->sg.length, crc); + buf->sg.length = tcp_conn->hdr_size; } static inline int @@@ -461,9 -468,7 +468,8 @@@ iscsi_tcp_hdr_recv(struct iscsi_conn *c sg_init_one(&sg, (u8 *)hdr, sizeof(struct iscsi_hdr) + ahslen); - desc.tfm = tcp_conn->rx_tfm; - desc.flags = 0; - crypto_hash_digest(&desc, &sg, sg.length, (u8 *)&cdgst); - crypto_digest_digest(tcp_conn->rx_tfm, &sg, 1, (u8 *)&cdgst); ++ crypto_hash_digest(&tcp_conn->rx_hash, &sg, sg.length, ++ (u8 *)&cdgst); rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) + ahslen); if (cdgst != rdgst) { @@@ -672,15 -675,15 +676,15 @@@ iscsi_tcp_copy(struct iscsi_conn *conn } static inline void - partial_sg_digest_update(struct iscsi_tcp_conn *tcp_conn, - struct scatterlist *sg, int offset, int length) -partial_sg_digest_update(struct crypto_tfm *tfm, struct scatterlist *sg, ++partial_sg_digest_update(struct hash_desc *desc, struct scatterlist *sg, + int offset, int length) { struct scatterlist temp; memcpy(&temp, sg, sizeof(struct scatterlist)); temp.offset = offset; temp.length = length; - crypto_hash_update(&tcp_conn->data_rx_hash, &temp, length); - crypto_digest_update(tfm, &temp, 1); ++ crypto_hash_update(desc, &temp, length); } static void @@@ -689,7 -692,7 +693,7 @@@ iscsi_recv_digest_update(struct iscsi_t struct scatterlist tmp; sg_init_one(&tmp, buf, len); - crypto_hash_update(&tcp_conn->data_rx_hash, &tmp, len); - crypto_digest_update(tcp_conn->rx_tfm, &tmp, 1); ++ crypto_hash_update(&tcp_conn->rx_hash, &tmp, len); } static int iscsi_scsi_data_in(struct iscsi_conn *conn) @@@ -743,11 -746,12 +747,12 @@@ if (!rc) { if (conn->datadgst_en) { if (!offset) - crypto_digest_update( - tcp_conn->rx_tfm, + crypto_hash_update( - &tcp_conn->data_rx_hash, - &sg[i], sg[i].length); ++ &tcp_conn->rx_hash, + &sg[i], 1); else - partial_sg_digest_update(tcp_conn, + partial_sg_digest_update( - tcp_conn->rx_tfm, ++ &tcp_conn->rx_hash, &sg[i], sg[i].offset + offset, sg[i].length - offset); @@@ -761,8 -765,9 +766,10 @@@ /* * data-in is complete, but buffer not... */ - partial_sg_digest_update(tcp_conn, &sg[i], - partial_sg_digest_update(tcp_conn->rx_tfm, - &sg[i], -- sg[i].offset, sg[i].length-rc); ++ partial_sg_digest_update(&tcp_conn->rx_hash, ++ &sg[i], ++ sg[i].offset, ++ sg[i].length-rc); rc = 0; break; } @@@ -883,9 -884,8 +886,8 @@@ more */ rc = iscsi_tcp_hdr_recv(conn); if (!rc && tcp_conn->in.datalen) { - if (conn->datadgst_en) { - crypto_hash_init(&tcp_conn->data_rx_hash); - } + if (conn->datadgst_en) - crypto_digest_init(tcp_conn->rx_tfm); ++ crypto_hash_init(&tcp_conn->rx_hash); tcp_conn->in_progress = IN_PROGRESS_DATA_RECV; } else if (rc) { iscsi_conn_failure(conn, rc); @@@ -937,13 -942,14 +944,14 @@@ 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->data_rx_hash, - crypto_digest_update(tcp_conn->rx_tfm, - &sg, 1); ++ crypto_hash_update(&tcp_conn->rx_hash, + &sg, sg.length); } - crypto_hash_final(&tcp_conn->data_rx_hash, - (u8 *)&tcp_conn->in.datadgst); - crypto_digest_final(tcp_conn->rx_tfm, - (u8 *) &tcp_conn->in.datadgst); ++ crypto_hash_final(&tcp_conn->rx_hash, ++ (u8 *) &tcp_conn->in.datadgst); debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst); tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV; + tcp_conn->data_copied = 0; } else tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; } @@@ -1183,11 -1189,9 +1191,9 @@@ iscsi_sendpage(struct iscsi_conn *conn static inline void iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn, - struct iscsi_cmd_task *ctask) + struct iscsi_tcp_cmd_task *tcp_ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - - crypto_hash_init(&tcp_conn->data_tx_hash); - crypto_digest_init(tcp_conn->tx_tfm); ++ crypto_hash_init(&tcp_conn->tx_hash); tcp_ctask->digest_count = 4; } @@@ -1450,86 -1416,125 +1418,126 @@@ iscsi_send_write_hdr(struct iscsi_conn iscsi_hdr_digest(conn, &tcp_ctask->headbuf, (u8*)tcp_ctask->hdrext); rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count); - if (rc) + if (rc) { tcp_ctask->xmstate |= XMSTATE_W_HDR; - return rc; + return rc; + } + + if (ctask->imm_count) { + tcp_ctask->xmstate |= XMSTATE_IMM_DATA; + iscsi_set_padding(tcp_ctask, ctask->imm_count); + + if (ctask->conn->datadgst_en) { + iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask); + tcp_ctask->immdigest = 0; + } + } + + if (ctask->unsol_count) + tcp_ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT; + return 0; } - static inline int - handle_xmstate_data_digest(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) + static int + iscsi_send_padding(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - int rc; + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + int sent = 0, rc; - tcp_ctask->xmstate &= ~XMSTATE_DATA_DIGEST; - debug_tcp("resent data digest 0x%x\n", tcp_ctask->datadigest); - rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, - &tcp_ctask->datadigest, 0); + if (tcp_ctask->xmstate & XMSTATE_W_PAD) { + iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, + tcp_ctask->pad_count); + if (conn->datadgst_en) - crypto_digest_update(tcp_conn->tx_tfm, - &tcp_ctask->sendbuf.sg, 1); ++ crypto_hash_update(&tcp_conn->tx_hash, ++ &tcp_ctask->sendbuf.sg, ++ tcp_ctask->sendbuf.sg.length); + } else if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_PAD)) + return 0; + + tcp_ctask->xmstate &= ~XMSTATE_W_PAD; + tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_PAD; + debug_scsi("sending %d pad bytes for itt 0x%x\n", + tcp_ctask->pad_count, ctask->itt); + rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count, + &sent); if (rc) { - tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST; - debug_tcp("resent data digest 0x%x fail!\n", - tcp_ctask->datadigest); + debug_scsi("padding send failed %d\n", rc); + tcp_ctask->xmstate |= XMSTATE_W_RESEND_PAD; } - return rc; } - static inline int - handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) + static int + iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, + struct iscsi_buf *buf, uint32_t *digest) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - int rc; + struct iscsi_tcp_cmd_task *tcp_ctask; + struct iscsi_tcp_conn *tcp_conn; + int rc, sent = 0; - BUG_ON(!ctask->imm_count); - tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA; + if (!conn->datadgst_en) + return 0; - if (conn->datadgst_en) { - iscsi_data_digest_init(tcp_conn, ctask); - tcp_ctask->immdigest = 0; - } + tcp_ctask = ctask->dd_data; + tcp_conn = conn->dd_data; - for (;;) { - rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, - &ctask->imm_count, &tcp_ctask->sent); - if (rc) { - tcp_ctask->xmstate |= XMSTATE_IMM_DATA; - if (conn->datadgst_en) { - crypto_hash_final(&tcp_conn->data_tx_hash, - (u8 *)&tcp_ctask->immdigest); - debug_tcp("tx imm sendpage fail 0x%x\n", - tcp_ctask->datadigest); - } - return rc; - } - if (conn->datadgst_en) - crypto_hash_update(&tcp_conn->data_tx_hash, - &tcp_ctask->sendbuf.sg, - tcp_ctask->sendbuf.sg.length); + if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_DATA_DIGEST)) { - crypto_digest_final(tcp_conn->tx_tfm, (u8*)digest); ++ crypto_hash_final(&tcp_conn->tx_hash, (u8*)digest); + iscsi_buf_init_iov(buf, (char*)digest, 4); + } + tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_DATA_DIGEST; - if (!ctask->imm_count) - break; - iscsi_buf_init_sg(&tcp_ctask->sendbuf, - &tcp_ctask->sg[tcp_ctask->sg_count++]); + rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent); + if (!rc) + debug_scsi("sent digest 0x%x for itt 0x%x\n", *digest, + ctask->itt); + else { + debug_scsi("sending digest 0x%x failed for itt 0x%x!\n", + *digest, ctask->itt); + tcp_ctask->xmstate |= XMSTATE_W_RESEND_DATA_DIGEST; } + return rc; + } - if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { - rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, - &tcp_ctask->immdigest, 1); - if (rc) { - debug_tcp("sending imm digest 0x%x fail!\n", - tcp_ctask->immdigest); - return rc; + static int + iscsi_send_data(struct iscsi_cmd_task *ctask, struct iscsi_buf *sendbuf, + struct scatterlist **sg, int *sent, int *count, + struct iscsi_buf *digestbuf, uint32_t *digest) + { + struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_conn *conn = ctask->conn; + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + int rc, buf_sent, offset; + + while (*count) { + buf_sent = 0; + offset = sendbuf->sent; + + rc = iscsi_sendpage(conn, sendbuf, count, &buf_sent); + *sent = *sent + buf_sent; + if (buf_sent && conn->datadgst_en) - partial_sg_digest_update(tcp_conn->tx_tfm, ++ partial_sg_digest_update(&tcp_conn->tx_hash, + &sendbuf->sg, sendbuf->sg.offset + offset, + buf_sent); + if (!iscsi_buf_left(sendbuf) && *sg != tcp_ctask->bad_sg) { + iscsi_buf_init_sg(sendbuf, *sg); + *sg = *sg + 1; } - debug_tcp("sending imm digest 0x%x\n", tcp_ctask->immdigest); + + if (rc) + return rc; } - return 0; + rc = iscsi_send_padding(conn, ctask); + if (rc) + return rc; + + return iscsi_send_digest(conn, ctask, digestbuf, digest); } - static inline int - handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) + static int + iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; struct iscsi_data_task *dtask; @@@ -1931,8 -1768,20 +1771,24 @@@ iscsi_tcp_conn_create(struct iscsi_cls_ /* initial operational parameters */ tcp_conn->hdr_size = sizeof(struct iscsi_hdr); - tcp_conn->tx_tfm = crypto_alloc_tfm("crc32c", 0); - if (!tcp_conn->tx_tfm) ++ tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0, ++ CRYPTO_ALG_ASYNC); ++ tcp_conn->tx_hash.flags = 0; ++ if (!tcp_conn->tx_hash.tfm) + goto free_tcp_conn; + - tcp_conn->rx_tfm = crypto_alloc_tfm("crc32c", 0); - if (!tcp_conn->rx_tfm) ++ tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0, ++ CRYPTO_ALG_ASYNC); ++ tcp_conn->rx_hash.flags = 0; ++ if (!tcp_conn->rx_hash.tfm) + goto free_tx_tfm; + return cls_conn; + free_tx_tfm: - crypto_free_tfm(tcp_conn->tx_tfm); ++ crypto_free_hash(tcp_conn->tx_hash.tfm); + free_tcp_conn: + kfree(tcp_conn); tcp_conn_alloc_fail: iscsi_conn_teardown(cls_conn); return NULL; @@@ -1970,14 -1819,10 +1826,10 @@@ iscsi_tcp_conn_destroy(struct iscsi_cls /* now free tcp_conn */ if (digest) { -- if (tcp_conn->tx_tfm) - crypto_free_hash(tcp_conn->tx_tfm); - crypto_free_tfm(tcp_conn->tx_tfm); -- if (tcp_conn->rx_tfm) - crypto_free_hash(tcp_conn->rx_tfm); - if (tcp_conn->data_tx_hash.tfm) - crypto_free_hash(tcp_conn->data_tx_hash.tfm); - if (tcp_conn->data_rx_hash.tfm) - crypto_free_hash(tcp_conn->data_rx_hash.tfm); - crypto_free_tfm(tcp_conn->rx_tfm); ++ if (tcp_conn->tx_hash.tfm) ++ crypto_free_hash(tcp_conn->tx_hash.tfm); ++ if (tcp_conn->rx_hash.tfm) ++ crypto_free_hash(tcp_conn->rx_hash.tfm); } kfree(tcp_conn); diff --cc drivers/scsi/iscsi_tcp.h index e35701305f,609f4778d1..3273683179 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h @@@ -84,10 -81,6 +82,7 @@@ struct iscsi_tcp_conn * stop to terminate */ /* iSCSI connection-wide sequencing */ int hdr_size; /* PDU header size */ + - struct crypto_hash *rx_tfm; /* CRC32C (Rx) */ - struct hash_desc data_rx_hash; /* CRC32C (Rx) for data */ - /* control data */ struct iscsi_tcp_recv in; /* TCP receive context */ int in_progress; /* connection state machine */ @@@ -97,9 -90,9 +92,9 @@@ void (*old_state_change)(struct sock *); void (*old_write_space)(struct sock *); - /* xmit */ - struct crypto_hash *tx_tfm; /* CRC32C (Tx) */ - struct hash_desc data_tx_hash; /* CRC32C (Tx) for data */ + /* data and header digests */ - struct crypto_tfm *tx_tfm; /* CRC32C (Tx) */ - struct crypto_tfm *rx_tfm; /* CRC32C (Rx) */ ++ struct hash_desc tx_hash; /* CRC32C (Tx) */ ++ struct hash_desc rx_hash; /* CRC32C (Rx) */ /* MIB custom statistics */ uint32_t sendpage_failures_cnt;