diff --git a/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp b/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp index 863ff316..671ed25e 100644 --- a/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp +++ b/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp @@ -16,7 +16,7 @@ namespace ox::fs { template struct __attribute__((packed)) FileStoreItem: public Item { ox::LittleEndian id = 0; - ox::LittleEndian fileType = 0; + ox::LittleEndian fileType = 0; ox::LittleEndian links = 0; ox::LittleEndian left = 0; ox::LittleEndian right = 0; @@ -68,7 +68,7 @@ class FileStoreTemplate: public FileStore { InodeId_t available(); private: - FileStoreData &fileStoreData(); + FileStoreData *fileStoreData(); /** * Places the given Item at the given ID. If it already exists, the @@ -96,7 +96,7 @@ class FileStoreTemplate: public FileStore { */ ItemPtr rootInode(); - bool canWrite(InodeId_t id, size_t size); + bool canWrite(ItemPtr existing, size_t size); }; @@ -151,8 +151,15 @@ Error FileStoreTemplate::decLinks(InodeId_t id) { template Error FileStoreTemplate::write(InodeId_t id, void *data, InodeId_t dataSize, uint8_t fileType) { - // TODO: delete the old node if it exists - if (canWrite(id, dataSize)) { + auto existing = find(id); + if (canWrite(existing, dataSize)) { + // delete the old node if it exists + if (existing.valid()) { + m_buffer->free(existing); + existing = nullptr; + } + + // write the given data auto dest = m_buffer->malloc(dataSize); // if first malloc failed, compact and try again dest = m_buffer->malloc(dataSize); @@ -165,7 +172,13 @@ Error FileStoreTemplate::write(InodeId_t id, void *data, InodeId_t dataS if (root.valid()) { placeItem(root, dest); } else { - fileStoreData().rootNode = root; + auto fsData = fileStoreData(); + if (fsData) { + fsData->rootNode = dest; + } else { + m_buffer->free(dest); + return 1; + } } return 0; } @@ -185,12 +198,21 @@ Error FileStoreTemplate::read(InodeId_t id, InodeId_t readStart, InodeId template typename FileStoreTemplate::StatInfo FileStoreTemplate::stat(InodeId_t id) { + auto inode = find(id); + if (inode.valid()) { + return { + .inodeId = id, + .links = inode->links, + .size = inode->size(), + .fileType = inode->fileType, + }; + } return {}; } template InodeId_t FileStoreTemplate::spaceNeeded(InodeId_t size) { - return 1; + return m_buffer->spaceNeeded(size); } template @@ -204,8 +226,15 @@ InodeId_t FileStoreTemplate::available() { } template -typename FileStoreTemplate::FileStoreData &FileStoreTemplate::fileStoreData() { - return *reinterpret_cast(m_buffer->firstItem()->data().get()); +typename FileStoreTemplate::FileStoreData *FileStoreTemplate::fileStoreData() { + auto first = m_buffer->firstItem(); + if (first.valid()) { + auto data = first->data(); + if (data.valid()) { + return reinterpret_cast(data.get()); + } + } + return nullptr; } template @@ -267,7 +296,7 @@ typename FileStoreTemplate::ItemPtr FileStoreTemplate::find(Item template typename FileStoreTemplate::ItemPtr FileStoreTemplate::find(size_t id) { - auto root = m_buffer->ptr(fileStoreData().rootNode); + auto root = m_buffer->ptr(fileStoreData()->rootNode); if (root.valid()) { auto item = find(root, id); return item; @@ -280,22 +309,12 @@ typename FileStoreTemplate::ItemPtr FileStoreTemplate::find(size */ template typename FileStoreTemplate::ItemPtr FileStoreTemplate::rootInode() { - return m_buffer->ptr(fileStoreData().rootNode); + return m_buffer->ptr(fileStoreData()->rootNode); } template -bool FileStoreTemplate::canWrite(InodeId_t id, size_t size) { - if (m_buffer->spaceNeeded(size) >= m_buffer->available()) { - return true; - } else { - auto existing = find(id); - if (existing.valid()) { - if (m_buffer->spaceNeeded(size) >= existing.size()) { - return true; - } - } - } - return false; +bool FileStoreTemplate::canWrite(ItemPtr existing, size_t size) { + return existing.size() >= size || m_buffer->spaceNeeded(size) >= m_buffer->available(); } using FileStore16 = FileStoreTemplate;