This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit dd6058989569436deba8bcaf8a2ed1190b15e9c8 Author: zhaoxingyu1 <[email protected]> AuthorDate: Mon Sep 15 13:39:59 2025 +0800 mtdconfig/nvs: add key check when gc When key string found corrupted during garbage collection, then remove key-value pair from the flash. Signed-off-by: zhaoxingyu1 <[email protected]> --- drivers/mtd/mtd_config_nvs.c | 48 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/mtd_config_nvs.c b/drivers/mtd/mtd_config_nvs.c index e96f6f45b0f..671e7f81b18 100644 --- a/drivers/mtd/mtd_config_nvs.c +++ b/drivers/mtd/mtd_config_nvs.c @@ -57,6 +57,8 @@ #define NVS_CACHE_NO_ADDR 0xffffffff +#define NVS_HASH_INITIAL_VALUE 2166136261 + #if CONFIG_MTD_CONFIG_BUFFER_SIZE > 0 # define NVS_BUFFER_SIZE(fs) CONFIG_MTD_CONFIG_BUFFER_SIZE # define NVS_ATE(name, size) \ @@ -179,17 +181,17 @@ static void nvs_invalid_cache(struct nvs_fs *fs, uint32_t sector) #endif /* CONFIG_MTD_CONFIG_CACHE_SIZE */ /**************************************************************************** - * Name: nvs_fnv_hash + * Name: nvs_fnv_hash_part ****************************************************************************/ -static uint32_t nvs_fnv_hash(FAR const uint8_t *input, uint32_t len) +static uint32_t nvs_fnv_hash_part(FAR const void *input, uint32_t len, + uint32_t hval) { - uint32_t i = 0; - uint32_t hval = 2166136261; + FAR const uint8_t *key8 = (FAR const uint8_t *)input; /* FNV-1 hash each octet in the buffer */ - while (i++ < len) + while (len-- > 0) { /* Multiply by the 32 bit FNV magic prime mod 2^32 */ @@ -197,12 +199,30 @@ static uint32_t nvs_fnv_hash(FAR const uint8_t *input, uint32_t len) /* Xor the bottom with the current octet */ - hval ^= *input++; + hval ^= *key8++; } return hval; } +/**************************************************************************** + * Name: nvs_fnv_hash + ****************************************************************************/ + +static uint32_t nvs_fnv_hash(FAR const void *input, uint32_t len) +{ + return nvs_fnv_hash_part(input, len, NVS_HASH_INITIAL_VALUE); +} + +/**************************************************************************** + * Name: nvs_fnv_hash_id + ****************************************************************************/ + +static uint32_t nvs_fnv_hash_id(uint32_t hash) +{ + return hash % 0xfffffffd + 1; +} + /**************************************************************************** * Name: nvs_align_up ****************************************************************************/ @@ -602,6 +622,7 @@ static int nvs_flash_block_move(FAR struct nvs_fs *fs, uint32_t data_end = data_begin + entry->len; uint8_t buf[NVS_BUFFER_SIZE(fs)]; size_t buf_size = nvs_align_down(fs, sizeof(buf)); + uint32_t hash = NVS_HASH_INITIAL_VALUE; uint8_t data_crc8 = 0; int rc; @@ -614,8 +635,19 @@ static int nvs_flash_block_move(FAR struct nvs_fs *fs, return rc; } + if (addr < data_begin) + { + hash = nvs_fnv_hash_part(buf, MIN(bytes_to_copy, + data_begin - addr), hash); + } + if (addr + bytes_to_copy > data_begin) { + if (nvs_fnv_hash_id(hash) != entry->id) + { + return -EBADMSG; + } + uint32_t end_addr = MIN(data_end, addr + bytes_to_copy); uint32_t begin_addr = MAX(data_begin, addr); data_crc8 = crc8part(buf + (begin_addr - addr), @@ -1689,7 +1721,7 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, bool hit = true; int rc; - hash_id = nvs_fnv_hash(key, key_size) % 0xfffffffd + 1; + hash_id = nvs_fnv_hash_id(nvs_fnv_hash(key, key_size)); #if CONFIG_MTD_CONFIG_CACHE_SIZE > 0 wlk_addr = fs->cache[nvs_cache_index(hash_id)]; if (wlk_addr == NVS_CACHE_NO_ADDR) @@ -1856,7 +1888,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* Calc hash id of key. */ - hash_id = nvs_fnv_hash(key, key_size) % 0xfffffffd + 1; + hash_id = nvs_fnv_hash_id(nvs_fnv_hash(key, key_size)); /* Find latest entry with same id. */
