mirror of
https://github.com/polhenarejos/pico-keys-sdk.git
synced 2026-08-23 21:16:56 +01:00
Fix FS record publication ordering (#35).
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
+20
-9
@@ -82,15 +82,16 @@ static size_t flash_record_size(uintptr_t base) {
|
||||
return 2 * sizeof(uintptr_t) + sizeof(uint16_t) + flash_record_length_size(base) + flash_record_payload_size(base);
|
||||
}
|
||||
|
||||
static uintptr_t allocate_free_addr(uint32_t size, bool persistent) {
|
||||
static uintptr_t allocate_free_addr(uint32_t size, bool persistent, uintptr_t *publish_at) {
|
||||
size_t length_size = size >= FLASH_FILE_EXTENDED_LENGTH ? FLASH_FILE_EXTENDED_LENGTH_SIZE : FLASH_FILE_LEGACY_LENGTH_SIZE;
|
||||
size_t overhead = 2 * sizeof(uintptr_t) + sizeof(uint16_t) + length_size;
|
||||
size_t real_size = 0;
|
||||
uintptr_t next_base = 0x0, endp = end_data_pool, startp = start_data_pool;
|
||||
|
||||
if (size > SIZE_MAX - overhead) {
|
||||
if (!publish_at || size > SIZE_MAX - overhead) {
|
||||
return 0x0;
|
||||
}
|
||||
*publish_at = 0x0;
|
||||
real_size = overhead + size;
|
||||
if (persistent) {
|
||||
endp = end_rom_pool;
|
||||
@@ -121,12 +122,17 @@ static uintptr_t allocate_free_addr(uint32_t size, bool persistent) {
|
||||
}
|
||||
|
||||
if (gap_reusable && potential_addr >= gap_start && potential_addr >= startp) {
|
||||
flash_program_uintptr(potential_addr, next_base);
|
||||
flash_program_uintptr(potential_addr + sizeof(uintptr_t), base);
|
||||
if (next_base != 0x0) {
|
||||
flash_program_uintptr(next_base + sizeof(uintptr_t), potential_addr);
|
||||
int r = flash_program_uintptr(potential_addr, next_base);
|
||||
if (r == PICOKEYS_OK) {
|
||||
r = flash_program_uintptr(potential_addr + sizeof(uintptr_t), base);
|
||||
}
|
||||
flash_program_uintptr(base, potential_addr);
|
||||
if (r == PICOKEYS_OK && next_base != 0x0) {
|
||||
r = flash_program_uintptr(next_base + sizeof(uintptr_t), potential_addr);
|
||||
}
|
||||
if (r != PICOKEYS_OK) {
|
||||
return 0x0;
|
||||
}
|
||||
*publish_at = base;
|
||||
return potential_addr;
|
||||
}
|
||||
if (next_base == 0x0) {
|
||||
@@ -205,7 +211,8 @@ static int flash_write_data_to_file_internal(file_t *file, const_byte_array_t da
|
||||
|
||||
file_t old_file = *file;
|
||||
bool replacing = old_file.data != NULL;
|
||||
uintptr_t new_addr = allocate_free_addr(new_size, (file_get_type(file) & FILE_PERSISTENT) == FILE_PERSISTENT);
|
||||
uintptr_t publish_at = 0x0;
|
||||
uintptr_t new_addr = allocate_free_addr(new_size, (file_get_type(file) & FILE_PERSISTENT) == FILE_PERSISTENT, &publish_at);
|
||||
if (new_addr == 0x0) {
|
||||
return PICOKEYS_ERR_NO_MEMORY;
|
||||
}
|
||||
@@ -235,9 +242,13 @@ static int flash_write_data_to_file_internal(file_t *file, const_byte_array_t da
|
||||
if (r == PICOKEYS_OK && partial && replacing && write_end < old_size) {
|
||||
r = copy_file_range(&old_file, write_end, payload + write_end, old_size - write_end);
|
||||
}
|
||||
if (r == PICOKEYS_OK && 2 * sizeof(uintptr_t) + sizeof(uint16_t) + length_size + new_size > FLASH_SECTOR_SIZE && !flash_commit_sync(5000u)) {
|
||||
/* Publish only after the record is complete; across sectors the record must be durable first. */
|
||||
if (r == PICOKEYS_OK && (publish_at & ~(uintptr_t)(FLASH_SECTOR_SIZE - 1)) != (new_addr & ~(uintptr_t)(FLASH_SECTOR_SIZE - 1)) && !flash_commit_sync(5000u)) {
|
||||
r = PICOKEYS_ERR_MEMORY_FATAL;
|
||||
}
|
||||
if (r == PICOKEYS_OK) {
|
||||
r = flash_program_uintptr(publish_at, new_addr);
|
||||
}
|
||||
if (r != PICOKEYS_OK) {
|
||||
flash_clear_file(&new_file);
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user