From a81eacc0b16552fe63ea1536cffec547c6e3db53 Mon Sep 17 00:00:00 2001 From: lishiao <1447175116@qq.com> Date: Tue, 17 Jun 2025 11:57:38 +0800 Subject: [PATCH] iscsi: compute Data Digest for out_data segments --- include/iscsi-private.h | 2 ++ lib/socket.c | 24 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 1fce36a..69c9e3b 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -20,6 +20,7 @@ #include #include #include +#include #if defined(_WIN32) #include @@ -316,6 +317,7 @@ struct iscsi_pdu { uint32_t expxferlen; uint32_t calculated_data_digest; + bool outdata_digest_computed; }; struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi, diff --git a/lib/socket.c b/lib/socket.c index 0b45663..9100064 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -839,13 +839,12 @@ static int iscsi_pdu_update_headerdigest(struct iscsi_context *iscsi, struct isc static int iscsi_write_to_socket(struct iscsi_context *iscsi) { - ssize_t count; + ssize_t count, data_segment_len; size_t total; struct iscsi_pdu *pdu; static char padding_buf[3]; int socket_flags = 0; - bool do_data_digest = (iscsi->data_digest != ISCSI_DATA_DIGEST_NONE); - + bool do_data_digest = (iscsi->data_digest != ISCSI_DATA_DIGEST_NONE), execute_data_digest; #ifdef MSG_NOSIGNAL socket_flags |= MSG_NOSIGNAL; #elif SO_NOSIGPIPE @@ -935,6 +934,23 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) return 0; } + data_segment_len = iscsi_get_pdu_data_size(pdu->outdata.data); + if (do_data_digest && + data_segment_len && + !pdu->payload_len) + execute_data_digest = true; + else + execute_data_digest = false; + + if (execute_data_digest && !pdu->outdata_digest_computed) + { + uint8_t ahslen = pdu->outdata.data[4]; + uint8_t head_len = iscsi->header_digest != ISCSI_HEADER_DIGEST_NONE ? 52 : 48; + uint32_t offset = head_len + ahslen * 4; + pdu->calculated_data_digest = crc32c_chain(pdu->calculated_data_digest, pdu->outdata.data + offset, pdu->outdata.size - offset); + pdu->outdata_digest_computed = true; + } + /* Write any iovectors that might have been passed to us */ while (pdu->payload_written < pdu->payload_len) { struct scsi_iovector* iovector_out; @@ -991,7 +1007,7 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) * 1. DataDigest has been negociated, and * 2. We have actually written some data */ - if (do_data_digest && pdu->payload_written) { + if (execute_data_digest || (do_data_digest && pdu->payload_written)) { uint32_t data_digest = crc32c_chain_done(pdu->calculated_data_digest); char data_digest_buf[ISCSI_DIGEST_SIZE];