Squashed 'deps/ox/' changes from 56d91c1..4887d55

4887d55 Merge branch 'master' of github.com:wombatant/ox
84533e5 Add walk command.
916d07e Merge branch 'master' of github.com:wombatant/ox into ox_master
31af216 Add operator< for DirectoryListing
218511c Fix mkdir not to overwrite an existing dir
15e05df Remove unused scripts
292caad Add link count to stat in FS
99e459a Add links count field to inodes
3211cc4 Add . and .. directory entries to directores
30c2837 Switch to .liccor.yml
16b6ed3 Add a check to ls to prevent ls-ing of non-directories

git-subtree-dir: deps/ox
git-subtree-split: 4887d55a984c0d9c53d9faa9747ef5e9b7c1674a
This commit is contained in:
Gary Talent 2017-09-09 20:10:07 -05:00
parent feb7e4c184
commit 2d1b146abf
9 changed files with 198 additions and 52 deletions

View File

@ -1,5 +0,0 @@
Copyright 2015 - 2017 gtalent2@gmail.com
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.

9
.liccor.yml Normal file
View File

@ -0,0 +1,9 @@
---
source:
- src
copyright_notice: |-
Copyright 2015 - 2017 gtalent2@gmail.com
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.

View File

@ -1 +0,0 @@
clang-check `find . | grep "\.cpp" | grep -v CMakeFiles | grep -v editormodels\.cpp`

View File

@ -1,16 +0,0 @@
#! /usr/bin/env python
import sys
if len(sys.argv) < 3:
sys.exit(1)
pkg = sys.argv[1]
name = sys.argv[2]
ifdef = "WOMBAT_%s_%s_HPP" % (pkg.upper(), name.upper())
namespace = "namespace wombat {\nnamespace %s {\n\n}\n}" % pkg
hpp = "#ifndef %s\n#define %s\n\n%s\n\n#endif" % (ifdef, ifdef, namespace)
cpp = "#include \"%s.hpp\"\n\n%s" % (name, namespace)
open("src/%s/%s.hpp" % (pkg, name), "w").write(hpp)
open("src/%s/%s.cpp" % (pkg, name), "w").write(cpp)

View File

