NVS Flash: prevent erasing initialized partition
Closes https://github.com/espressif/esp-idf/issues/4755 Closes https://github.com/espressif/esp-idf/issues/2777 * nvs_flash_erase_partition() checks whether the parition in question is initialized already and will return an error if so * reflect changes in the documentation
This commit is contained in:
@@ -137,6 +137,40 @@ extern "C" esp_err_t nvs_flash_secure_init_custom(const char *partName, uint32_t
|
||||
}
|
||||
#endif
|
||||
|
||||
static esp_err_t close_handles_and_deinit(const char* part_name)
|
||||
{
|
||||
nvs::Storage* storage = lookup_storage_from_name(part_name);
|
||||
if (!storage) {
|
||||
return ESP_ERR_NVS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NVS_ENCRYPTION
|
||||
if(EncrMgr::isEncrActive()) {
|
||||
auto encrMgr = EncrMgr::getInstance();
|
||||
encrMgr->removeSecurityContext(storage->getBaseSector());
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clean up handles related to the storage being deinitialized */
|
||||
auto it = s_nvs_handles.begin();
|
||||
auto next = it;
|
||||
while(it != s_nvs_handles.end()) {
|
||||
next++;
|
||||
if (it->mStoragePtr == storage) {
|
||||
ESP_LOGD(TAG, "Deleting handle %d (ns=%d) related to partition \"%s\" (missing call to nvs_close?)",
|
||||
it->mHandle, it->mNsIndex, part_name);
|
||||
s_nvs_handles.erase(it);
|
||||
delete static_cast<HandleEntry*>(it);
|
||||
}
|
||||
it = next;
|
||||
}
|
||||
|
||||
/* Finally delete the storage itself */
|
||||
s_nvs_storage_list.erase(storage);
|
||||
delete storage;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
extern "C" esp_err_t nvs_flash_init_partition(const char *part_name)
|
||||
@@ -195,6 +229,19 @@ extern "C" esp_err_t nvs_flash_secure_init(nvs_sec_cfg_t* cfg)
|
||||
|
||||
extern "C" esp_err_t nvs_flash_erase_partition(const char *part_name)
|
||||
{
|
||||
Lock::init();
|
||||
Lock lock;
|
||||
|
||||
// if the partition is initialized, uninitialize it first
|
||||
if (lookup_storage_from_name(part_name)) {
|
||||
esp_err_t err = close_handles_and_deinit(part_name);
|
||||
|
||||
// only hypothetical/future case, deinit_partition() only fails if partition is uninitialized
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
const esp_partition_t* partition = esp_partition_find_first(
|
||||
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, part_name);
|
||||
if (partition == NULL) {
|
||||
@@ -215,37 +262,7 @@ extern "C" esp_err_t nvs_flash_deinit_partition(const char* partition_name)
|
||||
Lock::init();
|
||||
Lock lock;
|
||||
|
||||
nvs::Storage* storage = lookup_storage_from_name(partition_name);
|
||||
if (!storage) {
|
||||
return ESP_ERR_NVS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NVS_ENCRYPTION
|
||||
if(EncrMgr::isEncrActive()) {
|
||||
auto encrMgr = EncrMgr::getInstance();
|
||||
encrMgr->removeSecurityContext(storage->getBaseSector());
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clean up handles related to the storage being deinitialized */
|
||||
auto it = s_nvs_handles.begin();
|
||||
auto next = it;
|
||||
while(it != s_nvs_handles.end()) {
|
||||
next++;
|
||||
if (it->mStoragePtr == storage) {
|
||||
ESP_LOGD(TAG, "Deleting handle %d (ns=%d) related to partition \"%s\" (missing call to nvs_close?)",
|
||||
it->mHandle, it->mNsIndex, partition_name);
|
||||
s_nvs_handles.erase(it);
|
||||
delete static_cast<HandleEntry*>(it);
|
||||
}
|
||||
it = next;
|
||||
}
|
||||
|
||||
/* Finally delete the storage itself */
|
||||
s_nvs_storage_list.erase(storage);
|
||||
delete storage;
|
||||
|
||||
return ESP_OK;
|
||||
return close_handles_and_deinit(partition_name);
|
||||
}
|
||||
|
||||
extern "C" esp_err_t nvs_flash_deinit(void)
|
||||
|
||||
Reference in New Issue
Block a user