This commit is contained in:
2025-10-28 09:57:48 +01:00
parent 3f0f4c2443
commit ea18992f6a
3 changed files with 335 additions and 165 deletions
+277 -104
View File
@@ -3825,6 +3825,8 @@ typedef struct {
char* dst; char* dst;
uint32_t offset_within_chunk; uint32_t offset_within_chunk;
uint32_t length_within_chunk; uint32_t length_within_chunk;
Address server_addr; // Chunk server address for this chunk
int chunk_server_idx; // Index in tdfs->chunk_servers array
} Range; } Range;
typedef enum { typedef enum {
@@ -3900,7 +3902,7 @@ TinyDFS *tinydfs_init(char *addr, uint16_t port)
addr2.port = port; addr2.port = port;
if (inet_pton(AF_INET, addr, &addr2.ipv4) != 1) { if (inet_pton(AF_INET, addr, &addr2.ipv4) != 1) {
free(tdfs); free(tdfs);
return tdfs; return NULL;
} }
tcp_context_init(&tdfs->tcp); tcp_context_init(&tdfs->tcp);
@@ -3919,7 +3921,7 @@ TinyDFS *tinydfs_init(char *addr, uint16_t port)
return tdfs; return tdfs;
} }
void tdfs_free(TinyDFS *tdfs) void tinydfs_free(TinyDFS *tdfs)
{ {
tcp_context_free(&tdfs->tcp); tcp_context_free(&tdfs->tcp);
free(tdfs); free(tdfs);
@@ -3937,7 +3939,7 @@ alloc_operation(TinyDFS *tdfs, OperationType type, int off, void *ptr, int len)
o->ptr = ptr; o->ptr = ptr;
o->off = off; o->off = off;
o->len = len; o->len = len;
o->result = (Result) { TINYDFS_RESULT_EMPTY }; o->result = (TinyDFS_Result) { TINYDFS_RESULT_EMPTY };
tdfs->num_operations++; tdfs->num_operations++;
return o - tdfs->operations; return o - tdfs->operations;
@@ -3978,6 +3980,63 @@ request_queue_pop(RequestQueue *reqs, Request *req)
return 0; return 0;
} }
// Get or create connection to a chunk server
static int get_chunk_server_connection(TinyDFS *tdfs, Address addr)
{
// Check if already connected
for (int i = 0; i < tdfs->num_chunk_servers; i++) {
if (tdfs->chunk_servers[i].used && addr_eql(tdfs->chunk_servers[i].addr, addr)) {
int conn_idx = tcp_index_from_tag(&tdfs->tcp, i);
if (conn_idx >= 0)
return i;
}
}
// Find free slot
int idx = -1;
for (int i = 0; i < MAX_CHUNK_SERVERS; i++) {
if (!tdfs->chunk_servers[i].used) {
idx = i;
break;
}
}
if (idx < 0) return -1;
// Connect
if (tcp_connect(&tdfs->tcp, addr, idx, NULL) < 0)
return -1;
// Initialize
tdfs->chunk_servers[idx].used = true;
tdfs->chunk_servers[idx].addr = addr;
request_queue_init(&tdfs->chunk_servers[idx].reqs);
tdfs->num_chunk_servers++;
return idx;
}
// Send download request for a chunk
static int send_download_chunk(TinyDFS *tdfs, int chunk_server_idx,
SHA256 hash, uint32_t offset, uint32_t length, int opidx, int range_idx)
{
int conn_idx = tcp_index_from_tag(&tdfs->tcp, chunk_server_idx);
if (conn_idx < 0) return -1;
MessageWriter writer;
ByteQueue *output = tcp_output_buffer(&tdfs->tcp, conn_idx);
message_writer_init(&writer, output, MESSAGE_TYPE_DOWNLOAD_CHUNK);
message_write(&writer, &hash, sizeof(hash));
message_write(&writer, &offset, sizeof(offset));
message_write(&writer, &length, sizeof(length));
if (!message_writer_free(&writer))
return -1;
RequestQueue *reqs = &tdfs->chunk_servers[chunk_server_idx].reqs;
return request_queue_push(reqs, (Request) { range_idx, opidx });
}
static void static void
metadata_server_request_start(TinyDFS *tdfs, MessageWriter *writer, uint16_t type) metadata_server_request_start(TinyDFS *tdfs, MessageWriter *writer, uint16_t type)
{ {
@@ -4149,7 +4208,7 @@ static void process_event_for_create(TinyDFS *tdfs,
int opidx, int request_tag, ByteView msg) int opidx, int request_tag, ByteView msg)
{ {
if (msg.len == 0) { if (msg.len == 0) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_CREATE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_CREATE_ERROR };
return; return;
} }
@@ -4157,41 +4216,41 @@ static void process_event_for_create(TinyDFS *tdfs,
// version; // version;
if (!binary_read(&reader, NULL, sizeof(uint16_t))) { if (!binary_read(&reader, NULL, sizeof(uint16_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_CREATE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_CREATE_ERROR };
return; return;
} }
uint16_t type; uint16_t type;
if (!binary_read(&reader, &type, sizeof(type))) { if (!binary_read(&reader, &type, sizeof(type))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_CREATE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_CREATE_ERROR };
return; return;
} }
// length // length
if (!binary_read(&reader, NULL, sizeof(uint32_t))) { if (!binary_read(&reader, NULL, sizeof(uint32_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_CREATE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_CREATE_ERROR };
return; return;
} }
if (type != MESSAGE_TYPE_CREATE_SUCCESS) { if (type != MESSAGE_TYPE_CREATE_SUCCESS) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_CREATE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_CREATE_ERROR };
return; return;
} }
// Check there is nothing else to read // Check there is nothing else to read
if (binary_read(&reader, NULL, 1)) { if (binary_read(&reader, NULL, 1)) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_CREATE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_CREATE_ERROR };
return; return;
} }
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_CREATE_SUCCESS }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_CREATE_SUCCESS };
} }
static void process_event_for_delete(TinyDFS *tdfs, static void process_event_for_delete(TinyDFS *tdfs,
int opidx, int request_tag, ByteView msg) int opidx, int request_tag, ByteView msg)
{ {
if (msg.len == 0) { if (msg.len == 0) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_DELETE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_DELETE_ERROR };
return; return;
} }
@@ -4199,41 +4258,41 @@ static void process_event_for_delete(TinyDFS *tdfs,
// version // version
if (!binary_read(&reader, NULL, sizeof(uint16_t))) { if (!binary_read(&reader, NULL, sizeof(uint16_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_DELETE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_DELETE_ERROR };
return; return;
} }
uint16_t type; uint16_t type;
if (!binary_read(&reader, &type, sizeof(type))) { if (!binary_read(&reader, &type, sizeof(type))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_DELETE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_DELETE_ERROR };
return; return;
} }
// length // length
if (!binary_read(&reader, NULL, sizeof(uint32_t))) { if (!binary_read(&reader, NULL, sizeof(uint32_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_DELETE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_DELETE_ERROR };
return; return;
} }
if (type != MESSAGE_TYPE_DELETE_SUCCESS) { if (type != MESSAGE_TYPE_DELETE_SUCCESS) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_DELETE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_DELETE_ERROR };
return; return;
} }
// Check there is nothing else to read // Check there is nothing else to read
if (binary_read(&reader, NULL, 1)) { if (binary_read(&reader, NULL, 1)) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_DELETE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_DELETE_ERROR };
return; return;
} }
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_DELETE_SUCCESS }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_DELETE_SUCCESS };
} }
static void process_event_for_list(TinyDFS *tdfs, static void process_event_for_list(TinyDFS *tdfs,
int opidx, int request_tag, ByteView msg) int opidx, int request_tag, ByteView msg)
{ {
if (msg.len == 0) { if (msg.len == 0) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_LIST_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_LIST_ERROR };
return; return;
} }
@@ -4241,24 +4300,24 @@ static void process_event_for_list(TinyDFS *tdfs,
// version // version
if (!binary_read(&reader, NULL, sizeof(uint16_t))) { if (!binary_read(&reader, NULL, sizeof(uint16_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_LIST_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_LIST_ERROR };
return; return;
} }
uint16_t type; uint16_t type;
if (!binary_read(&reader, &type, sizeof(type))) { if (!binary_read(&reader, &type, sizeof(type))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_LIST_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_LIST_ERROR };
return; return;
} }
// length // length
if (!binary_read(&reader, NULL, sizeof(uint32_t))) { if (!binary_read(&reader, NULL, sizeof(uint32_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_LIST_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_LIST_ERROR };
return; return;
} }
if (type != MESSAGE_TYPE_LIST_SUCCESS) { if (type != MESSAGE_TYPE_LIST_SUCCESS) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_LIST_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_LIST_ERROR };
return; return;
} }
@@ -4266,185 +4325,299 @@ static void process_event_for_list(TinyDFS *tdfs,
// Check there is nothing else to read // Check there is nothing else to read
if (binary_read(&reader, NULL, 1)) { if (binary_read(&reader, NULL, 1)) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_LIST_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_LIST_ERROR };
return; return;
} }
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_LIST_SUCCESS }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_LIST_SUCCESS };
} }
static void process_event_for_read(TinyDFS *tdfs, static void process_event_for_read(TinyDFS *tdfs,
int opidx, int request_tag, ByteView msg) int opidx, int request_tag, ByteView msg)
{ {
if (msg.len == 0) { if (msg.len == 0) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
switch (request_tag) { if (request_tag == TAG_RETRIEVE_METADATA_FOR_READ) {
// Handle metadata response from metadata server
case TAG_RETRIEVE_METADATA_FOR_READ:
{
BinaryReader reader = { msg.ptr, msg.len, 0 }; BinaryReader reader = { msg.ptr, msg.len, 0 };
// version // Skip version
if (!binary_read(&reader, NULL, sizeof(uint16_t))) { if (!binary_read(&reader, NULL, sizeof(uint16_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
// Check message type
uint16_t type; uint16_t type;
if (!binary_read(&reader, &type, sizeof(type))) { if (!binary_read(&reader, &type, sizeof(type))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
if (type != MESSAGE_TYPE_READ_SUCCESS) { if (type != MESSAGE_TYPE_READ_SUCCESS) {
// TODO tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
}
// length
if (!binary_read(&reader, NULL, sizeof(uint32_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
// Skip message length
if (!binary_read(&reader, NULL, sizeof(uint32_t))) {
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return;
}
// Read chunk size
uint32_t chunk_size; uint32_t chunk_size;
if (!binary_read(&reader, &chunk_size, sizeof(chunk_size))) { if (!binary_read(&reader, &chunk_size, sizeof(chunk_size))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
// Calculate which chunks we need
int off = tdfs->operations[opidx].off; int off = tdfs->operations[opidx].off;
int len = tdfs->operations[opidx].len; int len = tdfs->operations[opidx].len;
uint32_t first_byte = off; if (len == 0) {
uint32_t last_byte = off + len - 1; // TODO: what if len=0 ? tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_SUCCESS };
return;
uint32_t first_chunk = first_byte / chunk_size;
uint32_t last_chunk = last_byte / chunk_size;
uint32_t num_hashes;
if (!binary_read(&reader, &num_hashes, sizeof(num_hashes))) {
// TODO
} }
Range *ranges = malloc(num_hashes * sizeof(Range)); uint32_t first_byte = off;
uint32_t last_byte = off + len - 1;
uint32_t first_chunk = first_byte / chunk_size;
uint32_t last_chunk = last_byte / chunk_size;
uint32_t num_chunks_needed = last_chunk - first_chunk + 1;
// Read number of hashes
uint32_t num_hashes;
if (!binary_read(&reader, &num_hashes, sizeof(num_hashes))) {
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return;
}
// Allocate ranges
Range *ranges = malloc(num_chunks_needed * sizeof(Range));
if (ranges == NULL) { if (ranges == NULL) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
char *ptr = tdfs->operations[opidx].ptr; char *ptr = tdfs->operations[opidx].ptr;
for (uint32_t i = first_chunk; i <= last_chunk; i++) { int num_ranges_with_data = 0;
uint32_t first_byte_within_chunk = 0;
uint32_t last_byte_within_chunk = chunk_size-1; // TODO: what if chunk size is 0 ?
if (i == first_chunk) first_byte_within_chunk = first_byte % chunk_size;
if (i == last_chunk) last_byte_within_chunk = last_byte % chunk_size;
uint32_t length_within_chunk = 1 + last_byte_within_chunk - first_byte_within_chunk;
if (i - first_chunk < num_hashes) {
// Parse each chunk's hash and server locations
for (uint32_t i = 0; i < num_hashes; i++) {
// Read hash
SHA256 hash; SHA256 hash;
if (!binary_read(&reader, &hash, sizeof(hash))) { if (!binary_read(&reader, &hash, sizeof(hash))) {
// TODO free(ranges);
} tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
ranges[i - first_chunk] = (Range) {
.hash = hash,
.dst = ptr,
.offset_within_chunk = first_byte_within_chunk,
.length_within_chunk = length_within_chunk,
};
} else {
memset(ptr, 0, length_within_chunk);
}
ptr += length_within_chunk;
}
// Check there is nothing else to read
if (binary_read(&reader, NULL, 1)) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_LIST_ERROR };
return; return;
} }
// Read number of servers
uint32_t num_servers;
if (!binary_read(&reader, &num_servers, sizeof(num_servers))) {
free(ranges);
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return;
}
// Parse IPv4 addresses
uint32_t num_ipv4;
if (!binary_read(&reader, &num_ipv4, sizeof(num_ipv4))) {
free(ranges);
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
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))) {
free(ranges);
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
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);
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
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);
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return;
}
}
if (!found) {
free(ranges);
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return;
}
// Calculate byte range for this chunk
uint32_t chunk_idx = first_chunk + i;
uint32_t first_in_chunk = (chunk_idx == first_chunk) ? (first_byte % chunk_size) : 0;
uint32_t last_in_chunk = (chunk_idx == last_chunk) ? (last_byte % chunk_size) : (chunk_size - 1);
uint32_t len_in_chunk = 1 + last_in_chunk - first_in_chunk;
// Fill in range info
ranges[i].hash = hash;
ranges[i].dst = ptr;
ranges[i].offset_within_chunk = first_in_chunk;
ranges[i].length_within_chunk = len_in_chunk;
ranges[i].server_addr = server_addr;
ranges[i].chunk_server_idx = -1;
ptr += len_in_chunk;
num_ranges_with_data++;
}
// Fill remaining chunks with zeros (sparse file)
for (uint32_t i = num_hashes; i < num_chunks_needed; i++) {
uint32_t chunk_idx = first_chunk + i;
uint32_t first_in_chunk = (chunk_idx == first_chunk) ? (first_byte % chunk_size) : 0;
uint32_t last_in_chunk = (chunk_idx == last_chunk) ? (last_byte % chunk_size) : (chunk_size - 1);
uint32_t len_in_chunk = 1 + last_in_chunk - first_in_chunk;
memset(ptr, 0, len_in_chunk);
ptr += len_in_chunk;
}
// Store range info
tdfs->operations[opidx].ranges = ranges; tdfs->operations[opidx].ranges = ranges;
tdfs->operations[opidx].ranges_head = 0; tdfs->operations[opidx].ranges_head = 0;
tdfs->operations[opidx].ranges_count = num_hashes; tdfs->operations[opidx].ranges_count = num_ranges_with_data;
tdfs->operations[opidx].num_pending = 0; tdfs->operations[opidx].num_pending = 0;
// TODO: start N downloads // Start first download
if (num_ranges_with_data > 0) {
Range *r = &ranges[0];
int cs_idx = get_chunk_server_connection(tdfs, r->server_addr);
if (cs_idx < 0) {
free(ranges);
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return;
} }
break; r->chunk_server_idx = cs_idx;
default: if (send_download_chunk(tdfs, cs_idx, r->hash, r->offset_within_chunk,
{ r->length_within_chunk, opidx, 0) < 0) {
free(ranges);
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return;
}
tdfs->operations[opidx].num_pending = 1;
tdfs->operations[opidx].ranges_head = 1;
} else {
// No chunks to download
free(ranges);
tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_SUCCESS };
}
} else {
// Handle chunk download response
int range_idx = request_tag;
BinaryReader reader = { msg.ptr, msg.len, 0 }; BinaryReader reader = { msg.ptr, msg.len, 0 };
// version // Parse response
if (!binary_read(&reader, NULL, sizeof(uint16_t))) { if (!binary_read(&reader, NULL, sizeof(uint16_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
uint16_t type; uint16_t type;
if (!binary_read(&reader, &type, sizeof(type))) { if (!binary_read(&reader, &type, sizeof(type))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
if (type != MESSAGE_TYPE_DOWNLOAD_CHUNK_SUCCESS) { if (type != MESSAGE_TYPE_DOWNLOAD_CHUNK_SUCCESS) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
// length
if (!binary_read(&reader, NULL, sizeof(uint32_t))) { if (!binary_read(&reader, NULL, sizeof(uint32_t))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
uint32_t data_len; uint32_t data_len;
if (!binary_read(&reader, &data_len, sizeof(data_len))) { if (!binary_read(&reader, &data_len, sizeof(data_len))) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
uint8_t *data = reader.src + reader.cur; uint8_t *data = reader.src + reader.cur;
if (!binary_read(&reader, NULL, data_len)) { if (!binary_read(&reader, NULL, data_len)) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
// Check there is nothing else to read
if (binary_read(&reader, NULL, 1)) { if (binary_read(&reader, NULL, 1)) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_LIST_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_ERROR };
return; return;
} }
memcpy(tdfs->operations[opidx].ranges[request_tag].dst, data, data_len); // Copy data to destination
if (range_idx >= 0 && range_idx < tdfs->operations[opidx].ranges_count) {
memcpy(tdfs->operations[opidx].ranges[range_idx].dst, data, data_len);
}
tdfs->operations[opidx].num_pending--; tdfs->operations[opidx].num_pending--;
// Start next download (sequential)
int next_idx = tdfs->operations[opidx].ranges_head;
if (next_idx < tdfs->operations[opidx].ranges_count) {
Range *r = &tdfs->operations[opidx].ranges[next_idx];
int cs_idx = get_chunk_server_connection(tdfs, r->server_addr);
if (cs_idx >= 0) {
r->chunk_server_idx = cs_idx;
if (send_download_chunk(tdfs, cs_idx, r->hash, r->offset_within_chunk,
r->length_within_chunk, opidx, next_idx) == 0) {
tdfs->operations[opidx].num_pending++;
tdfs->operations[opidx].ranges_head++;
}
}
}
// Check if done
if (tdfs->operations[opidx].num_pending == 0) { if (tdfs->operations[opidx].num_pending == 0) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_READ_SUCCESS }; free(tdfs->operations[opidx].ranges);
} else { tdfs->operations[opidx].ranges = NULL;
// TODO: start operation tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_READ_SUCCESS };
} }
} }
break;
}
} }
static void process_event_for_write(TinyDFS *tdfs, static void process_event_for_write(TinyDFS *tdfs,
int opidx, int request_tag, ByteView msg) int opidx, int request_tag, ByteView msg)
{ {
if (msg.len == 0) { if (msg.len == 0) {
tdfs->operations[opidx].result = (Result) { TINYDFS_RESULT_WRITE_ERROR }; tdfs->operations[opidx].result = (TinyDFS_Result) { TINYDFS_RESULT_WRITE_ERROR };
return; return;
} }
@@ -4472,7 +4645,7 @@ static void process_event(TinyDFS *tdfs,
} }
static bool static bool
translate_operation_into_result(TinyDFS *tdfs, int opidx, Result *result) translate_operation_into_result(TinyDFS *tdfs, int opidx, TinyDFS_Result *result)
{ {
if (tdfs->operations[opidx].result.type == TINYDFS_RESULT_EMPTY) if (tdfs->operations[opidx].result.type == TINYDFS_RESULT_EMPTY)
return false; return false;
+6 -9
View File
@@ -24,16 +24,13 @@ typedef struct {
TinyDFS_ResultType type; TinyDFS_ResultType type;
} TinyDFS_Result; } TinyDFS_Result;
typedef int TinyDFS_Handle;
#define TINYDFS_INVALID ((TinyDFS_Handle) -1)
TinyDFS *tinydfs_init(char *addr, uint16_t port); TinyDFS *tinydfs_init(char *addr, uint16_t port);
void tinydfs_free(TinyDFS *tdfs); void tinydfs_free(TinyDFS *tdfs);
int tinydfs_wait(TinyDFS *tdfs, TinyDFS_Handle handle, TinyDFS_Result *result, int timeout); void tinydfs_wait(TinyDFS *tdfs, int opidx, TinyDFS_Result *result, int timeout);
TinyDFS_Handle tinydfs_submit_create (TinyDFS *tdfs, char *path, int path_len, bool is_dir, unsigned int chunk_size); int tinydfs_submit_create (TinyDFS *tdfs, char *path, int path_len, bool is_dir, unsigned int chunk_size);
TinyDFS_Handle tinydfs_submit_delete (TinyDFS *tdfs, char *path, int path_len); int tinydfs_submit_delete (TinyDFS *tdfs, char *path, int path_len);
TinyDFS_Handle tinydfs_submit_list (TinyDFS *tdfs, char *path, int path_len); int tinydfs_submit_list (TinyDFS *tdfs, char *path, int path_len);
TinyDFS_Handle tinydfs_submit_read (TinyDFS *tdfs, char *path, int path_len, void *dst, int len); int tinydfs_submit_read (TinyDFS *tdfs, char *path, int path_len, int off, void *dst, int len);
TinyDFS_Handle tinydfs_submit_write (TinyDFS *tdfs, char *path, int path_len, void *src, int len); int tinydfs_submit_write (TinyDFS *tdfs, char *path, int path_len, int off, void *src, int len);
#endif // TINYDFS_INCLUDED #endif // TINYDFS_INCLUDED
+5 -5
View File
@@ -7,31 +7,31 @@ int main(void)
if (tdfs == NULL) if (tdfs == NULL)
return -1; return -1;
if (tinydfs_submit_create(tdfs, "/my_file_1", -1, false, 1024) == TINYDFS_INVALID) { if (tinydfs_submit_create(tdfs, "/my_file_1", -1, false, 1024) < 0) {
tinydfs_free(tdfs); tinydfs_free(tdfs);
return -1; return -1;
} }
if (tinydfs_submit_create(tdfs, "/my_file_2", -1, false, 1024) == TINYDFS_INVALID) { if (tinydfs_submit_create(tdfs, "/my_file_2", -1, false, 1024) < 0) {
tinydfs_free(tdfs); tinydfs_free(tdfs);
return -1; return -1;
} }
char buff_1[] = "This is file 1"; char buff_1[] = "This is file 1";
if (tinydfs_submit_write(tdfs, "/my_file_1", -1, buff_1, sizeof(buff_1)-1) == TINYDFS_INVALID) { if (tinydfs_submit_write(tdfs, "/my_file_1", -1, 0, buff_1, sizeof(buff_1)-1) < 0) {
tinydfs_free(tdfs); tinydfs_free(tdfs);
return -1; return -1;
} }
char buff_2[] = "This is file 1"; char buff_2[] = "This is file 1";
if (tinydfs_submit_write(tdfs, "/my_file_1", -1, buff_2, sizeof(buff_2)-1) == TINYDFS_INVALID) { if (tinydfs_submit_write(tdfs, "/my_file_1", -1, 0, buff_2, sizeof(buff_2)-1) < 0) {
tinydfs_free(tdfs); tinydfs_free(tdfs);
return -1; return -1;
} }
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
TinyDFS_Result result; TinyDFS_Result result;
tinydfs_wait(tdfs, TINYDFS_INVALID, &result, -1); tinydfs_wait(tdfs, -1, &result, -1);
} }
tinydfs_free(tdfs); tinydfs_free(tdfs);