diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 20b261a5b..a20259c81 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -17,7 +17,7 @@ struct __attribute__((packed)) FileStoreHeader { public: typedef InodeId InodeId_t; typedef FsT FsSize_t; - const static auto VERSION = 5; + const static auto VERSION = 6; private: uint16_t m_version; @@ -116,6 +116,7 @@ class FileStore { typename Header::FsSize_t m_dataLen; InodeId_t m_id; + InodeId_t m_links; uint8_t m_fileType; typename Header::FsSize_t m_left; typename Header::FsSize_t m_right; @@ -135,6 +136,9 @@ class FileStore { void setId(InodeId_t); InodeId_t getId(); + void setLinks(InodeId_t); + InodeId_t getLinks(); + void setFileType(uint8_t); uint8_t getFileType(); @@ -178,6 +182,18 @@ class FileStore { */ int remove(InodeId_t id); + /** + * Increments the links of the inode of the given ID. + * @param id the id of the inode + */ + int incLinks(InodeId_t id); + + /** + * Decrements the links of the inode of the given ID. + * @param id the id of the inode + */ + int decLinks(InodeId_t id); + /** * Removes all inodes of the type. * @param fileType the type of file to remove @@ -268,7 +284,7 @@ class FileStore { Inode *getInode(Inode *root, InodeId_t id); /** - * Gets the inode at the given id. + * Gets the parent inode at the given id. * @param root the root node to start comparing on * @param id id of the "file" * @param pathLen number of characters in pathLen @@ -405,6 +421,16 @@ typename Header::InodeId_t FileStore
::Inode::getId() { return bigEndianAdapt(m_id); } +template +void FileStore
::Inode::setLinks(InodeId_t links) { + this->m_links = bigEndianAdapt(links); +} + +template +typename Header::InodeId_t FileStore
::Inode::getLinks() { + return bigEndianAdapt(m_links); +} + template void FileStore
::Inode::setFileType(uint8_t fileType) { this->m_fileType = bigEndianAdapt(fileType); @@ -441,7 +467,6 @@ void FileStore
::Inode::setData(void *data, typename Header::FsSize_t siz setDataLen(size); } - template uint8_t *FileStore
::Inode::getData() { return (uint8_t*) (this + 1); @@ -511,6 +536,36 @@ int FileStore
::remove(InodeId_t id) { return remove(ptr(m_header.getRootInode()), id); } +/** + * Increments the links of the inode of the given ID. + * @param id the id of the inode + */ +template +int FileStore
::incLinks(InodeId_t id) { + auto inode = getInode(ptr(m_header.getRootInode()), id); + if (inode) { + inode->setLinks(inode->getLinks() + 1); + return 0; + } else { + return 1; + } +} + +/** + * Decrements the links of the inode of the given ID. + * @param id the id of the inode + */ +template +int FileStore
::decLinks(InodeId_t id) { + auto inode = getInode(ptr(m_header.getRootInode()), id); + if (inode) { + inode->setLinks(inode->getLinks() - 1); + return 0; + } else { + return 1; + } +} + template int FileStore
::remove(Inode *root, InodeId_t id) { auto err = 1; diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index ceeaa5fb7..b6f9b94ff 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -16,7 +16,7 @@ FileSystem *createFileSystem(uint8_t *buff, size_t buffSize, bool ownsBuff) { FileSystem *fs = nullptr; switch (version) { - case 5: + case 6: switch (type) { case ox::OxFS_16: fs = new FileSystem16(buff, ownsBuff); diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index 2d5bb81ef..eadfe168c 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -81,7 +81,7 @@ struct __attribute__((packed)) Directory { return size ? (DirectoryEntry*) (this + 1) : nullptr; } - uint64_t getFileInode(const char *name, uint64_t buffSize); + uint64_t getFileInode(const char *name); int getChildrenInodes(InodeId_t *inodes, size_t inodesLen); @@ -94,7 +94,7 @@ struct __attribute__((packed)) Directory { }; template -uint64_t Directory::getFileInode(const char *name, uint64_t buffSize) { +uint64_t Directory::getFileInode(const char *name) { uint64_t inode = 0; auto current = files(); if (current) { @@ -506,7 +506,7 @@ template int FileSystemTemplate::remove(const char *path, bool recursive) { auto inode = findInodeOf(path); if (inode) { - return remove(inode, recursive) | rmDirectoryEntry(path); + return rmDirectoryEntry(path) | remove(inode, recursive); } else { return 1; } @@ -575,7 +575,8 @@ int FileSystemTemplate::write(const char *path, void *buffer // find an inode value for the given path if (!inode) { inode = generateInodeId(); - err = insertDirectoryEntry(dirPath, fileName, inode); + err |= write(inode, buffer, 0, fileType); // ensure file exists before indexing it + err |= insertDirectoryEntry(dirPath, fileName, inode); } if (!err) { @@ -620,7 +621,7 @@ uint64_t FileSystemTemplate::findInodeOf(const char *path) { auto dir = (Directory*) dirBuffer; if (read(inode, dirBuffer, dirStat.size) == 0) { if (dirStat.fileType == FileType::FileType_Directory && it.next(fileName, pathLen) == 0) { - inode = dir->getFileInode(fileName, dirStat.size); + inode = dir->getFileInode(fileName); } else { inode = 0; // null out inode and break break; @@ -726,7 +727,9 @@ int FileSystemTemplate::insertDirectoryEntry(const char *dir auto entry = (DirectoryEntry*) &dirBuff[s.size]; entry->inode = inode; entry->setName(fileName); - return write(s.inode, dirBuff, dirBuffSize, FileType_Directory); + err = write(s.inode, dirBuff, dirBuffSize, FileType_Directory); + err |= m_store->incLinks(inode); + return err; } else { return 1; } @@ -803,7 +806,9 @@ int FileSystemTemplate::rmDirectoryEntry(const char *path) { } auto dir = (Directory*) dirBuff; - err = dir->rmFile(fileName); + auto inode = dir->getFileInode(fileName); + err |= dir->rmFile(fileName); + err |= m_store->decLinks(inode); if (err) { return err;