Implement protocol-level checksums (xxhash3)

This commit is contained in:
Vitaliy Filippov
2026-04-03 21:26:25 +03:00
parent 435c43e4c8
commit e14231e263
13 changed files with 188 additions and 53 deletions
+37 -2
View File
@@ -268,6 +268,11 @@ void osd_messenger_t::handle_send(int result, bool prev, bool more, osd_client_t
cl->zc_free_list.push_back(NULL); // end marker
cl->send_free_ops.clear();
cl->write_state = cl->write_op || cl->write_ops.size() ? CL_WRITE_READY : 0;
if (cl->proto_csum_status == MSGR_PEER_CSUM_IN && !cl->write_op && !cl->write_ops.size())
{
// Checksums negotiated, enable
cl->proto_csum_status = MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT;
}
#ifdef WITH_RDMA
if (cl->rdma_conn && !cl->write_op && !cl->write_ops.size() && cl->peer_state == PEER_RDMA_CONNECTING)
{
@@ -344,13 +349,15 @@ size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_le
{
size_t done = 0;
size_t from = cl->write_op_pos;
auto op_write_buf = [&](uint8_t *src, size_t src_len)
auto op_write_buf = [&](uint8_t *src, size_t src_len, bool skip_csum = false)
{
if (from < src_len)
{
size_t n = src_len-from;
if (n > dst_len-done)
n = dst_len-done;
if (cl->write_csum_state && !skip_csum)
XXH3_64bits_update(cl->write_csum_state, src+from, n);
memcpy(dst+done, src+from, n);
done += n;
cl->write_op_pos += n;
@@ -363,6 +370,12 @@ size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_le
from -= src_len;
return true;
};
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT) && !from)
{
if (!cl->write_csum_state)
cl->write_csum_state = XXH3_createState();
XXH3_64bits_reset(cl->write_csum_state);
}
if (!op_write_headers(cl->write_op, op_write_buf))
{
return done;
@@ -386,6 +399,13 @@ size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_le
}
}
}
if (cl->write_csum_state)
{
if (!from)
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
if (!op_write_buf((uint8_t*)&cl->write_op->csum, 8, true))
return done;
}
cl->write_op = NULL;
cl->write_op_pos = 0;
return done;
@@ -394,12 +414,14 @@ size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_le
void osd_messenger_t::op_get_write_buffers(osd_client_t *cl, std::vector<iovec> & lst)
{
size_t from = cl->write_op_pos;
auto op_write_buf = [&](uint8_t *src, size_t src_len)
auto op_write_buf = [&](uint8_t *src, size_t src_len, bool skip_csum = false)
{
if (lst.size() >= IOV_MAX)
return false;
if (from < src_len)
{
if (cl->write_csum_state && !skip_csum)
XXH3_64bits_update(cl->write_csum_state, src+from, src_len-from);
lst.push_back((iovec){ .iov_base = src+from, .iov_len = src_len-from });
cl->write_op_pos += src_len-from;
from = 0;
@@ -408,6 +430,12 @@ void osd_messenger_t::op_get_write_buffers(osd_client_t *cl, std::vector<iovec>
from -= src_len;
return true;
};
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT) && !from)
{
if (!cl->write_csum_state)
cl->write_csum_state = XXH3_createState();
XXH3_64bits_reset(cl->write_csum_state);
}
if (!op_write_headers(cl->write_op, op_write_buf))
{
return;
@@ -439,6 +467,13 @@ void osd_messenger_t::op_get_write_buffers(osd_client_t *cl, std::vector<iovec>
}
}
}
if (cl->write_csum_state)
{
if (!from)
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
if (!op_write_buf((uint8_t*)&cl->write_op->csum, 8, true))
return;
}
cl->write_op = NULL;
cl->write_op_pos = 0;
}