Add TOASTY_WRITE_CREATE_IF_MISSING flag for server-side file auto-creation
Adds support for automatically creating files when write operations target non-existent files. This is essential for REST PUT operations which should be able to create new resources. Implementation: - Added TOASTY_WRITE_CREATE_IF_MISSING flag to ToastyFS API header - Updated toasty_write() and toasty_begin_write() to accept flags parameter - Client sends write flags in MESSAGE_TYPE_WRITE message to metadata server - Metadata server parses flags and handles file auto-creation atomically: * When write fails with FILETREE_NOENT and flag is set * Logs creation to WAL for crash consistency * Creates file with default 4096-byte chunk size * Retries write with newly created file's generation tag - Updated web proxy PUT handler to use TOASTY_WRITE_CREATE_IF_MISSING - Updated examples and simulation client for new API signature Benefits: - Works for both sync and async APIs - Single round trip (atomic server-side operation) - Prevents race conditions - Proper WAL logging ensures crash consistency
This commit is contained in:
@@ -537,6 +537,10 @@ process_client_write(MetadataServer *state, int conn_idx, ByteView msg)
|
||||
if (!binary_read(&reader, &expect_gen, sizeof(expect_gen)))
|
||||
return -1;
|
||||
|
||||
uint32_t flags;
|
||||
if (!binary_read(&reader, &flags, sizeof(flags)))
|
||||
return -1;
|
||||
|
||||
char path_mem[1<<10];
|
||||
uint16_t path_len;
|
||||
|
||||
@@ -634,6 +638,28 @@ process_client_write(MetadataServer *state, int conn_idx, ByteView msg)
|
||||
int ret = file_tree_write(&state->file_tree, path, offset, length,
|
||||
num_chunks, expect_gen, &new_gen, new_hashes, removed_hashes, &num_removed);
|
||||
|
||||
// If write failed because file doesn't exist and CREATE_IF_MISSING flag is set,
|
||||
// create the file and retry the write
|
||||
#define TOASTY_WRITE_CREATE_IF_MISSING (1 << 0)
|
||||
if (ret == FILETREE_NOENT && (flags & TOASTY_WRITE_CREATE_IF_MISSING)) {
|
||||
// Create the file with default chunk size of 4096 bytes
|
||||
uint64_t chunk_size = 4096;
|
||||
|
||||
// Log the creation in the WAL
|
||||
if (wal_append_create(&state->wal, path, false, chunk_size) < 0) {
|
||||
assert(0); // TODO
|
||||
}
|
||||
|
||||
uint64_t create_gen;
|
||||
int create_ret = file_tree_create_entity(&state->file_tree, path, false, chunk_size, &create_gen);
|
||||
|
||||
if (create_ret == 0) {
|
||||
// File created successfully, retry the write with the new generation
|
||||
ret = file_tree_write(&state->file_tree, path, offset, length,
|
||||
num_chunks, create_gen, &new_gen, new_hashes, removed_hashes, &num_removed);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
|
||||
string desc = file_tree_strerror(ret);
|
||||
|
||||
Reference in New Issue
Block a user