nvmet-tcp: fix regression in data_digest calculation
authorSagi Grimberg <sagi@grimberg.me>
Thu, 23 Jun 2022 21:49:53 +0000 (00:49 +0300)
committerChristoph Hellwig <hch@lst.de>
Wed, 29 Jun 2022 14:13:44 +0000 (16:13 +0200)
Data digest calculation iterates over command mapped iovec. However
since commit bac04454ef9f we unmap the iovec before we handle the data
digest, and since commit 69b85e1f1d1d we clear nr_mapped when we unmap
the iov.

Instead of open-coding the command iov traversal, simply call
crypto_ahash_digest with the command sg that is already allocated (we
already do that for the send path). Rename nvmet_tcp_send_ddgst to
nvmet_tcp_calc_ddgst and call it from send and recv paths.

Fixes: 69b85e1f1d1d ("nvmet-tcp: add an helper to free the cmd buffers")
Fixes: bac04454ef9f ("nvmet-tcp: fix kmap leak when data digest in use")
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/target/tcp.c

index 2793554..0a95425 100644 (file)
@@ -405,7 +405,7 @@ err:
        return NVME_SC_INTERNAL;
 }
 
-static void nvmet_tcp_send_ddgst(struct ahash_request *hash,
+static void nvmet_tcp_calc_ddgst(struct ahash_request *hash,
                struct nvmet_tcp_cmd *cmd)
 {
        ahash_request_set_crypt(hash, cmd->req.sg,
@@ -413,23 +413,6 @@ static void nvmet_tcp_send_ddgst(struct ahash_request *hash,
        crypto_ahash_digest(hash);
 }
 
-static void nvmet_tcp_recv_ddgst(struct ahash_request *hash,
-               struct nvmet_tcp_cmd *cmd)
-{
-       struct scatterlist sg;
-       struct kvec *iov;
-       int i;
-
-       crypto_ahash_init(hash);
-       for (i = 0, iov = cmd->iov; i < cmd->nr_mapped; i++, iov++) {
-               sg_init_one(&sg, iov->iov_base, iov->iov_len);
-               ahash_request_set_crypt(hash, &sg, NULL, iov->iov_len);
-               crypto_ahash_update(hash);
-       }
-       ahash_request_set_crypt(hash, NULL, (void *)&cmd->exp_ddgst, 0);
-       crypto_ahash_final(hash);
-}
-
 static void nvmet_setup_c2h_data_pdu(struct nvmet_tcp_cmd *cmd)
 {
        struct nvme_tcp_data_pdu *pdu = cmd->data_pdu;
@@ -454,7 +437,7 @@ static void nvmet_setup_c2h_data_pdu(struct nvmet_tcp_cmd *cmd)
 
        if (queue->data_digest) {
                pdu->hdr.flags |= NVME_TCP_F_DDGST;
-               nvmet_tcp_send_ddgst(queue->snd_hash, cmd);
+               nvmet_tcp_calc_ddgst(queue->snd_hash, cmd);
        }
 
        if (cmd->queue->hdr_digest) {
@@ -1137,7 +1120,7 @@ static void nvmet_tcp_prep_recv_ddgst(struct nvmet_tcp_cmd *cmd)
 {
        struct nvmet_tcp_queue *queue = cmd->queue;
 
-       nvmet_tcp_recv_ddgst(queue->rcv_hash, cmd);
+       nvmet_tcp_calc_ddgst(queue->rcv_hash, cmd);
        queue->offset = 0;
        queue->left = NVME_TCP_DIGEST_LENGTH;
        queue->rcv_state = NVMET_TCP_RECV_DDGST;