Fix GET request returning corrupted data for multi-chunk blobs
Four bugs caused data mismatches between PUT and GET operations: 1. chunk_store_exists() used file_open (O_CREAT) to check if a chunk file exists, which created empty files as a side effect. Servers would then read from these empty files and return uninitialized heap memory as chunk data. Fixed by using file_exists (access()) instead. 2. Server's process_fetch_chunk checked `ret < 0` after chunk_store_read, missing the EOF case (ret == 0) from empty files. Changed to `ret <= 0`. 3. begin_transfers() == 0 was used as a completion check in both STEP_FETCH_CHUNK and STEP_STORE_CHUNK, but returning 0 only means "no new transfers started", not "all done". With concurrent chunk transfers, this caused premature completion, leaving in-flight transfers to hit UNREACHABLE. Fixed by using all_chunk_transfers_completed() instead. 4. choose_store_locations_for_chunk() returned [0, 1] for ALL chunks regardless of index, while GET fetches chunk i from servers (i+j) % num_servers. This made some chunks unreachable. Fixed by using (chunk_idx + j) % num_servers for store locations. Also added SO_REUSEADDR to the server listen socket so restarting the cluster doesn't fail with "Couldn't setup TCP listener", and added a note on mock_access about the simulation mismatch. https://claude.ai/code/session_01JniNxxDP4NbsDXNGmGNG7H
This commit is contained in:
+1
-1
@@ -949,7 +949,7 @@ found_size:;
|
||||
return HR_OUT_OF_MEMORY;
|
||||
|
||||
int ret = chunk_store_read(&state->chunk_store, message.hash, chunk_data, chunk_size);
|
||||
if (ret < 0) {
|
||||
if (ret <= 0) {
|
||||
free(chunk_data);
|
||||
FetchChunkResponseMessage response = {
|
||||
.base = {
|
||||
|
||||
Reference in New Issue
Block a user