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>
This commit is contained in:
Andrzej Puzdrowski 2019-05-21 13:27:26 +02:00 committed by Carles Cufí
parent b76edc1a1d
commit 54000fb886

View file

@ -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
*/
nvs_sector_advance(fs, &addr);
}
/* search for the first ate containing all 0xff) */
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
*/
rc = nvs_flash_cmp_const(fs, addr - ate_size, 0xff,
sizeof(struct nvs_ate));
if (!rc) {
/* empty ate */
nvs_sector_advance(fs, &addr);
}
}
/* 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,