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:
parent
b76edc1a1d
commit
54000fb886
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue