mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fix(nvs): eraseMultiPageBlob to robustly delete all related BLOB_DATA records and respect VER_ANY
This commit is contained in:
parent
6cd48e0e91
commit
12d8abde53
@ -98,6 +98,8 @@ public:
|
||||
|
||||
esp_err_t findItem(uint8_t nsIndex, ItemType datatype, const char* key, size_t &itemIndex, Item& item, uint8_t chunkIdx = CHUNK_ANY, VerOffset chunkStart = VerOffset::VER_ANY);
|
||||
|
||||
esp_err_t eraseEntryAndSpan(size_t index);
|
||||
|
||||
template<typename T>
|
||||
esp_err_t writeItem(uint8_t nsIndex, const char* key, const T& value)
|
||||
{
|
||||
@ -188,8 +190,6 @@ protected:
|
||||
|
||||
esp_err_t writeEntryData(const uint8_t* data, size_t size);
|
||||
|
||||
esp_err_t eraseEntryAndSpan(size_t index);
|
||||
|
||||
esp_err_t updateFirstUsedEntry(size_t index, size_t span);
|
||||
|
||||
static constexpr size_t getAlignmentForType(ItemType type)
|
||||
|
@ -661,34 +661,57 @@ esp_err_t Storage::eraseMultiPageBlob(uint8_t nsIndex, const char* key, VerOffse
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
/* Erase the index first and make children blobs orphan*/
|
||||
// Erase the index first and make children blobs orphan
|
||||
err = findPage->eraseItem(nsIndex, ItemType::BLOB_IDX, key, Page::CHUNK_ANY, chunkStart);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
uint8_t chunkCount = item.blobIndex.chunkCount;
|
||||
|
||||
if (chunkStart == VerOffset::VER_ANY) {
|
||||
chunkStart = item.blobIndex.chunkStart;
|
||||
} else {
|
||||
NVS_ASSERT_OR_RETURN(chunkStart == item.blobIndex.chunkStart, ESP_FAIL);
|
||||
// If caller requires delete of VER_ANY
|
||||
// We may face dirty NVS partition and version duplicates can be there
|
||||
// Make second attempt to delete index and ignore eventual not found
|
||||
if(chunkStart == VerOffset::VER_ANY)
|
||||
{
|
||||
err = findItem(nsIndex, ItemType::BLOB_IDX, key, findPage, item, Page::CHUNK_ANY, chunkStart);
|
||||
if (err == ESP_OK) {
|
||||
err = findPage->eraseItem(nsIndex, ItemType::BLOB_IDX, key, Page::CHUNK_ANY, chunkStart);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
} else if (err != ESP_ERR_NVS_NOT_FOUND) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now erase corresponding chunks*/
|
||||
for (uint8_t chunkNum = 0; chunkNum < chunkCount; chunkNum++) {
|
||||
err = findItem(nsIndex, ItemType::BLOB_DATA, key, findPage, item, static_cast<uint8_t> (chunkStart) + chunkNum);
|
||||
// setup limits for chunkIndex-es to be deleted
|
||||
uint8_t minChunkIndex = (uint8_t) VerOffset::VER_0_OFFSET;
|
||||
uint8_t maxChunkIndex = (uint8_t) VerOffset::VER_ANY;
|
||||
|
||||
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) {
|
||||
return err;
|
||||
} else if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
continue; // Keep erasing other chunks
|
||||
}
|
||||
err = findPage->eraseItem(nsIndex, ItemType::BLOB_DATA, key, static_cast<uint8_t> (chunkStart) + chunkNum);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
if(chunkStart == VerOffset::VER_0_OFFSET) {
|
||||
maxChunkIndex = (uint8_t) VerOffset::VER_1_OFFSET;
|
||||
} else if (chunkStart == VerOffset::VER_1_OFFSET) {
|
||||
minChunkIndex = (uint8_t) VerOffset::VER_1_OFFSET;
|
||||
}
|
||||
|
||||
for (auto it = std::begin(mPageManager); it != std::end(mPageManager); ++it) {
|
||||
size_t itemIndex = 0;
|
||||
do {
|
||||
err = it->findItem(nsIndex, ItemType::BLOB_DATA, key, itemIndex, item);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
break;
|
||||
} else if (err == ESP_OK) {
|
||||
// check if item.chunkIndex is within the version range indicated by chunkStart, if so, delete it
|
||||
if((item.chunkIndex >= minChunkIndex) && (item.chunkIndex < maxChunkIndex)) {
|
||||
err = it->eraseEntryAndSpan(itemIndex);
|
||||
}
|
||||
|
||||
// continue findItem until end of page
|
||||
itemIndex += item.span;
|
||||
}
|
||||
if(err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
} while (err == ESP_OK && itemIndex < Page::ENTRY_COUNT);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
|
Loading…
x
Reference in New Issue
Block a user