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
This commit is contained in:
Claude
2026-01-27 22:15:20 +00:00
parent 3bb30dcd09
commit cd3ecec786
2 changed files with 39 additions and 37 deletions
+37 -35
View File
@@ -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) {