NVS: Changed all new to new (nothrow)

This commit is contained in:
Jakob Hasse 2020-03-04 15:26:34 +08:00
parent cc34d5a5b0
commit 58cf509495
9 changed files with 101 additions and 34 deletions

View File

@ -105,7 +105,10 @@ extern "C" esp_err_t nvs_flash_init_custom(const char *partName, uint32_t baseSe
nvs::Storage* new_storage = NULL; nvs::Storage* new_storage = NULL;
nvs::Storage* storage = lookup_storage_from_name(partName); nvs::Storage* storage = lookup_storage_from_name(partName);
if (storage == NULL) { if (storage == NULL) {
new_storage = new nvs::Storage((const char *)partName); new_storage = new (std::nothrow) nvs::Storage((const char *)partName);
if (!new_storage) return ESP_ERR_NO_MEM;
storage = new_storage; storage = new_storage;
} }
@ -127,6 +130,9 @@ extern "C" esp_err_t nvs_flash_secure_init_custom(const char *partName, uint32_t
if(cfg) { if(cfg) {
auto encrMgr = EncrMgr::getInstance(); auto encrMgr = EncrMgr::getInstance();
if (!encrMgr) return ESP_ERR_NO_MEM;
auto err = encrMgr->setSecurityContext(baseSector, sectorCount, cfg); auto err = encrMgr->setSecurityContext(baseSector, sectorCount, cfg);
if(err != ESP_OK) { if(err != ESP_OK) {
return err; return err;
@ -282,7 +288,10 @@ extern "C" esp_err_t nvs_open_from_partition(const char *part_name, const char*
return err; return err;
} }
HandleEntry *handle_entry = new HandleEntry(open_mode==NVS_READONLY, nsIndex, sHandle); HandleEntry *handle_entry = new (std::nothrow) HandleEntry(open_mode==NVS_READONLY, nsIndex, sHandle);
if (!handle_entry) return ESP_ERR_NO_MEM;
s_nvs_handles.push_back(handle_entry); s_nvs_handles.push_back(handle_entry);
*out_handle = handle_entry->mHandle; *out_handle = handle_entry->mHandle;

View File

@ -27,8 +27,10 @@ namespace nvs
{ {
if(!isActive) if(!isActive)
{ {
instance = new EncrMgr(); instance = new (std::nothrow) EncrMgr();
isActive = true; if (instance) {
isActive = true;
}
} }
return instance; return instance;
} }
@ -62,7 +64,9 @@ namespace nvs
uint8_t* eky = reinterpret_cast<uint8_t*>(cfg); uint8_t* eky = reinterpret_cast<uint8_t*>(cfg);
auto ctxt = new XtsCtxt(); auto ctxt = new (std::nothrow) XtsCtxt();
if (!ctxt) return ESP_ERR_NO_MEM;
ctxt->baseSector = baseSector; ctxt->baseSector = baseSector;
ctxt->sectorCount = sectorCount; ctxt->sectorCount = sectorCount;

View File

@ -20,7 +20,7 @@ namespace nvs
HashList::HashList() HashList::HashList()
{ {
} }
void HashList::clear() void HashList::clear()
{ {
for (auto it = mBlockList.begin(); it != mBlockList.end();) { for (auto it = mBlockList.begin(); it != mBlockList.end();) {
@ -30,7 +30,7 @@ void HashList::clear()
delete static_cast<HashListBlock*>(tmp); delete static_cast<HashListBlock*>(tmp);
} }
} }
HashList::~HashList() HashList::~HashList()
{ {
clear(); clear();
@ -42,7 +42,7 @@ HashList::HashListBlock::HashListBlock()
"cache block size calculation incorrect"); "cache block size calculation incorrect");
} }
void HashList::insert(const Item& item, size_t index) esp_err_t HashList::insert(const Item& item, size_t index)
{ {
const uint32_t hash_24 = item.calculateCrc32WithoutValue() & 0xffffff; const uint32_t hash_24 = item.calculateCrc32WithoutValue() & 0xffffff;
// add entry to the end of last block if possible // add entry to the end of last block if possible
@ -50,14 +50,19 @@ void HashList::insert(const Item& item, size_t index)
auto& block = mBlockList.back(); auto& block = mBlockList.back();
if (block.mCount < HashListBlock::ENTRY_COUNT) { if (block.mCount < HashListBlock::ENTRY_COUNT) {
block.mNodes[block.mCount++] = HashListNode(hash_24, index); block.mNodes[block.mCount++] = HashListNode(hash_24, index);
return; return ESP_OK;
} }
} }
// if the above failed, create a new block and add entry to it // if the above failed, create a new block and add entry to it
HashListBlock* newBlock = new HashListBlock; HashListBlock* newBlock = new (std::nothrow) HashListBlock;
if (!newBlock) return ESP_ERR_NO_MEM;
mBlockList.push_back(newBlock); mBlockList.push_back(newBlock);
newBlock->mNodes[0] = HashListNode(hash_24, index); newBlock->mNodes[0] = HashListNode(hash_24, index);
newBlock->mCount++; newBlock->mCount++;
return ESP_OK;
} }
void HashList::erase(size_t index, bool itemShouldExist) void HashList::erase(size_t index, bool itemShouldExist)

View File

@ -27,16 +27,16 @@ class HashList
public: public:
HashList(); HashList();
~HashList(); ~HashList();
void insert(const Item& item, size_t index); esp_err_t insert(const Item& item, size_t index);
void erase(const size_t index, bool itemShouldExist=true); void erase(const size_t index, bool itemShouldExist=true);
size_t find(size_t start, const Item& item); size_t find(size_t start, const Item& item);
void clear(); void clear();
private: private:
HashList(const HashList& other); HashList(const HashList& other);
const HashList& operator= (const HashList& rhs); const HashList& operator= (const HashList& rhs);
protected: protected:
struct HashListNode { struct HashListNode {

View File

@ -26,6 +26,9 @@ esp_err_t nvs_flash_write(size_t destAddr, const void *srcAddr, size_t size) {
if(EncrMgr::isEncrActive()) { if(EncrMgr::isEncrActive()) {
auto encrMgr = EncrMgr::getInstance(); auto encrMgr = EncrMgr::getInstance();
if (!encrMgr) return ESP_ERR_NO_MEM;
auto xtsCtxt = encrMgr->findXtsCtxtFromAddr(destAddr); auto xtsCtxt = encrMgr->findXtsCtxtFromAddr(destAddr);
if(xtsCtxt) { if(xtsCtxt) {
@ -44,7 +47,7 @@ esp_err_t nvs_flash_write(size_t destAddr, const void *srcAddr, size_t size) {
} }
esp_err_t nvs_flash_read(size_t srcAddr, void *destAddr, size_t size) { esp_err_t nvs_flash_read(size_t srcAddr, void *destAddr, size_t size) {
auto err = spi_flash_read(srcAddr, destAddr, size); auto err = spi_flash_read(srcAddr, destAddr, size);
if(err != ESP_OK) { if(err != ESP_OK) {
@ -53,6 +56,9 @@ esp_err_t nvs_flash_read(size_t srcAddr, void *destAddr, size_t size) {
if(EncrMgr::isEncrActive()) { if(EncrMgr::isEncrActive()) {
auto encrMgr = EncrMgr::getInstance(); auto encrMgr = EncrMgr::getInstance();
if (!encrMgr) return ESP_ERR_NO_MEM;
auto xtsCtxt = encrMgr->findXtsCtxtFromAddr(srcAddr); auto xtsCtxt = encrMgr->findXtsCtxtFromAddr(srcAddr);
if(xtsCtxt) { if(xtsCtxt) {
return encrMgr->decryptNvsData(static_cast<uint8_t*>(destAddr), return encrMgr->decryptNvsData(static_cast<uint8_t*>(destAddr),

View File

@ -49,7 +49,10 @@ esp_err_t Page::load(uint32_t sectorNumber)
// check if the whole page is really empty // check if the whole page is really empty
// reading the whole page takes ~40 times less than erasing it // reading the whole page takes ~40 times less than erasing it
const int BLOCK_SIZE = 128; const int BLOCK_SIZE = 128;
uint32_t* block = new uint32_t[BLOCK_SIZE]; uint32_t* block = new (std::nothrow) uint32_t[BLOCK_SIZE];
if (!block) return ESP_ERR_NO_MEM;
for (uint32_t i = 0; i < SPI_FLASH_SEC_SIZE; i += 4 * BLOCK_SIZE) { for (uint32_t i = 0; i < SPI_FLASH_SEC_SIZE; i += 4 * BLOCK_SIZE) {
rc = spi_flash_read(mBaseAddress + i, block, 4 * BLOCK_SIZE); rc = spi_flash_read(mBaseAddress + i, block, 4 * BLOCK_SIZE);
if (rc != ESP_OK) { if (rc != ESP_OK) {
@ -215,7 +218,11 @@ esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, c
// write first item // write first item
size_t span = (totalSize + ENTRY_SIZE - 1) / ENTRY_SIZE; size_t span = (totalSize + ENTRY_SIZE - 1) / ENTRY_SIZE;
item = Item(nsIndex, datatype, span, key, chunkIdx); item = Item(nsIndex, datatype, span, key, chunkIdx);
mHashList.insert(item, mNextFreeEntry); err = mHashList.insert(item, mNextFreeEntry);
if (err != ESP_OK) {
return err;
}
if (!isVariableLengthType(datatype)) { if (!isVariableLengthType(datatype)) {
memcpy(item.data, data, dataSize); memcpy(item.data, data, dataSize);
@ -426,7 +433,11 @@ esp_err_t Page::copyItems(Page& other)
return err; return err;
} }
other.mHashList.insert(entry, other.mNextFreeEntry); err = other.mHashList.insert(entry, other.mNextFreeEntry);
if (err != ESP_OK) {
return err;
}
err = other.writeEntry(entry); err = other.writeEntry(entry);
if (err != ESP_OK) { if (err != ESP_OK) {
return err; return err;
@ -549,7 +560,11 @@ esp_err_t Page::mLoadEntryTable()
continue; continue;
} }
mHashList.insert(item, i); err = mHashList.insert(item, i);
if (err != ESP_OK) {
mState = PageState::INVALID;
return err;
}
// search for potential duplicate item // search for potential duplicate item
size_t duplicateIndex = mHashList.find(0, item); size_t duplicateIndex = mHashList.find(0, item);
@ -619,7 +634,11 @@ esp_err_t Page::mLoadEntryTable()
assert(item.span > 0); assert(item.span > 0);
mHashList.insert(item, i); err = mHashList.insert(item, i);
if (err != ESP_OK) {
mState = PageState::INVALID;
return err;
}
size_t span = item.span; size_t span = item.span;

View File

@ -21,7 +21,9 @@ esp_err_t PageManager::load(uint32_t baseSector, uint32_t sectorCount)
mPageCount = sectorCount; mPageCount = sectorCount;
mPageList.clear(); mPageList.clear();
mFreePageList.clear(); mFreePageList.clear();
mPages.reset(new Page[sectorCount]); mPages.reset(new (std::nothrow) Page[sectorCount]);
if (!mPages) return ESP_ERR_NO_MEM;
for (uint32_t i = 0; i < sectorCount; ++i) { for (uint32_t i = 0; i < sectorCount; ++i) {
auto err = mPages[i].load(baseSector + i); auto err = mPages[i].load(baseSector + i);
@ -85,7 +87,7 @@ esp_err_t PageManager::load(uint32_t baseSector, uint32_t sectorCount)
break; break;
} }
} }
} }
} }
// check if power went out while page was being freed // check if power went out while page was being freed

View File

@ -31,7 +31,7 @@ void Storage::clearNamespaces()
mNamespaces.clearAndFreeNodes(); mNamespaces.clearAndFreeNodes();
} }
void Storage::populateBlobIndices(TBlobIndexList& blobIdxList) esp_err_t Storage::populateBlobIndices(TBlobIndexList& blobIdxList)
{ {
for (auto it = mPageManager.begin(); it != mPageManager.end(); ++it) { for (auto it = mPageManager.begin(); it != mPageManager.end(); ++it) {
Page& p = *it; Page& p = *it;
@ -43,7 +43,9 @@ void Storage::populateBlobIndices(TBlobIndexList& blobIdxList)
* duplicate index at this point */ * duplicate index at this point */
while (p.findItem(Page::NS_ANY, ItemType::BLOB_IDX, nullptr, itemIndex, item) == ESP_OK) { while (p.findItem(Page::NS_ANY, ItemType::BLOB_IDX, nullptr, itemIndex, item) == ESP_OK) {
BlobIndexNode* entry = new BlobIndexNode; BlobIndexNode* entry = new (std::nothrow) BlobIndexNode;
if (!entry) return ESP_ERR_NO_MEM;
item.getKey(entry->key, sizeof(entry->key) - 1); item.getKey(entry->key, sizeof(entry->key) - 1);
entry->nsIndex = item.nsIndex; entry->nsIndex = item.nsIndex;
@ -54,6 +56,8 @@ void Storage::populateBlobIndices(TBlobIndexList& blobIdxList)
itemIndex += item.span; itemIndex += item.span;
} }
} }
return ESP_OK;
} }
void Storage::eraseOrphanDataBlobs(TBlobIndexList& blobIdxList) void Storage::eraseOrphanDataBlobs(TBlobIndexList& blobIdxList)
@ -100,7 +104,13 @@ esp_err_t Storage::init(uint32_t baseSector, uint32_t sectorCount)
size_t itemIndex = 0; size_t itemIndex = 0;
Item item; Item item;
while (p.findItem(Page::NS_INDEX, ItemType::U8, nullptr, itemIndex, item) == ESP_OK) { while (p.findItem(Page::NS_INDEX, ItemType::U8, nullptr, itemIndex, item) == ESP_OK) {
NamespaceEntry* entry = new NamespaceEntry; NamespaceEntry* entry = new (std::nothrow) NamespaceEntry;
if (!entry) {
mState = StorageState::INVALID;
return ESP_ERR_NO_MEM;
}
item.getKey(entry->mName, sizeof(entry->mName) - 1); item.getKey(entry->mName, sizeof(entry->mName) - 1);
item.getValue(entry->mIndex); item.getValue(entry->mIndex);
mNamespaces.push_back(entry); mNamespaces.push_back(entry);
@ -114,7 +124,11 @@ esp_err_t Storage::init(uint32_t baseSector, uint32_t sectorCount)
// Populate list of multi-page index entries. // Populate list of multi-page index entries.
TBlobIndexList blobIdxList; TBlobIndexList blobIdxList;
populateBlobIndices(blobIdxList); err = populateBlobIndices(blobIdxList);
if (err != ESP_OK) {
mState = StorageState::INVALID;
return ESP_ERR_NO_MEM;
}
// Remove the entries for which there is no parent multi-page index. // Remove the entries for which there is no parent multi-page index.
eraseOrphanDataBlobs(blobIdxList); eraseOrphanDataBlobs(blobIdxList);
@ -182,7 +196,7 @@ esp_err_t Storage::writeMultiPageBlob(uint8_t nsIndex, const char* key, const vo
return err; return err;
} else if(getCurrentPage().getVarDataTailroom() == tailroom) { } else if(getCurrentPage().getVarDataTailroom() == tailroom) {
/* We got the same page or we are not improving.*/ /* We got the same page or we are not improving.*/
return ESP_ERR_NVS_NOT_ENOUGH_SPACE; return ESP_ERR_NVS_NOT_ENOUGH_SPACE;
} else { } else {
continue; continue;
} }
@ -203,7 +217,11 @@ esp_err_t Storage::writeMultiPageBlob(uint8_t nsIndex, const char* key, const vo
if (err != ESP_OK) { if (err != ESP_OK) {
break; break;
} else { } else {
UsedPageNode* node = new UsedPageNode(); UsedPageNode* node = new (std::nothrow) UsedPageNode();
if (!node) {
err = ESP_ERR_NO_MEM;
break;
}
node->mPage = &page; node->mPage = &page;
usedPages.push_back(node); usedPages.push_back(node);
if (remainingSize || (tailroom - chunkSize) < Page::ENTRY_SIZE) { if (remainingSize || (tailroom - chunkSize) < Page::ENTRY_SIZE) {
@ -301,9 +319,9 @@ esp_err_t Storage::writeItem(uint8_t nsIndex, ItemType datatype, const char* key
if (err != ESP_OK) { if (err != ESP_OK) {
return err; return err;
} }
findPage = nullptr; findPage = nullptr;
} else { } else {
/* Support for earlier versions where BLOBS were stored without index */ /* Support for earlier versions where BLOBS were stored without index */
err = findItem(nsIndex, datatype, key, findPage, item); err = findItem(nsIndex, datatype, key, findPage, item);
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) { if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) {
@ -381,6 +399,11 @@ esp_err_t Storage::createOrOpenNamespace(const char* nsName, bool canCreate, uin
return ESP_ERR_NVS_NOT_ENOUGH_SPACE; return ESP_ERR_NVS_NOT_ENOUGH_SPACE;
} }
NamespaceEntry* entry = new (std::nothrow) NamespaceEntry;
if (!entry) {
return ESP_ERR_NO_MEM;
}
auto err = writeItem(Page::NS_INDEX, ItemType::U8, nsName, &ns, sizeof(ns)); auto err = writeItem(Page::NS_INDEX, ItemType::U8, nsName, &ns, sizeof(ns));
if (err != ESP_OK) { if (err != ESP_OK) {
return err; return err;
@ -388,7 +411,6 @@ esp_err_t Storage::createOrOpenNamespace(const char* nsName, bool canCreate, uin
mNamespaceUsage.set(ns, true); mNamespaceUsage.set(ns, true);
nsIndex = ns; nsIndex = ns;
NamespaceEntry* entry = new NamespaceEntry;
entry->mIndex = ns; entry->mIndex = ns;
strncpy(entry->mName, nsName, sizeof(entry->mName) - 1); strncpy(entry->mName, nsName, sizeof(entry->mName) - 1);
entry->mName[sizeof(entry->mName) - 1] = 0; entry->mName[sizeof(entry->mName) - 1] = 0;
@ -456,14 +478,14 @@ esp_err_t Storage::readItem(uint8_t nsIndex, ItemType datatype, const char* key,
if (err != ESP_ERR_NVS_NOT_FOUND) { if (err != ESP_ERR_NVS_NOT_FOUND) {
return err; return err;
} // else check if the blob is stored with earlier version format without index } // else check if the blob is stored with earlier version format without index
} }
auto err = findItem(nsIndex, datatype, key, findPage, item); auto err = findItem(nsIndex, datatype, key, findPage, item);
if (err != ESP_OK) { if (err != ESP_OK) {
return err; return err;
} }
return findPage->readItem(nsIndex, datatype, key, data, dataSize); return findPage->readItem(nsIndex, datatype, key, data, dataSize);
} }
esp_err_t Storage::eraseMultiPageBlob(uint8_t nsIndex, const char* key, VerOffset chunkStart) esp_err_t Storage::eraseMultiPageBlob(uint8_t nsIndex, const char* key, VerOffset chunkStart)

View File

@ -128,7 +128,7 @@ protected:
void clearNamespaces(); void clearNamespaces();
void populateBlobIndices(TBlobIndexList&); esp_err_t populateBlobIndices(TBlobIndexList&);
void eraseOrphanDataBlobs(TBlobIndexList&); void eraseOrphanDataBlobs(TBlobIndexList&);