Merge branch 'master' of github.com:wombatant/ox into ox_master
This commit is contained in:
+60
-3
@@ -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;
|
||||
@@ -103,6 +103,7 @@ class FileStore {
|
||||
|
||||
struct StatInfo {
|
||||
InodeId_t inodeId;
|
||||
InodeId_t links;
|
||||
typename Header::FsSize_t size;
|
||||
uint8_t fileType;
|
||||
};
|
||||
@@ -116,6 +117,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 +137,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 +183,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 +285,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 +422,16 @@ typename Header::InodeId_t FileStore<Header>::Inode::getId() {
|
||||
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>
|
||||
void FileStore<Header>::Inode::setFileType(uint8_t fileType) {
|
||||
this->m_fileType = bigEndianAdapt(fileType);
|
||||
@@ -441,7 +468,6 @@ void FileStore<Header>::Inode::setData(void *data, typename Header::FsSize_t siz
|
||||
setDataLen(size);
|
||||
}
|
||||
|
||||
|
||||
template<typename Header>
|
||||
uint8_t *FileStore<Header>::Inode::getData() {
|
||||
return (uint8_t*) (this + 1);
|
||||
@@ -511,6 +537,36 @@ int FileStore<Header>::remove(InodeId_t 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>
|
||||
int FileStore<Header>::remove(Inode *root, InodeId_t id) {
|
||||
auto err = 1;
|
||||
@@ -664,6 +720,7 @@ typename FileStore<Header>::StatInfo FileStore<Header>::stat(InodeId_t id) {
|
||||
if (inode) {
|
||||
stat.size = inode->getDataLen();
|
||||
stat.fileType = inode->getFileType();
|
||||
stat.links = inode->getLinks();
|
||||
stat.inodeId = id;
|
||||
} else {
|
||||
stat.inodeId = 0;
|
||||
|
||||
@@ -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);
|
||||
|
||||
+61
-21
@@ -26,6 +26,7 @@ enum FileType {
|
||||
|
||||
struct FileStat {
|
||||
uint64_t inode;
|
||||
uint64_t links;
|
||||
uint64_t size;
|
||||
uint8_t fileType;
|
||||
};
|
||||
@@ -86,7 +87,7 @@ struct __attribute__((packed)) Directory {
|
||||
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);
|
||||
|
||||
@@ -99,7 +100,7 @@ struct __attribute__((packed)) Directory {
|
||||
};
|
||||
|
||||
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;
|
||||
auto current = files();
|
||||
if (current) {
|
||||
@@ -125,7 +126,9 @@ int Directory<InodeId_t, FsSize_t>::getChildrenInodes(InodeId_t *inodes, size_t
|
||||
auto current = files();
|
||||
if (current) {
|
||||
for (uint64_t i = 0; i < this->children; i++) {
|
||||
inodes[i] = current->inode;
|
||||
if (ox_strcmp(current->getName(), ".") and ox_strcmp(current->getName(), "..")) {
|
||||
inodes[i] = current->inode;
|
||||
}
|
||||
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
|
||||
}
|
||||
return 0;
|
||||
@@ -206,6 +209,13 @@ class FileSystem {
|
||||
|
||||
virtual int mkdir(const char *path) = 0;
|
||||
|
||||
/**
|
||||
* Moves an entry from one directory to another.
|
||||
* @param src the path to the file
|
||||
* @param dest the path of the destination directory
|
||||
*/
|
||||
virtual int move(const char *src, const char *dest) = 0;
|
||||
|
||||
template<typename List>
|
||||
int ls(const char *path, List *list);
|
||||
|
||||
@@ -245,11 +255,14 @@ class FileSystem {
|
||||
|
||||
template<typename List>
|
||||
int FileSystem::ls(const char *path, List *list) {
|
||||
int err = 0;
|
||||
auto s = stat(path);
|
||||
uint8_t dirBuff[s.size * 4];
|
||||
auto dir = (Directory<uint64_t, uint64_t>*) dirBuff;
|
||||
auto err = readDirectory(path, dir);
|
||||
err |= dir->ls(list);
|
||||
if (s.fileType == FileType_Directory) {
|
||||
uint8_t dirBuff[s.size * 4];
|
||||
auto dir = (Directory<uint64_t, uint64_t>*) dirBuff;
|
||||
err = readDirectory(path, dir);
|
||||
err |= dir->ls(list);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -318,13 +331,7 @@ class FileSystemTemplate: public FileSystem {
|
||||
uint64_t size() override;
|
||||
|
||||
uint8_t *buff() override;
|
||||
|
||||
/**
|
||||
* Moves an entry from one directory to another.
|
||||
* @param src the path to the file
|
||||
* @param dest the path of the destination directory
|
||||
*/
|
||||
int move(const char *src, const char *dest);
|
||||
int move(const char *src, const char *dest) override;
|
||||
|
||||
/**
|
||||
* Removes an entry from a directory. This does not delete the referred to file.
|
||||
@@ -375,7 +382,31 @@ template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::mkdir(const char *path) {
|
||||
if (!stat(path).inode) {
|
||||
Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t> dir;
|
||||
return write(path, &dir, sizeof(dir), FileType::FileType_Directory);
|
||||
auto err = write(path, &dir, sizeof(dir), FileType::FileType_Directory);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// add . entry for self
|
||||
auto inode = findInodeOf(path);
|
||||
err = insertDirectoryEntry(path, ".", inode);
|
||||
if (err) {
|
||||
remove(inode);
|
||||
return err;
|
||||
}
|
||||
|
||||
// add .. entry for parent
|
||||
size_t pathLen = ox_strlen(path);
|
||||
char dirPath[pathLen];
|
||||
PathIterator pathReader(path, pathLen);
|
||||
err |= pathReader.dirPath(dirPath, pathLen);
|
||||
err = insertDirectoryEntry(path, "..", findInodeOf(dirPath));
|
||||
if (err) {
|
||||
remove(inode);
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
@@ -401,6 +432,7 @@ FileStat FileSystemTemplate<FileStore, FS_TYPE>::stat(uint64_t inode) {
|
||||
auto s = m_store->stat(inode);
|
||||
stat.size = s.size;
|
||||
stat.inode = s.inodeId;
|
||||
stat.links = s.links;
|
||||
stat.fileType = s.fileType;
|
||||
return stat;
|
||||
}
|
||||
@@ -485,7 +517,7 @@ template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::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;
|
||||
}
|
||||
@@ -512,10 +544,13 @@ int FileSystemTemplate<FileStore, FS_TYPE>::remove(uint64_t inode, bool recursiv
|
||||
}
|
||||
|
||||
typename FileStore::InodeId_t inodes[dir->children];
|
||||
ox_memset(inodes, 0, sizeof(typename FileStore::InodeId_t) * dir->children);
|
||||
dir->getChildrenInodes(inodes, dir->children);
|
||||
|
||||
for (auto i : inodes) {
|
||||
err |= remove(i, true);
|
||||
if (i) {
|
||||
err |= remove(i, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
@@ -551,7 +586,8 @@ int FileSystemTemplate<FileStore, FS_TYPE>::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) {
|
||||
@@ -596,7 +632,7 @@ uint64_t FileSystemTemplate<FileStore, FS_TYPE>::findInodeOf(const char *path) {
|
||||
auto dir = (Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t>*) 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;
|
||||
@@ -702,7 +738,9 @@ int FileSystemTemplate<FileStore, FS_TYPE>::insertDirectoryEntry(const char *dir
|
||||
auto entry = (DirectoryEntry<typename FileStore::InodeId_t>*) &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;
|
||||
}
|
||||
@@ -779,7 +817,9 @@ int FileSystemTemplate<FileStore, FS_TYPE>::rmDirectoryEntry(const char *path) {
|
||||
}
|
||||
|
||||
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) {
|
||||
return err;
|
||||
|
||||
@@ -314,9 +314,11 @@ map<string, int(*)(string)> tests = {
|
||||
|
||||
fs->ls("/usr/share/", &files);
|
||||
|
||||
retval |= !(files[0].name == "a.txt");
|
||||
retval |= !(files[1].name == "b.txt");
|
||||
retval |= !(files[2].name == "c.txt");
|
||||
retval |= !(files[0].name == ".");
|
||||
retval |= !(files[1].name == "..");
|
||||
retval |= !(files[2].name == "a.txt");
|
||||
retval |= !(files[3].name == "b.txt");
|
||||
retval |= !(files[4].name == "c.txt");
|
||||
|
||||
delete fs;
|
||||
delete []buff;
|
||||
|
||||
Reference in New Issue
Block a user