-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fs: nvs: Add recovery path for corrupted NVS #83128
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -781,10 +781,23 @@ static int nvs_startup(struct nvs_fs *fs) | |
} | ||
} | ||
} | ||
/* all sectors are closed, this is not a nvs fs */ | ||
/* all sectors are closed, this is not a nvs fs or irreparably corrupted */ | ||
if (closed_sectors == fs->sector_count) { | ||
#ifdef CONFIG_NVS_INIT_BAD_MEMORY_REGION | ||
LOG_WRN("All sectors closed, erasing all sectors..."); | ||
rc = flash_flatten(fs->flash_device, fs->offset, | ||
fs->sector_size * fs->sector_count); | ||
if (rc) { | ||
goto end; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please insert a space after this line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line was removed |
||
|
||
i = fs->sector_count; | ||
addr = ((fs->sector_count - 1) << ADDR_SECT_SHIFT) + | ||
(uint16_t)(fs->sector_size - ate_size); | ||
#else | ||
rc = -EDEADLK; | ||
goto end; | ||
#endif | ||
} | ||
|
||
if (i == fs->sector_count) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ CONFIG_FLASH_MAP=y | |
CONFIG_NVS=y | ||
CONFIG_LOG=y | ||
CONFIG_NVS_LOG_LEVEL_DBG=y | ||
CONFIG_NVS_INIT_BAD_MEMORY_REGION=y |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -959,3 +959,40 @@ ZTEST_F(nvs, test_nvs_cache_hash_quality) | |
|
||
#endif | ||
} | ||
|
||
/* | ||
* Test NVS bad region initialization recovery. | ||
*/ | ||
ZTEST_F(nvs, test_nvs_init_bad_memory_region) | ||
{ | ||
int err; | ||
uint32_t data; | ||
|
||
err = nvs_mount(&fixture->fs); | ||
zassert_true(err == 0, "nvs_mount call failure: %d", err); | ||
|
||
/* Write bad ATE to each sector */ | ||
for (uint16_t i = 0; i < TEST_SECTOR_COUNT; i++) { | ||
data = 0xdeadbeef; | ||
err = flash_write(fixture->fs.flash_device, | ||
fixture->fs.offset + (fixture->fs.sector_size * (i + 1)) - | ||
sizeof(struct nvs_ate), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NIT, I think this alignment might still be considered incorrect. |
||
&data, sizeof(data)); | ||
zassert_true(err == 0, "flash_write failed: %d", err); | ||
} | ||
|
||
/* Reinitialize the NVS. */ | ||
memset(&fixture->fs, 0, sizeof(fixture->fs)); | ||
(void)setup(); | ||
|
||
#ifdef CONFIG_NVS_INIT_BAD_MEMORY_REGION | ||
err = nvs_mount(&fixture->fs); | ||
zassert_true(err == 0, "nvs_mount call failure: %d", err); | ||
|
||
/* Ensure that the NVS is able to store new content. */ | ||
execute_long_pattern_write(TEST_DATA_ID, &fixture->fs); | ||
#else | ||
err = nvs_mount(&fixture->fs); | ||
zassert_true(err == -EDEADLK, "nvs_mount call ok, expect fail: %d", err); | ||
#endif | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming here is confusing. You are talking about region but in the description you are referring to "bad partition recovery"
AFAIK the term "Region" doesn't seem to be used anywhere in NVS.
NVS knows only about Sectors of data
Could be NVS_INIT_BAD_SECTORS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The terminology
region
was carefully chosen not to overlap with partition (as defined in dts), area (as used inflash_area_...
routines, there also are no bad sectors (which would be used by nand devices).@corymayer, please update the bool to "Non-volatile Storage bad region recovery".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Laczen So maybe it is better to use the terminology "memory region" instead of just "region"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Memory region" is also existing terminology.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"memory region" is used to describe a part of the memory. This is what this PR is about, right ? Am I missing something ? Or do you mean that the "memory region" terminology is reserved for other purposes in zephyr ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything is existing terminology, so context matters. If something does not exist in a given context than it can be used to describe some characteristic in that context. And NAND actually uses Bad Block Management, for example winbond devices, to manage sectors in pages, which is again vendor specific nomenclature, because sectors/pages/block naming varies between devices.
So, Region or Memory region, when defined within context of NVS as a specific offset/range tuple may be fine, as long as it's relation to sectors or partitions, as used by NVS, is clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"memory region" is used in dts for linker memory regions, in user mode for memory domains... It is in no way reserved exclusively for these purposes but might be confusing to use it here as some people associate memory with RAM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case I prefer "memory region" which covers (flash/ram/... regions) instead of just "region"
but that's not a blocker for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the name to "bad memory region" and added a unit test