Skip to content

Commit

Permalink
iscsi_tcp: Use ahash
Browse files Browse the repository at this point in the history
This patch replaces uses of the long obsolete hash interface with
ahash.

Signed-off-by: Herbert Xu <[email protected]>
Reviewed-by: Mike Christie <[email protected]>
  • Loading branch information
herbertx committed Jan 27, 2016
1 parent 4a31340 commit 5d6ac29
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 42 deletions.
54 changes: 32 additions & 22 deletions drivers/scsi/iscsi_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
* Zhenyu Wang
*/

#include <crypto/hash.h>
#include <linux/types.h>
#include <linux/inet.h>
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/blkdev.h>
#include <linux/crypto.h>
#include <linux/delay.h>
#include <linux/kfifo.h>
#include <linux/scatterlist.h>
Expand Down Expand Up @@ -428,7 +428,7 @@ static void iscsi_sw_tcp_send_hdr_prep(struct iscsi_conn *conn, void *hdr,
* sufficient room.
*/
if (conn->hdrdgst_en) {
iscsi_tcp_dgst_header(&tcp_sw_conn->tx_hash, hdr, hdrlen,
iscsi_tcp_dgst_header(tcp_sw_conn->tx_hash, hdr, hdrlen,
hdr + hdrlen);
hdrlen += ISCSI_DIGEST_SIZE;
}
Expand All @@ -454,7 +454,7 @@ iscsi_sw_tcp_send_data_prep(struct iscsi_conn *conn, struct scatterlist *sg,
{
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
struct hash_desc *tx_hash = NULL;
struct ahash_request *tx_hash = NULL;
unsigned int hdr_spec_len;

ISCSI_SW_TCP_DBG(conn, "offset=%d, datalen=%d %s\n", offset, len,
Expand All @@ -467,7 +467,7 @@ iscsi_sw_tcp_send_data_prep(struct iscsi_conn *conn, struct scatterlist *sg,
WARN_ON(iscsi_padded(len) != iscsi_padded(hdr_spec_len));

if (conn->datadgst_en)
tx_hash = &tcp_sw_conn->tx_hash;
tx_hash = tcp_sw_conn->tx_hash;

return iscsi_segment_seek_sg(&tcp_sw_conn->out.data_segment,
sg, count, offset, len,
Expand All @@ -480,7 +480,7 @@ iscsi_sw_tcp_send_linear_data_prep(struct iscsi_conn *conn, void *data,
{
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
struct hash_desc *tx_hash = NULL;
struct ahash_request *tx_hash = NULL;
unsigned int hdr_spec_len;

ISCSI_SW_TCP_DBG(conn, "datalen=%zd %s\n", len, conn->datadgst_en ?
Expand All @@ -492,7 +492,7 @@ iscsi_sw_tcp_send_linear_data_prep(struct iscsi_conn *conn, void *data,
WARN_ON(iscsi_padded(len) != iscsi_padded(hdr_spec_len));

if (conn->datadgst_en)
tx_hash = &tcp_sw_conn->tx_hash;
tx_hash = tcp_sw_conn->tx_hash;

iscsi_segment_init_linear(&tcp_sw_conn->out.data_segment,
data, len, NULL, tx_hash);
Expand Down Expand Up @@ -543,6 +543,7 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,
struct iscsi_cls_conn *cls_conn;
struct iscsi_tcp_conn *tcp_conn;
struct iscsi_sw_tcp_conn *tcp_sw_conn;
struct crypto_ahash *tfm;

cls_conn = iscsi_tcp_conn_setup(cls_session, sizeof(*tcp_sw_conn),
conn_idx);
Expand All @@ -552,23 +553,28 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,
tcp_conn = conn->dd_data;
tcp_sw_conn = tcp_conn->dd_data;

tcp_sw_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
CRYPTO_ALG_ASYNC);
tcp_sw_conn->tx_hash.flags = 0;
if (IS_ERR(tcp_sw_conn->tx_hash.tfm))
tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm))
goto free_conn;

tcp_sw_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
CRYPTO_ALG_ASYNC);
tcp_sw_conn->rx_hash.flags = 0;
if (IS_ERR(tcp_sw_conn->rx_hash.tfm))
goto free_tx_tfm;
tcp_conn->rx_hash = &tcp_sw_conn->rx_hash;
tcp_sw_conn->tx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
if (!tcp_sw_conn->tx_hash)
goto free_tfm;
ahash_request_set_callback(tcp_sw_conn->tx_hash, 0, NULL, NULL);

tcp_sw_conn->rx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
if (!tcp_sw_conn->rx_hash)
goto free_tx_hash;
ahash_request_set_callback(tcp_sw_conn->rx_hash, 0, NULL, NULL);

tcp_conn->rx_hash = tcp_sw_conn->rx_hash;

return cls_conn;

free_tx_tfm:
crypto_free_hash(tcp_sw_conn->tx_hash.tfm);
free_tx_hash:
ahash_request_free(tcp_sw_conn->tx_hash);
free_tfm:
crypto_free_ahash(tfm);
free_conn:
iscsi_conn_printk(KERN_ERR, conn,
"Could not create connection due to crc32c "
Expand Down Expand Up @@ -607,10 +613,14 @@ static void iscsi_sw_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)

iscsi_sw_tcp_release_conn(conn);

if (tcp_sw_conn->tx_hash.tfm)
crypto_free_hash(tcp_sw_conn->tx_hash.tfm);
if (tcp_sw_conn->rx_hash.tfm)
crypto_free_hash(tcp_sw_conn->rx_hash.tfm);
ahash_request_free(tcp_sw_conn->rx_hash);
if (tcp_sw_conn->tx_hash) {
struct crypto_ahash *tfm;

tfm = crypto_ahash_reqtfm(tcp_sw_conn->tx_hash);
ahash_request_free(tcp_sw_conn->tx_hash);
crypto_free_ahash(tfm);
}

iscsi_tcp_conn_teardown(cls_conn);
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/iscsi_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ struct iscsi_sw_tcp_conn {
void (*old_write_space)(struct sock *);

/* data and header digests */
struct hash_desc tx_hash; /* CRC32C (Tx) */
struct hash_desc rx_hash; /* CRC32C (Rx) */
struct ahash_request *tx_hash; /* CRC32C (Tx) */
struct ahash_request *rx_hash; /* CRC32C (Rx) */

/* MIB custom statistics */
uint32_t sendpage_failures_cnt;
Expand Down
29 changes: 17 additions & 12 deletions drivers/scsi/libiscsi_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@
* Zhenyu Wang
*/

#include <crypto/hash.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/inet.h>
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/blkdev.h>
#include <linux/crypto.h>
#include <linux/delay.h>
#include <linux/kfifo.h>
#include <linux/scatterlist.h>
Expand Down Expand Up @@ -214,7 +214,8 @@ int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
} else
sg_init_one(&sg, segment->data + segment->copied,
copied);
crypto_hash_update(segment->hash, &sg, copied);
ahash_request_set_crypt(segment->hash, &sg, NULL, copied);
crypto_ahash_update(segment->hash);
}

segment->copied += copied;
Expand Down Expand Up @@ -260,7 +261,9 @@ int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
* is completely handled in hdr done function.
*/
if (segment->hash) {
crypto_hash_final(segment->hash, segment->digest);
ahash_request_set_crypt(segment->hash, NULL,
segment->digest, 0);
crypto_ahash_final(segment->hash);
iscsi_tcp_segment_splice_digest(segment,
recv ? segment->recv_digest : segment->digest);
return 0;
Expand Down Expand Up @@ -310,13 +313,14 @@ iscsi_tcp_segment_recv(struct iscsi_tcp_conn *tcp_conn,
}

inline void
iscsi_tcp_dgst_header(struct hash_desc *hash, const void *hdr, size_t hdrlen,
unsigned char digest[ISCSI_DIGEST_SIZE])
iscsi_tcp_dgst_header(struct ahash_request *hash, const void *hdr,
size_t hdrlen, unsigned char digest[ISCSI_DIGEST_SIZE])
{
struct scatterlist sg;

sg_init_one(&sg, hdr, hdrlen);
crypto_hash_digest(hash, &sg, hdrlen, digest);
ahash_request_set_crypt(hash, &sg, digest, hdrlen);
crypto_ahash_digest(hash);
}
EXPORT_SYMBOL_GPL(iscsi_tcp_dgst_header);

Expand All @@ -341,22 +345,22 @@ iscsi_tcp_dgst_verify(struct iscsi_tcp_conn *tcp_conn,
*/
static inline void
__iscsi_segment_init(struct iscsi_segment *segment, size_t size,
iscsi_segment_done_fn_t *done, struct hash_desc *hash)
iscsi_segment_done_fn_t *done, struct ahash_request *hash)
{
memset(segment, 0, sizeof(*segment));
segment->total_size = size;
segment->done = done;

if (hash) {
segment->hash = hash;
crypto_hash_init(hash);
crypto_ahash_init(hash);
}
}

inline void
iscsi_segment_init_linear(struct iscsi_segment *segment, void *data,
size_t size, iscsi_segment_done_fn_t *done,
struct hash_desc *hash)
struct ahash_request *hash)
{
__iscsi_segment_init(segment, size, done, hash);
segment->data = data;
Expand All @@ -368,7 +372,8 @@ inline int
iscsi_segment_seek_sg(struct iscsi_segment *segment,
struct scatterlist *sg_list, unsigned int sg_count,
unsigned int offset, size_t size,
iscsi_segment_done_fn_t *done, struct hash_desc *hash)
iscsi_segment_done_fn_t *done,
struct ahash_request *hash)
{
struct scatterlist *sg;
unsigned int i;
Expand Down Expand Up @@ -431,7 +436,7 @@ static void
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;
struct ahash_request *rx_hash = NULL;

if (conn->datadgst_en &&
!(conn->session->tt->caps & CAP_DIGEST_OFFLOAD))
Expand Down Expand Up @@ -686,7 +691,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)

if (tcp_conn->in.datalen) {
struct iscsi_tcp_task *tcp_task = task->dd_data;
struct hash_desc *rx_hash = NULL;
struct ahash_request *rx_hash = NULL;
struct scsi_data_buffer *sdb = scsi_in(task->sc);

/*
Expand Down
13 changes: 7 additions & 6 deletions include/scsi/libiscsi_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
struct iscsi_tcp_conn;
struct iscsi_segment;
struct sk_buff;
struct hash_desc;
struct ahash_request;

typedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *,
struct iscsi_segment *);
Expand All @@ -38,7 +38,7 @@ struct iscsi_segment {
unsigned int total_size;
unsigned int total_copied;

struct hash_desc *hash;
struct ahash_request *hash;
unsigned char padbuf[ISCSI_PAD_LEN];
unsigned char recv_digest[ISCSI_DIGEST_SIZE];
unsigned char digest[ISCSI_DIGEST_SIZE];
Expand Down Expand Up @@ -73,7 +73,7 @@ struct iscsi_tcp_conn {
/* control data */
struct iscsi_tcp_recv in; /* TCP receive context */
/* CRC32C (Rx) LLD should set this is they do not offload */
struct hash_desc *rx_hash;
struct ahash_request *rx_hash;
};

struct iscsi_tcp_task {
Expand Down Expand Up @@ -111,15 +111,16 @@ extern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment);
extern void iscsi_segment_init_linear(struct iscsi_segment *segment,
void *data, size_t size,
iscsi_segment_done_fn_t *done,
struct hash_desc *hash);
struct ahash_request *hash);
extern int
iscsi_segment_seek_sg(struct iscsi_segment *segment,
struct scatterlist *sg_list, unsigned int sg_count,
unsigned int offset, size_t size,
iscsi_segment_done_fn_t *done, struct hash_desc *hash);
iscsi_segment_done_fn_t *done,
struct ahash_request *hash);

/* digest helpers */
extern void iscsi_tcp_dgst_header(struct hash_desc *hash, const void *hdr,
extern void iscsi_tcp_dgst_header(struct ahash_request *hash, const void *hdr,
size_t hdrlen,
unsigned char digest[ISCSI_DIGEST_SIZE]);
extern struct iscsi_cls_conn *
Expand Down

0 comments on commit 5d6ac29

Please sign in to comment.