@ -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;
@ -103,6 +103,7 @@ class FileStore {
struct StatInfo { struct StatInfo {
InodeId_t inodeId; InodeId_t inodeId;
InodeId_t links;
typename Header::FsSize_t size; typename Header::FsSize_t size;
uint8_t fileType; uint8_t fileType;
}; };
@ -116,6 +117,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 +137,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 +183,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
@ -251,6 +268,8 @@ class FileStore {
*/ */
typename Header::FsSize_t available(); typename Header::FsSize_t available();
void walk(int(*cb)(const char*, uint64_t start, uint64_t end));
uint16_t fsType(); uint16_t fsType();
uint16_t version(); uint16_t version();
@ -268,7 +287,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 +424,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 +470,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 +539,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;
@ -664,6 +722,7 @@ typename FileStore<Header>::StatInfo FileStore<Header>::stat(InodeId_t id) {
if (inode) { if (inode) {
stat.size = inode->getDataLen(); stat.size = inode->getDataLen();
stat.fileType = inode->getFileType(); stat.fileType = inode->getFileType();
stat.links = inode->getLinks();
stat.inodeId = id; stat.inodeId = id;
} else { } else {
stat.inodeId = 0; stat.inodeId = 0;
@ -830,6 +889,17 @@ uint16_t FileStore<Header>::version() {
return m_header.getVersion(); return m_header.getVersion();
}; };
template<typename Header>
void FileStore<Header>::walk(int(*cb)(const char*, uint64_t start, uint64_t end)) {
auto err = cb("Header", 0, sizeof(Header));
auto inode = ptr<Inode*>(firstInode());
while (!err && inode != (Inode*) begin()) {
inode = ptr<Inode*>(inode->getNext());
auto start = ptr(inode);
err = cb("Inode", start, start + inode->size());
}
}
template<typename Header> template<typename Header>
uint8_t *FileStore<Header>::format(uint8_t *buffer, typename Header::FsSize_t size, uint16_t fsType) { uint8_t *FileStore<Header>::format(uint8_t *buffer, typename Header::FsSize_t size, uint16_t fsType) {
ox_memset(buffer, 0, size); ox_memset(buffer, 0, size);

View File

@ -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);

View File

@ -26,6 +26,7 @@ enum FileType {
struct FileStat { struct FileStat {
uint64_t inode; uint64_t inode;
uint64_t links;
uint64_t size; uint64_t size;
uint8_t fileType; uint8_t fileType;
}; };
@ -42,6 +43,11 @@ struct DirectoryListing {
} }
}; };
template<typename String>
bool operator<(const DirectoryListing<String> &a, const DirectoryListing<String> &b) {
return a.name < b.name;
}
template<typename InodeId_t> template<typename InodeId_t>
struct __attribute__((packed)) DirectoryEntry { struct __attribute__((packed)) DirectoryEntry {
InodeId_t inode; InodeId_t inode;
@ -81,7 +87,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 +100,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) {
@ -120,7 +126,9 @@ int Directory<InodeId_t, FsSize_t>::getChildrenInodes(InodeId_t *inodes, size_t
auto current = files(); auto current = files();
if (current) { if (current) {
for (uint64_t i = 0; i < this->children; i++) { for (uint64_t i = 0; i < this->children; i++) {
if (ox_strcmp(current->getName(), ".") and ox_strcmp(current->getName(), "..")) {
inodes[i] = current->inode; inodes[i] = current->inode;
}
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size()); current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
} }
return 0; return 0;
@ -201,6 +209,13 @@ class FileSystem {
virtual int mkdir(const char *path) = 0; 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> template<typename List>
int ls(const char *path, List *list); int ls(const char *path, List *list);
@ -234,17 +249,22 @@ class FileSystem {
virtual uint8_t *buff() = 0; virtual uint8_t *buff() = 0;
virtual void walk(int(*cb)(const char*, uint64_t, uint64_t)) = 0;
protected: protected:
virtual int readDirectory(const char *path, Directory<uint64_t, uint64_t> *dirOut) = 0; virtual int readDirectory(const char *path, Directory<uint64_t, uint64_t> *dirOut) = 0;
}; };
template<typename List> template<typename List>
int FileSystem::ls(const char *path, List *list) { int FileSystem::ls(const char *path, List *list) {
int err = 0;
auto s = stat(path); auto s = stat(path);
if (s.fileType == FileType_Directory) {
uint8_t dirBuff[s.size * 4]; uint8_t dirBuff[s.size * 4];
auto dir = (Directory<uint64_t, uint64_t>*) dirBuff; auto dir = (Directory<uint64_t, uint64_t>*) dirBuff;
auto err = readDirectory(path, dir); err = readDirectory(path, dir);
err |= dir->ls(list); err |= dir->ls(list);
}
return err; return err;
} }
@ -314,18 +334,15 @@ class FileSystemTemplate: public FileSystem {
uint8_t *buff() override; uint8_t *buff() override;
/** int move(const char *src, const char *dest) 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);
/** /**
* Removes an entry from a directory. This does not delete the referred to file. * Removes an entry from a directory. This does not delete the referred to file.
*/ */
int rmDirectoryEntry(const char *path); int rmDirectoryEntry(const char *path);
void walk(int(*cb)(const char*, uint64_t, uint64_t)) override;
static uint8_t *format(uint8_t *buffer, typename FileStore::FsSize_t size, bool useDirectories); static uint8_t *format(uint8_t *buffer, typename FileStore::FsSize_t size, bool useDirectories);
protected: protected:
@ -368,8 +385,36 @@ int FileSystemTemplate<FileStore, FS_TYPE>::stripDirectories() {
template<typename FileStore, FsType FS_TYPE> template<typename FileStore, FsType FS_TYPE>
int FileSystemTemplate<FileStore, FS_TYPE>::mkdir(const char *path) { int FileSystemTemplate<FileStore, FS_TYPE>::mkdir(const char *path) {
if (!stat(path).inode) {
Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t> dir; 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;
}
} }
template<typename FileStore, FsType FS_TYPE> template<typename FileStore, FsType FS_TYPE>
@ -392,6 +437,7 @@ FileStat FileSystemTemplate<FileStore, FS_TYPE>::stat(uint64_t inode) {
auto s = m_store->stat(inode); auto s = m_store->stat(inode);
stat.size = s.size; stat.size = s.size;
stat.inode = s.inodeId; stat.inode = s.inodeId;
stat.links = s.links;
stat.fileType = s.fileType; stat.fileType = s.fileType;
return stat; return stat;
} }
@ -476,7 +522,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;
} }
@ -503,11 +549,14 @@ int FileSystemTemplate<FileStore, FS_TYPE>::remove(uint64_t inode, bool recursiv
} }
typename FileStore::InodeId_t inodes[dir->children]; typename FileStore::InodeId_t inodes[dir->children];
ox_memset(inodes, 0, sizeof(typename FileStore::InodeId_t) * dir->children);
dir->getChildrenInodes(inodes, dir->children); dir->getChildrenInodes(inodes, dir->children);
for (auto i : inodes) { for (auto i : inodes) {
if (i) {
err |= remove(i, true); err |= remove(i, true);
} }
}
if (!err) { if (!err) {
err |= m_store->remove(inode); err |= m_store->remove(inode);
@ -542,7 +591,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) {
@ -587,7 +637,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;
@ -693,7 +743,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;
} }
@ -770,7 +822,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;
@ -809,6 +863,11 @@ void FileSystemTemplate<FileStore, FS_TYPE>::expand(uint64_t newSize) {
} }
} }
template<typename FileStore, FsType FS_TYPE>
void FileSystemTemplate<FileStore, FS_TYPE>::walk(int(*cb)(const char*, uint64_t, uint64_t)) {
m_store->walk(cb);
}
typedef FileSystemTemplate<FileStore16, OxFS_16> FileSystem16; typedef FileSystemTemplate<FileStore16, OxFS_16> FileSystem16;
typedef FileSystemTemplate<FileStore32, OxFS_32> FileSystem32; typedef FileSystemTemplate<FileStore32, OxFS_32> FileSystem32;
typedef FileSystemTemplate<FileStore64, OxFS_64> FileSystem64; typedef FileSystemTemplate<FileStore64, OxFS_64> FileSystem64;

View File

@ -20,7 +20,7 @@
using namespace ox; using namespace ox;
using namespace std; using namespace std;
const static auto oxfstoolVersion = "1.3.0"; const static auto oxfstoolVersion = "1.4.0";
const static auto usage = "usage:\n" const static auto usage = "usage:\n"
"\toxfs format [16,32,64] <size> <path>\n" "\toxfs format [16,32,64] <size> <path>\n"
"\toxfs read <FS file> <inode>\n" "\toxfs read <FS file> <inode>\n"
@ -28,6 +28,7 @@ const static auto usage = "usage:\n"
"\toxfs write-expand <FS file> <inode> <insertion file>\n" "\toxfs write-expand <FS file> <inode> <insertion file>\n"
"\toxfs rm <FS file> <inode>\n" "\toxfs rm <FS file> <inode>\n"
"\toxfs compact <FS file>\n" "\toxfs compact <FS file>\n"
"\toxfs walk <FS file>\n"
"\toxfs version\n"; "\toxfs version\n";
uint8_t *loadFileBuff(FILE *file, ::size_t *sizeOut = nullptr) { uint8_t *loadFileBuff(FILE *file, ::size_t *sizeOut = nullptr) {
@ -333,6 +334,31 @@ int remove(int argc, char **args) {
return err; return err;
} }
int walk(int argc, char **args) {
int err = 0;
size_t fsSize;
auto fsPath = args[2];
auto fsBuff = loadFileBuff(fsPath, &fsSize);
if (fsBuff) {
auto fs = createFileSystem(fsBuff, fsSize);
if (fs) {
fs->walk([](const char *type, uint64_t start, uint64_t end) {
cout << "narf\n";
cout << type << ", start: " << start << ", end: " << end << endl;
return 0;
});
delete fs;
} else {
cerr << "Invalid file system.\n";
err = 1;
}
delete []fsBuff;
} else {
err = 2;
}
return err;
}
int main(int argc, char **args) { int main(int argc, char **args) {
auto err = 0; auto err = 0;
if (argc > 1) { if (argc > 1) {
@ -349,6 +375,8 @@ int main(int argc, char **args) {
err = compact(argc, args); err = compact(argc, args);
} else if (ox_strcmp(cmd, "rm") == 0) { } else if (ox_strcmp(cmd, "rm") == 0) {
err = remove(argc, args); err = remove(argc, args);
} else if (ox_strcmp(cmd, "walk") == 0) {
err = walk(argc, args);
} else if (ox_strcmp(cmd, "help") == 0) { } else if (ox_strcmp(cmd, "help") == 0) {
printf("%s\n", usage); printf("%s\n", usage);
} else if (ox_strcmp(cmd, "version") == 0) { } else if (ox_strcmp(cmd, "version") == 0) {

View File

@ -314,9 +314,11 @@ map<string, int(*)(string)> tests = {
fs->ls("/usr/share/", &files); fs->ls("/usr/share/", &files);
retval |= !(files[0].name == "a.txt"); retval |= !(files[0].name == ".");
retval |= !(files[1].name == "b.txt"); retval |= !(files[1].name == "..");
retval |= !(files[2].name == "c.txt"); retval |= !(files[2].name == "a.txt");
retval |= !(files[3].name == "b.txt");
retval |= !(files[4].name == "c.txt");
delete fs; delete fs;
delete []buff; delete []buff;