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