Skip to content
Permalink
Browse files

fs/nvs: fix startup for 2-sectors configuration

This patch fixes following bug:

After first GC operation the 1st sector had become scratch
and the 2nd sector had became write sector. After that NVS
was initialize (via reboot) again - it recognized the 1st
sector as write sector and 2nd as undone GC destination sector,
therefore it cleared 2nd sector and  re-run GC, which implied data loss.

Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
  • Loading branch information...
nvlsianpu authored and carlescufi committed May 21, 2019
1 parent b76edc1 commit 54000fb886ea5ab21404f927666d60a9a0a238b4
Showing with 22 additions and 7 deletions.
  1. +22 −7 subsys/fs/nvs/nvs.c
@@ -536,13 +536,15 @@ static int nvs_startup(struct nvs_fs *fs)
* Coverity and GCC believe the contrary.
*/
u32_t addr = 0U;

u16_t i;

k_mutex_lock(&fs->nvs_lock, K_FOREVER);

ate_size = nvs_al_size(fs, sizeof(struct nvs_ate));
/* step through the sectors to find the last sector */
for (u16_t i = 0; i < fs->sector_count; i++) {
/* step through the sectors to find a open sector following
* a closed sector, this is where NVS can to write.
*/
for (i = 0; i < fs->sector_count; i++) {
addr = (i << ADDR_SECT_SHIFT) + fs->sector_size - ate_size;
rc = nvs_flash_cmp_const(fs, addr, 0xff,
sizeof(struct nvs_ate));
@@ -556,12 +558,25 @@ static int nvs_startup(struct nvs_fs *fs)
break;
}
}
/* none of the sectors where closed, set the address to
* the first sector
}

if (i == fs->sector_count) {
/* none of the sectors where closed, in most cases we can set
* the address to the first sector, except when there are only
* two sectors. Then we can only set it to the first sector if
* the last sector contains no ate's. So we check this first
*/
nvs_sector_advance(fs, &addr);
rc = nvs_flash_cmp_const(fs, addr - ate_size, 0xff,
sizeof(struct nvs_ate));
if (!rc) {
/* empty ate */
nvs_sector_advance(fs, &addr);
}
}
/* search for the first ate containing all 0xff) */

/* addr contains address of the last ate in the most recent sector
* search for the first ate containing all 0xff
*/
while (1) {
addr -= ate_size;
rc = nvs_flash_cmp_const(fs, addr, 0xff,

0 comments on commit 54000fb

Please sign in to comment.
You can’t perform that action at this time.