From cd3ecec7861af710d7ac89edf052d40349d5085f Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 27 Jan 2026 22:15:20 +0000 Subject: [PATCH] Fix two bugs in read operation that caused test failure 1. Fix client not reading all server addresses in READ response The metadata server sends address info for ALL chunk servers holding a chunk, but the client only read info for ONE server. This caused message parsing to become misaligned for subsequent chunks. Added a loop to iterate through all num_servers and read each server's address list (using the first one, skipping the rest). 2. Fix tag value conflict between metadata and chunk server responses TAG_RETRIEVE_METADATA_FOR_READ was 1, which conflicted with chunk download range indices (0, 1, 2, 3...). When the second chunk download response came with range_idx=1, it was incorrectly treated as a metadata response. Changed TAG values from positive to negative integers since range indices are always non-negative. Also updated the test to properly exit on success instead of assert(0). https://claude.ai/code/session_01QYDQCNiUj1cjrsS6qRgkvd --- src/client.c | 72 ++++++++++++++++++++++++----------------------- src/test_client.c | 4 +-- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/client.c b/src/client.c index c6ad55e..237d837 100644 --- a/src/client.c +++ b/src/client.c @@ -27,9 +27,9 @@ typedef pthread_mutex_t Mutex; #define TAG_METADATA_SERVER -2 -#define TAG_RETRIEVE_METADATA_FOR_READ 1 -#define TAG_RETRIEVE_METADATA_FOR_WRITE 2 -#define TAG_COMMIT_WRITE 3 +#define TAG_RETRIEVE_METADATA_FOR_READ -1 +#define TAG_RETRIEVE_METADATA_FOR_WRITE -3 +#define TAG_COMMIT_WRITE -4 #define TAG_UPLOAD_CHUNK_MIN 1000 #define TAG_UPLOAD_CHUNK_MAX 100000 @@ -1065,7 +1065,6 @@ static void process_event_for_read(ToastyFS *toasty, toasty->operations[opidx].result = (ToastyResult) { .type=TOASTY_RESULT_READ_ERROR, .user=toasty->operations[opidx].user }; return; } - // Store actual_bytes for later use toasty->operations[opidx].actual_bytes = actual_bytes; @@ -1120,49 +1119,52 @@ static void process_event_for_read(ToastyFS *toasty, return; } - // Parse IPv4 addresses - uint32_t num_ipv4; - if (!binary_read(&reader, &num_ipv4, sizeof(num_ipv4))) { - free(ranges); - toasty->operations[opidx].result = (ToastyResult) { .type=TOASTY_RESULT_READ_ERROR, .user=toasty->operations[opidx].user }; - return; - } - Address server_addr = {0}; bool found = false; - // Get first IPv4 address - for (uint32_t j = 0; j < num_ipv4; j++) { - IPv4 ipv4; - uint16_t port; - if (!binary_read(&reader, &ipv4, sizeof(ipv4)) || - !binary_read(&reader, &port, sizeof(port))) { + // Parse each server's address list (use first one, skip the rest) + for (uint32_t s = 0; s < num_servers; s++) { + // Parse IPv4 addresses + uint32_t num_ipv4; + if (!binary_read(&reader, &num_ipv4, sizeof(num_ipv4))) { free(ranges); toasty->operations[opidx].result = (ToastyResult) { .type=TOASTY_RESULT_READ_ERROR, .user=toasty->operations[opidx].user }; return; } - if (!found) { - server_addr.is_ipv4 = true; - server_addr.ipv4 = ipv4; - server_addr.port = port; - found = true; - } - } - // Skip IPv6 addresses - uint32_t num_ipv6; - if (!binary_read(&reader, &num_ipv6, sizeof(num_ipv6))) { - free(ranges); - toasty->operations[opidx].result = (ToastyResult) { .type=TOASTY_RESULT_READ_ERROR, .user=toasty->operations[opidx].user }; - return; - } - for (uint32_t j = 0; j < num_ipv6; j++) { - if (!binary_read(&reader, NULL, sizeof(IPv6)) || - !binary_read(&reader, NULL, sizeof(uint16_t))) { + // Get first IPv4 address from first server + for (uint32_t j = 0; j < num_ipv4; j++) { + IPv4 ipv4; + uint16_t port; + if (!binary_read(&reader, &ipv4, sizeof(ipv4)) || + !binary_read(&reader, &port, sizeof(port))) { + free(ranges); + toasty->operations[opidx].result = (ToastyResult) { .type=TOASTY_RESULT_READ_ERROR, .user=toasty->operations[opidx].user }; + return; + } + if (!found) { + server_addr.is_ipv4 = true; + server_addr.ipv4 = ipv4; + server_addr.port = port; + found = true; + } + } + + // Skip IPv6 addresses + uint32_t num_ipv6; + if (!binary_read(&reader, &num_ipv6, sizeof(num_ipv6))) { free(ranges); toasty->operations[opidx].result = (ToastyResult) { .type=TOASTY_RESULT_READ_ERROR, .user=toasty->operations[opidx].user }; return; } + for (uint32_t j = 0; j < num_ipv6; j++) { + if (!binary_read(&reader, NULL, sizeof(IPv6)) || + !binary_read(&reader, NULL, sizeof(uint16_t))) { + free(ranges); + toasty->operations[opidx].result = (ToastyResult) { .type=TOASTY_RESULT_READ_ERROR, .user=toasty->operations[opidx].user }; + return; + } + } } if (!found) { diff --git a/src/test_client.c b/src/test_client.c index 6bfabcb..68a4625 100644 --- a/src/test_client.c +++ b/src/test_client.c @@ -166,8 +166,8 @@ int test_client_tick(void *state_, void **ctxs, if (memcmp(client->buf, msg, sizeof(msg)-1)) { assert(0); // TODO } - assert(0); // TODO - break; + printf("Test PASSED: Read data matches written data\n"); + exit(0); // Test completed successfully } *timeout = -1;