index-fs: append log records in place and add opt-in put precheck bypass
This commit is contained in:
parent
26fa4cce66
commit
bc55ed994b
|
|
@ -43,6 +43,10 @@ typedef struct {
|
||||||
uint64_t last_ingest_time_ns;
|
uint64_t last_ingest_time_ns;
|
||||||
amduat_asl_snapshot_id_t next_snapshot_id;
|
amduat_asl_snapshot_id_t next_snapshot_id;
|
||||||
bool snapshot_state_initialized;
|
bool snapshot_state_initialized;
|
||||||
|
bool log_tail_initialized;
|
||||||
|
uint64_t log_tail_logseq;
|
||||||
|
uint8_t log_tail_hash[32];
|
||||||
|
bool skip_exists_precheck;
|
||||||
void *open_segments;
|
void *open_segments;
|
||||||
pthread_mutex_t write_mutex;
|
pthread_mutex_t write_mutex;
|
||||||
uint32_t write_depth;
|
uint32_t write_depth;
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,19 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_impl(
|
||||||
amduat_reference_t *out_ref,
|
amduat_reference_t *out_ref,
|
||||||
amduat_asl_index_state_t *out_state);
|
amduat_asl_index_state_t *out_state);
|
||||||
|
|
||||||
|
static bool amduat_asl_store_index_fs_env_truthy(const char *value) {
|
||||||
|
if (value == NULL || value[0] == '\0') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (strcmp(value, "1") == 0 || strcmp(value, "true") == 0 ||
|
||||||
|
strcmp(value, "TRUE") == 0 || strcmp(value, "yes") == 0 ||
|
||||||
|
strcmp(value, "YES") == 0 || strcmp(value, "on") == 0 ||
|
||||||
|
strcmp(value, "ON") == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int amduat_asl_store_index_fs_lockfile_acquire(
|
static int amduat_asl_store_index_fs_lockfile_acquire(
|
||||||
amduat_asl_store_index_fs_t *fs) {
|
amduat_asl_store_index_fs_t *fs) {
|
||||||
char lock_path[AMDUAT_ASL_STORE_INDEX_FS_ROOT_MAX + 32];
|
char lock_path[AMDUAT_ASL_STORE_INDEX_FS_ROOT_MAX + 32];
|
||||||
|
|
@ -194,6 +207,8 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_begin_write(
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
}
|
}
|
||||||
fs->write_lock_fd = lock_fd;
|
fs->write_lock_fd = lock_fd;
|
||||||
|
/* Another store instance may have appended while we were unlocked. */
|
||||||
|
fs->log_tail_initialized = false;
|
||||||
}
|
}
|
||||||
fs->write_depth += 1u;
|
fs->write_depth += 1u;
|
||||||
return AMDUAT_ASL_STORE_OK;
|
return AMDUAT_ASL_STORE_OK;
|
||||||
|
|
@ -1193,28 +1208,6 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_load_log(
|
||||||
return AMDUAT_ASL_STORE_OK;
|
return AMDUAT_ASL_STORE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static amduat_asl_store_error_t amduat_asl_store_index_fs_write_log(
|
|
||||||
const char *log_path,
|
|
||||||
const char *log_dir,
|
|
||||||
amduat_asl_log_record_t *records,
|
|
||||||
size_t record_count) {
|
|
||||||
amduat_octets_t log_bytes;
|
|
||||||
amduat_asl_store_index_fs_write_status_t status;
|
|
||||||
|
|
||||||
if (!amduat_enc_asl_log_encode_v1(records, record_count, &log_bytes)) {
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = amduat_asl_store_index_fs_write_replace(log_dir, log_path,
|
|
||||||
log_bytes.data,
|
|
||||||
log_bytes.len);
|
|
||||||
amduat_octets_free(&log_bytes);
|
|
||||||
if (status == AMDUAT_ASL_STORE_INDEX_FS_WRITE_OK) {
|
|
||||||
return AMDUAT_ASL_STORE_OK;
|
|
||||||
}
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool amduat_asl_store_index_fs_encode_artifact_ref(
|
static bool amduat_asl_store_index_fs_encode_artifact_ref(
|
||||||
amduat_reference_t ref,
|
amduat_reference_t ref,
|
||||||
uint8_t *out,
|
uint8_t *out,
|
||||||
|
|
@ -1250,6 +1243,240 @@ static bool amduat_asl_store_index_fs_encode_artifact_ref(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static amduat_asl_store_error_t amduat_asl_store_index_fs_load_log_tail(
|
||||||
|
const char *log_path,
|
||||||
|
uint64_t *out_last_logseq,
|
||||||
|
uint8_t out_last_hash[AMDUAT_ASL_STORE_INDEX_FS_LOG_HASH_LEN]) {
|
||||||
|
int fd;
|
||||||
|
uint8_t *header_bytes = NULL;
|
||||||
|
size_t header_size = 0u;
|
||||||
|
uint64_t last_logseq = 0u;
|
||||||
|
uint8_t prev_hash[AMDUAT_ASL_STORE_INDEX_FS_LOG_HASH_LEN];
|
||||||
|
bool seen_record = false;
|
||||||
|
|
||||||
|
if (log_path == NULL || out_last_logseq == NULL || out_last_hash == NULL) {
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(prev_hash, 0, sizeof(prev_hash));
|
||||||
|
fd = open(log_path, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
if (errno == ENOENT || errno == ENOTDIR) {
|
||||||
|
*out_last_logseq = 0u;
|
||||||
|
memcpy(out_last_hash, prev_hash, sizeof(prev_hash));
|
||||||
|
return AMDUAT_ASL_STORE_OK;
|
||||||
|
}
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_asl_store_index_fs_log_read_header_bytes(fd,
|
||||||
|
&header_bytes,
|
||||||
|
&header_size)) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||||
|
}
|
||||||
|
free(header_bytes);
|
||||||
|
(void)header_size;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
uint8_t record_header[16];
|
||||||
|
uint64_t logseq;
|
||||||
|
uint32_t record_type;
|
||||||
|
uint32_t payload_len;
|
||||||
|
uint8_t *payload = NULL;
|
||||||
|
uint8_t record_hash[AMDUAT_ASL_STORE_INDEX_FS_LOG_HASH_LEN];
|
||||||
|
uint8_t expected_hash[AMDUAT_ASL_STORE_INDEX_FS_LOG_HASH_LEN];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = amduat_asl_store_index_fs_log_read_exact_eof(fd,
|
||||||
|
record_header,
|
||||||
|
sizeof(record_header));
|
||||||
|
if (rc == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rc < 0) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
logseq = amduat_asl_store_index_fs_load_u64_le(record_header);
|
||||||
|
if (seen_record && logseq <= last_logseq) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||||
|
}
|
||||||
|
record_type =
|
||||||
|
amduat_asl_store_index_fs_log_load_u32_le(record_header + 8u);
|
||||||
|
payload_len =
|
||||||
|
amduat_asl_store_index_fs_log_load_u32_le(record_header + 12u);
|
||||||
|
|
||||||
|
if (payload_len != 0u) {
|
||||||
|
payload = (uint8_t *)malloc(payload_len);
|
||||||
|
if (payload == NULL) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
if (!amduat_asl_store_index_fs_log_read_exact(fd,
|
||||||
|
payload,
|
||||||
|
payload_len)) {
|
||||||
|
free(payload);
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_asl_store_index_fs_log_read_exact(fd,
|
||||||
|
record_hash,
|
||||||
|
sizeof(record_hash))) {
|
||||||
|
free(payload);
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_asl_store_index_fs_log_hash_record(prev_hash,
|
||||||
|
logseq,
|
||||||
|
record_type,
|
||||||
|
payload_len,
|
||||||
|
payload,
|
||||||
|
expected_hash) ||
|
||||||
|
memcmp(expected_hash, record_hash, sizeof(record_hash)) != 0) {
|
||||||
|
free(payload);
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(prev_hash, record_hash, sizeof(prev_hash));
|
||||||
|
last_logseq = logseq;
|
||||||
|
seen_record = true;
|
||||||
|
free(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
*out_last_logseq = last_logseq;
|
||||||
|
memcpy(out_last_hash, prev_hash, sizeof(prev_hash));
|
||||||
|
return AMDUAT_ASL_STORE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static amduat_asl_store_error_t amduat_asl_store_index_fs_append_log_record_file(
|
||||||
|
const char *index_path,
|
||||||
|
const char *log_path,
|
||||||
|
uint64_t prev_logseq,
|
||||||
|
const uint8_t prev_hash[AMDUAT_ASL_STORE_INDEX_FS_LOG_HASH_LEN],
|
||||||
|
uint32_t record_type,
|
||||||
|
const uint8_t *payload,
|
||||||
|
size_t payload_len,
|
||||||
|
uint64_t *out_new_logseq,
|
||||||
|
uint8_t out_new_hash[AMDUAT_ASL_STORE_INDEX_FS_LOG_HASH_LEN]) {
|
||||||
|
int fd = -1;
|
||||||
|
struct stat st;
|
||||||
|
bool needs_header = false;
|
||||||
|
uint8_t *header_bytes = NULL;
|
||||||
|
size_t header_size = 0u;
|
||||||
|
uint8_t record_header[16];
|
||||||
|
uint8_t record_hash[AMDUAT_ASL_STORE_INDEX_FS_LOG_HASH_LEN];
|
||||||
|
uint64_t new_logseq;
|
||||||
|
|
||||||
|
if (index_path == NULL || log_path == NULL || prev_hash == NULL ||
|
||||||
|
out_new_logseq == NULL || out_new_hash == NULL) {
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
if (payload_len != 0u && payload == NULL) {
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
if (payload_len > UINT32_MAX || prev_logseq == UINT64_MAX) {
|
||||||
|
return AMDUAT_ASL_STORE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_logseq = prev_logseq + 1u;
|
||||||
|
|
||||||
|
fd = open(log_path, O_RDWR | O_CREAT, 0644);
|
||||||
|
if (fd < 0) {
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
if (fstat(fd, &st) != 0) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
needs_header = st.st_size == 0;
|
||||||
|
if (!needs_header) {
|
||||||
|
if (lseek(fd, 0, SEEK_SET) < 0) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
if (!amduat_asl_store_index_fs_log_read_header_bytes(fd,
|
||||||
|
&header_bytes,
|
||||||
|
&header_size)) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||||
|
}
|
||||||
|
free(header_bytes);
|
||||||
|
(void)header_size;
|
||||||
|
}
|
||||||
|
if (lseek(fd, 0, SEEK_END) < 0) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
if (needs_header) {
|
||||||
|
uint8_t header[AMDUAT_ASL_STORE_INDEX_FS_LOG_HEADER_LEN];
|
||||||
|
memcpy(header,
|
||||||
|
k_amduat_asl_store_index_fs_log_magic,
|
||||||
|
AMDUAT_ASL_STORE_INDEX_FS_LOG_MAGIC_LEN);
|
||||||
|
amduat_asl_store_index_fs_log_store_u32_le(
|
||||||
|
header + AMDUAT_ASL_STORE_INDEX_FS_LOG_MAGIC_LEN,
|
||||||
|
AMDUAT_ASL_STORE_INDEX_FS_LOG_VERSION);
|
||||||
|
amduat_asl_store_index_fs_log_store_u32_le(
|
||||||
|
header + AMDUAT_ASL_STORE_INDEX_FS_LOG_MAGIC_LEN + 4u,
|
||||||
|
AMDUAT_ASL_STORE_INDEX_FS_LOG_HEADER_LEN);
|
||||||
|
amduat_asl_store_index_fs_log_store_u64_le(
|
||||||
|
header + AMDUAT_ASL_STORE_INDEX_FS_LOG_MAGIC_LEN + 8u,
|
||||||
|
0u);
|
||||||
|
if (!amduat_asl_store_index_fs_log_write_exact(fd, header, sizeof(header))) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_asl_store_index_fs_log_hash_record(prev_hash,
|
||||||
|
new_logseq,
|
||||||
|
record_type,
|
||||||
|
(uint32_t)payload_len,
|
||||||
|
payload,
|
||||||
|
record_hash)) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_asl_store_index_fs_log_store_u64_le(record_header, new_logseq);
|
||||||
|
amduat_asl_store_index_fs_log_store_u32_le(record_header + 8u, record_type);
|
||||||
|
amduat_asl_store_index_fs_log_store_u32_le(record_header + 12u,
|
||||||
|
(uint32_t)payload_len);
|
||||||
|
if (!amduat_asl_store_index_fs_log_write_exact(fd,
|
||||||
|
record_header,
|
||||||
|
sizeof(record_header)) ||
|
||||||
|
(payload_len != 0u &&
|
||||||
|
!amduat_asl_store_index_fs_log_write_exact(fd, payload, payload_len)) ||
|
||||||
|
!amduat_asl_store_index_fs_log_write_exact(fd,
|
||||||
|
record_hash,
|
||||||
|
sizeof(record_hash))) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fsync(fd) != 0) {
|
||||||
|
close(fd);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
if (close(fd) != 0) {
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
if (!amduat_asl_store_index_fs_fsync_directory(index_path)) {
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_new_logseq = new_logseq;
|
||||||
|
memcpy(out_new_hash, record_hash, sizeof(record_hash));
|
||||||
|
return AMDUAT_ASL_STORE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static amduat_asl_store_error_t amduat_asl_store_index_fs_append_log_record_unlocked(
|
static amduat_asl_store_error_t amduat_asl_store_index_fs_append_log_record_unlocked(
|
||||||
amduat_asl_store_index_fs_t *fs,
|
amduat_asl_store_index_fs_t *fs,
|
||||||
uint32_t record_type,
|
uint32_t record_type,
|
||||||
|
|
@ -1258,11 +1485,8 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_append_log_record_unlo
|
||||||
amduat_asl_index_state_t *out_state) {
|
amduat_asl_index_state_t *out_state) {
|
||||||
char *index_path = NULL;
|
char *index_path = NULL;
|
||||||
char *log_path = NULL;
|
char *log_path = NULL;
|
||||||
amduat_asl_log_record_t *log_records = NULL;
|
uint64_t new_logseq = 0u;
|
||||||
size_t log_count = 0u;
|
uint8_t new_hash[AMDUAT_ASL_STORE_INDEX_FS_LOG_HASH_LEN];
|
||||||
amduat_asl_log_record_t *next = NULL;
|
|
||||||
uint64_t new_logseq;
|
|
||||||
uint8_t *payload_copy = NULL;
|
|
||||||
amduat_asl_store_error_t err;
|
amduat_asl_store_error_t err;
|
||||||
|
|
||||||
if (fs == NULL) {
|
if (fs == NULL) {
|
||||||
|
|
@ -1287,74 +1511,38 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_append_log_record_unlo
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = amduat_asl_store_index_fs_load_log(log_path, &log_records, &log_count);
|
if (!fs->log_tail_initialized) {
|
||||||
|
err = amduat_asl_store_index_fs_load_log_tail(log_path,
|
||||||
|
&fs->log_tail_logseq,
|
||||||
|
fs->log_tail_hash);
|
||||||
if (err != AMDUAT_ASL_STORE_OK) {
|
if (err != AMDUAT_ASL_STORE_OK) {
|
||||||
amduat_asl_store_index_fs_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
free(log_path);
|
||||||
free(index_path);
|
free(index_path);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (log_count != 0u && log_records == NULL) {
|
fs->log_tail_initialized = true;
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log_count == 0u) {
|
err = amduat_asl_store_index_fs_append_log_record_file(
|
||||||
log_records = (amduat_asl_log_record_t *)calloc(1u,
|
index_path,
|
||||||
sizeof(*log_records));
|
log_path,
|
||||||
if (log_records == NULL) {
|
fs->log_tail_logseq,
|
||||||
free(log_path);
|
fs->log_tail_hash,
|
||||||
free(index_path);
|
record_type,
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
payload,
|
||||||
}
|
payload_len,
|
||||||
new_logseq = 1u;
|
&new_logseq,
|
||||||
} else {
|
new_hash);
|
||||||
if (log_records[log_count - 1u].logseq == UINT64_MAX) {
|
|
||||||
amduat_asl_store_index_fs_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
new_logseq = log_records[log_count - 1u].logseq + 1u;
|
|
||||||
next = (amduat_asl_log_record_t *)realloc(
|
|
||||||
log_records, (log_count + 1u) * sizeof(*log_records));
|
|
||||||
if (next == NULL) {
|
|
||||||
amduat_asl_store_index_fs_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
log_records = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (payload_len != 0u) {
|
|
||||||
payload_copy = (uint8_t *)malloc(payload_len);
|
|
||||||
if (payload_copy == NULL) {
|
|
||||||
amduat_asl_store_index_fs_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
memcpy(payload_copy, payload, payload_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
log_records[log_count].logseq = new_logseq;
|
|
||||||
log_records[log_count].record_type = record_type;
|
|
||||||
log_records[log_count].payload = amduat_octets(payload_copy, payload_len);
|
|
||||||
memset(log_records[log_count].record_hash, 0,
|
|
||||||
sizeof(log_records[log_count].record_hash));
|
|
||||||
log_count += 1u;
|
|
||||||
|
|
||||||
err = amduat_asl_store_index_fs_write_log(log_path, index_path,
|
|
||||||
log_records, log_count);
|
|
||||||
amduat_asl_store_index_fs_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
free(log_path);
|
||||||
free(index_path);
|
free(index_path);
|
||||||
if (err != AMDUAT_ASL_STORE_OK) {
|
if (err != AMDUAT_ASL_STORE_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs->log_tail_logseq = new_logseq;
|
||||||
|
memcpy(fs->log_tail_hash, new_hash, sizeof(new_hash));
|
||||||
|
fs->log_tail_initialized = true;
|
||||||
|
|
||||||
if (out_state != NULL &&
|
if (out_state != NULL &&
|
||||||
!amduat_asl_store_index_fs_current_state_impl(fs, out_state)) {
|
!amduat_asl_store_index_fs_current_state_impl(fs, out_state)) {
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
|
@ -4114,6 +4302,7 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
amduat_reference_t derived_ref;
|
amduat_reference_t derived_ref;
|
||||||
amduat_octets_t artifact_bytes;
|
amduat_octets_t artifact_bytes;
|
||||||
amduat_asl_index_state_t current_state;
|
amduat_asl_index_state_t current_state;
|
||||||
|
bool has_current_state = false;
|
||||||
amduat_artifact_t existing_artifact;
|
amduat_artifact_t existing_artifact;
|
||||||
amduat_asl_store_error_t err;
|
amduat_asl_store_error_t err;
|
||||||
char *index_path;
|
char *index_path;
|
||||||
|
|
@ -4121,7 +4310,6 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
char *blocks_path;
|
char *blocks_path;
|
||||||
char *segment_path;
|
char *segment_path;
|
||||||
char *block_path;
|
char *block_path;
|
||||||
char *log_path;
|
|
||||||
uint16_t shard_id;
|
uint16_t shard_id;
|
||||||
uint64_t segment_id;
|
uint64_t segment_id;
|
||||||
uint64_t local_segment_id;
|
uint64_t local_segment_id;
|
||||||
|
|
@ -4130,11 +4318,8 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
amduat_asl_extent_record_t extent;
|
amduat_asl_extent_record_t extent;
|
||||||
amduat_octets_t segment_bytes;
|
amduat_octets_t segment_bytes;
|
||||||
uint8_t segment_hash[AMDUAT_ASL_STORE_INDEX_FS_SEGMENT_HASH_LEN];
|
uint8_t segment_hash[AMDUAT_ASL_STORE_INDEX_FS_SEGMENT_HASH_LEN];
|
||||||
amduat_asl_log_record_t *log_records;
|
|
||||||
size_t log_count;
|
|
||||||
uint8_t *seal_payload;
|
uint8_t *seal_payload;
|
||||||
size_t seal_len;
|
size_t seal_len;
|
||||||
uint64_t new_logseq;
|
|
||||||
amduat_asl_store_index_fs_write_status_t write_status;
|
amduat_asl_store_index_fs_write_status_t write_status;
|
||||||
size_t artifact_len;
|
size_t artifact_len;
|
||||||
|
|
||||||
|
|
@ -4163,11 +4348,13 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
fs->shard_count);
|
fs->shard_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fs->skip_exists_precheck) {
|
||||||
if (!amduat_asl_store_index_fs_current_state_impl(ctx, ¤t_state)) {
|
if (!amduat_asl_store_index_fs_current_state_impl(ctx, ¤t_state)) {
|
||||||
amduat_reference_free(&derived_ref);
|
amduat_reference_free(&derived_ref);
|
||||||
amduat_octets_free(&artifact_bytes);
|
amduat_octets_free(&artifact_bytes);
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
}
|
}
|
||||||
|
has_current_state = true;
|
||||||
|
|
||||||
existing_artifact = amduat_artifact(amduat_octets(NULL, 0u));
|
existing_artifact = amduat_artifact(amduat_octets(NULL, 0u));
|
||||||
err = amduat_asl_store_index_fs_get_indexed_impl(ctx, derived_ref,
|
err = amduat_asl_store_index_fs_get_indexed_impl(ctx, derived_ref,
|
||||||
|
|
@ -4187,6 +4374,7 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
amduat_octets_free(&artifact_bytes);
|
amduat_octets_free(&artifact_bytes);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fs->segment_policy.small_artifact_threshold != 0u &&
|
if (fs->segment_policy.small_artifact_threshold != 0u &&
|
||||||
artifact_bytes.len <= fs->segment_policy.small_artifact_threshold &&
|
artifact_bytes.len <= fs->segment_policy.small_artifact_threshold &&
|
||||||
|
|
@ -4205,6 +4393,12 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
amduat_asl_store_index_fs_open_segment_contains(open_segment,
|
amduat_asl_store_index_fs_open_segment_contains(open_segment,
|
||||||
derived_ref)) {
|
derived_ref)) {
|
||||||
*out_ref = derived_ref;
|
*out_ref = derived_ref;
|
||||||
|
if (!has_current_state &&
|
||||||
|
!amduat_asl_store_index_fs_current_state_impl(ctx, ¤t_state)) {
|
||||||
|
amduat_octets_free(&artifact_bytes);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
has_current_state = true;
|
||||||
amduat_asl_store_index_fs_fill_index_state(out_state,
|
amduat_asl_store_index_fs_fill_index_state(out_state,
|
||||||
current_state.snapshot_id,
|
current_state.snapshot_id,
|
||||||
current_state.log_position);
|
current_state.log_position);
|
||||||
|
|
@ -4254,6 +4448,13 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!has_current_state &&
|
||||||
|
!amduat_asl_store_index_fs_current_state_impl(ctx, ¤t_state)) {
|
||||||
|
amduat_reference_free(&derived_ref);
|
||||||
|
amduat_octets_free(&artifact_bytes);
|
||||||
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
|
}
|
||||||
|
has_current_state = true;
|
||||||
amduat_asl_store_index_fs_fill_index_state(out_state,
|
amduat_asl_store_index_fs_fill_index_state(out_state,
|
||||||
current_state.snapshot_id,
|
current_state.snapshot_id,
|
||||||
current_state.log_position);
|
current_state.log_position);
|
||||||
|
|
@ -4470,75 +4671,11 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
return AMDUAT_ASL_STORE_ERR_IO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!amduat_asl_store_index_fs_layout_build_log_path(fs->root_path,
|
|
||||||
&log_path)) {
|
|
||||||
amduat_reference_free(&derived_ref);
|
|
||||||
amduat_octets_free(&artifact_bytes);
|
|
||||||
free(index_path);
|
|
||||||
free(segments_path);
|
|
||||||
free(blocks_path);
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_records = NULL;
|
|
||||||
log_count = 0u;
|
|
||||||
err = amduat_asl_store_index_fs_load_log(log_path, &log_records, &log_count);
|
|
||||||
if (err != AMDUAT_ASL_STORE_OK) {
|
|
||||||
amduat_reference_free(&derived_ref);
|
|
||||||
amduat_octets_free(&artifact_bytes);
|
|
||||||
amduat_asl_store_index_fs_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
|
||||||
free(segments_path);
|
|
||||||
free(blocks_path);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log_count != 0u && log_records == NULL) {
|
|
||||||
amduat_reference_free(&derived_ref);
|
|
||||||
amduat_octets_free(&artifact_bytes);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
|
||||||
free(segments_path);
|
|
||||||
free(blocks_path);
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log_count == 0u) {
|
|
||||||
log_records = (amduat_asl_log_record_t *)calloc(1u,
|
|
||||||
sizeof(*log_records));
|
|
||||||
if (log_records == NULL) {
|
|
||||||
amduat_reference_free(&derived_ref);
|
|
||||||
amduat_octets_free(&artifact_bytes);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
|
||||||
free(segments_path);
|
|
||||||
free(blocks_path);
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
amduat_asl_log_record_t *next = (amduat_asl_log_record_t *)realloc(
|
|
||||||
log_records, (log_count + 1u) * sizeof(*log_records));
|
|
||||||
if (next == NULL) {
|
|
||||||
amduat_reference_free(&derived_ref);
|
|
||||||
amduat_octets_free(&artifact_bytes);
|
|
||||||
amduat_enc_asl_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
|
||||||
free(segments_path);
|
|
||||||
free(blocks_path);
|
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
log_records = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
seal_len = 8u + AMDUAT_ASL_STORE_INDEX_FS_SEGMENT_HASH_LEN;
|
seal_len = 8u + AMDUAT_ASL_STORE_INDEX_FS_SEGMENT_HASH_LEN;
|
||||||
seal_payload = (uint8_t *)malloc(seal_len);
|
seal_payload = (uint8_t *)malloc(seal_len);
|
||||||
if (seal_payload == NULL) {
|
if (seal_payload == NULL) {
|
||||||
amduat_reference_free(&derived_ref);
|
amduat_reference_free(&derived_ref);
|
||||||
amduat_octets_free(&artifact_bytes);
|
amduat_octets_free(&artifact_bytes);
|
||||||
amduat_asl_store_index_fs_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
free(index_path);
|
||||||
free(segments_path);
|
free(segments_path);
|
||||||
free(blocks_path);
|
free(blocks_path);
|
||||||
|
|
@ -4554,34 +4691,13 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
seal_payload[6] = (uint8_t)((segment_id >> 48) & 0xffu);
|
seal_payload[6] = (uint8_t)((segment_id >> 48) & 0xffu);
|
||||||
seal_payload[7] = (uint8_t)((segment_id >> 56) & 0xffu);
|
seal_payload[7] = (uint8_t)((segment_id >> 56) & 0xffu);
|
||||||
memcpy(seal_payload + 8, segment_hash, sizeof(segment_hash));
|
memcpy(seal_payload + 8, segment_hash, sizeof(segment_hash));
|
||||||
|
err = amduat_asl_store_index_fs_append_log_record_unlocked(
|
||||||
if (log_count == 0u) {
|
fs,
|
||||||
new_logseq = 1u;
|
AMDUAT_ASL_LOG_RECORD_SEGMENT_SEAL,
|
||||||
} else {
|
seal_payload,
|
||||||
if (log_records[log_count - 1u].logseq == UINT64_MAX) {
|
seal_len,
|
||||||
amduat_reference_free(&derived_ref);
|
NULL);
|
||||||
amduat_octets_free(&artifact_bytes);
|
|
||||||
amduat_asl_store_index_fs_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
|
||||||
free(segments_path);
|
|
||||||
free(blocks_path);
|
|
||||||
free(seal_payload);
|
free(seal_payload);
|
||||||
return AMDUAT_ASL_STORE_ERR_IO;
|
|
||||||
}
|
|
||||||
new_logseq = log_records[log_count - 1u].logseq + 1u;
|
|
||||||
}
|
|
||||||
log_records[log_count].logseq = new_logseq;
|
|
||||||
log_records[log_count].record_type = AMDUAT_ASL_LOG_RECORD_SEGMENT_SEAL;
|
|
||||||
log_records[log_count].payload = amduat_octets(seal_payload, seal_len);
|
|
||||||
memset(log_records[log_count].record_hash, 0,
|
|
||||||
sizeof(log_records[log_count].record_hash));
|
|
||||||
log_count += 1u;
|
|
||||||
|
|
||||||
err = amduat_asl_store_index_fs_write_log(log_path, index_path,
|
|
||||||
log_records, log_count);
|
|
||||||
amduat_asl_store_index_fs_log_free(log_records, log_count);
|
|
||||||
free(log_path);
|
|
||||||
free(index_path);
|
free(index_path);
|
||||||
free(segments_path);
|
free(segments_path);
|
||||||
free(blocks_path);
|
free(blocks_path);
|
||||||
|
|
@ -4596,7 +4712,7 @@ static amduat_asl_store_error_t amduat_asl_store_index_fs_put_indexed_unlocked_i
|
||||||
*out_ref = derived_ref;
|
*out_ref = derived_ref;
|
||||||
amduat_asl_store_index_fs_fill_index_state(out_state,
|
amduat_asl_store_index_fs_fill_index_state(out_state,
|
||||||
current_state.snapshot_id,
|
current_state.snapshot_id,
|
||||||
new_logseq);
|
fs->log_tail_logseq);
|
||||||
amduat_asl_store_index_fs_update_ingest_state(fs, artifact_len);
|
amduat_asl_store_index_fs_update_ingest_state(fs, artifact_len);
|
||||||
amduat_asl_store_index_fs_maybe_snapshot_size(fs);
|
amduat_asl_store_index_fs_maybe_snapshot_size(fs);
|
||||||
return AMDUAT_ASL_STORE_OK;
|
return AMDUAT_ASL_STORE_OK;
|
||||||
|
|
@ -4800,6 +4916,7 @@ amduat_asl_store_error_t amduat_asl_store_index_fs_snapshot_create(
|
||||||
free(manifest_path);
|
free(manifest_path);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
fs->log_tail_initialized = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
amduat_asl_snapshot_manifest_t verify_manifest;
|
amduat_asl_snapshot_manifest_t verify_manifest;
|
||||||
|
|
@ -5224,6 +5341,11 @@ bool amduat_asl_store_index_fs_init(amduat_asl_store_index_fs_t *fs,
|
||||||
fs->last_ingest_time_ns = 0u;
|
fs->last_ingest_time_ns = 0u;
|
||||||
fs->next_snapshot_id = 0u;
|
fs->next_snapshot_id = 0u;
|
||||||
fs->snapshot_state_initialized = false;
|
fs->snapshot_state_initialized = false;
|
||||||
|
fs->log_tail_initialized = false;
|
||||||
|
fs->log_tail_logseq = 0u;
|
||||||
|
memset(fs->log_tail_hash, 0, sizeof(fs->log_tail_hash));
|
||||||
|
fs->skip_exists_precheck = amduat_asl_store_index_fs_env_truthy(
|
||||||
|
getenv("AMDUAT_ASL_INDEX_FS_SKIP_EXISTS_PRECHECK"));
|
||||||
fs->open_segments = NULL;
|
fs->open_segments = NULL;
|
||||||
fs->write_depth = 0u;
|
fs->write_depth = 0u;
|
||||||
fs->write_lock_fd = -1;
|
fs->write_lock_fd = -1;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue