[ox/fs] Fill out new FileSystem method stubs

This commit is contained in:
Gary Talent 2018-08-18 23:41:31 -05:00
parent 3d3ea32357
commit 40f8af85a8
6 changed files with 124 additions and 69 deletions

View File

@ -12,16 +12,16 @@
namespace ox::fs {
using InodeId_t = uintptr_t;
using FsSize_t = uintptr_t;
using InodeId_t = uint64_t;
using FsSize_t = std::size_t;
class FileStore {
public:
struct StatInfo {
InodeId_t inodeId = 0;
InodeId_t inode = 0;
InodeId_t links = 0;
InodeId_t size = 0;
FsSize_t size = 0;
uint8_t fileType = 0;
};
@ -40,7 +40,7 @@ class FileStore {
*/
virtual Error remove(InodeId_t id) = 0;
virtual Error read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size = nullptr) = 0;
virtual Error read(InodeId_t id, void *data, FsSize_t dataSize, std::size_t *size = nullptr) = 0;
virtual Error read(InodeId_t id, FsSize_t readStart, FsSize_t readSize, void *data, FsSize_t *size = nullptr) = 0;
@ -59,6 +59,14 @@ class FileStore {
virtual InodeId_t available() = 0;
/**
* @return a pointer to the buffer of the file system, or null if not
* applicable
*/
virtual uint8_t *buff() = 0;
virtual Error walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) = 0;
virtual ValErr<InodeId_t> generateInodeId() = 0;
};

View File

@ -63,23 +63,23 @@ class FileStoreTemplate: public FileStore {
public:
FileStoreTemplate(void *buff, size_t buffSize);
Error format();
Error format() override;
Error setSize(InodeId_t buffSize);
Error setSize(InodeId_t buffSize) override;
Error incLinks(InodeId_t id);
Error incLinks(InodeId_t id) override;
Error decLinks(InodeId_t id);
Error decLinks(InodeId_t id) override;
Error write(InodeId_t id, void *data, FsSize_t dataLen, uint8_t fileType = 0);
Error write(InodeId_t id, void *data, FsSize_t dataLen, uint8_t fileType = 0) override;
Error remove(InodeId_t id);
Error remove(InodeId_t id) override;
Error read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size);
Error read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size) override;
Error read(InodeId_t id, FsSize_t readStart, FsSize_t readSize, void *data, FsSize_t *size);
Error read(InodeId_t id, FsSize_t readStart, FsSize_t readSize, void *data, FsSize_t *size) override;
const ptrarith::Ptr<uint8_t, std::size_t> read(InodeId_t id);
const ptrarith::Ptr<uint8_t, std::size_t> read(InodeId_t id) override;
/**
* Reads the "file" at the given id. You are responsible for freeing
@ -96,17 +96,21 @@ class FileStoreTemplate: public FileStore {
FsSize_t readSize, T *data,
FsSize_t *size);
ValErr<StatInfo> stat(InodeId_t id);
ValErr<StatInfo> stat(InodeId_t id) override;
Error resize(std::size_t size, void *newBuff = nullptr);
Error resize(std::size_t size, void *newBuff = nullptr) override;
InodeId_t spaceNeeded(FsSize_t size);
InodeId_t spaceNeeded(FsSize_t size) override;
InodeId_t size();
InodeId_t size() override;
InodeId_t available();
InodeId_t available() override;
ValErr<InodeId_t> generateInodeId();
uint8_t *buff() override;
Error walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) override;
ValErr<InodeId_t> generateInodeId() override;
private:
void compact();
@ -376,6 +380,10 @@ const ptrarith::Ptr<uint8_t, std::size_t> FileStoreTemplate<size_t>::read(InodeI
template<typename size_t>
Error FileStoreTemplate<size_t>::resize(std::size_t size, void *newBuff) {
m_buffSize = size;
if (newBuff) {
m_buffer = reinterpret_cast<Buffer*>(newBuff);
}
return OxError(0);
}
@ -384,7 +392,7 @@ ValErr<typename FileStoreTemplate<size_t>::StatInfo> FileStoreTemplate<size_t>::
auto inode = find(id);
if (inode.valid()) {
return ValErr<StatInfo>({
.inodeId = id,
.inode = id,
.links = inode->links,
.size = inode->size(),
.fileType = inode->fileType,
@ -408,6 +416,19 @@ InodeId_t FileStoreTemplate<size_t>::available() {
return m_buffer->available();
}
template<typename size_t>
uint8_t *FileStoreTemplate<size_t>::buff() {
return reinterpret_cast<uint8_t*>(m_buffer);
}
template<typename size_t>
Error FileStoreTemplate<size_t>::walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) {
for (auto i = m_buffer->iterator(); i.valid(); i.next()) {
oxReturnError(cb(i->fileType, i.ptr().offset(), i.ptr().end()));
}
return OxError(0);
}
template<typename size_t>
ValErr<InodeId_t> FileStoreTemplate<size_t>::generateInodeId() {
auto fsData = fileStoreData();

View File

@ -30,4 +30,4 @@ struct FileStat {
uint8_t fileType = 0;
};
}
}

View File

@ -50,15 +50,15 @@ class FileSystemTemplate {
Error remove(const char *path, bool recursive = false);
void resize(uint64_t size = 0);
void resize(uint64_t size, void *buffer = nullptr);
Error write(const char *path, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile);
Error write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile);
FileStat stat(uint64_t inode);
ValErr<FileStat> stat(uint64_t inode);
FileStat stat(const char *path);
ValErr<FileStat> stat(const char *path);
uint64_t spaceNeeded(uint64_t size);
@ -68,13 +68,18 @@ class FileSystemTemplate {
uint8_t *buff();
void walk(int(*cb)(const char*, uint64_t, uint64_t));
Error walk(Error(*cb)(uint8_t, uint64_t, uint64_t));
bool valid() const;
private:
ValErr<FileSystemData> fileSystemData();
/**
* Finds the inode ID at the given path.
*/
ValErr<uint64_t> find(const char *path);
};
template<typename InodeId_t>
@ -122,29 +127,23 @@ Error FileSystemTemplate<InodeId_t>::mkdir(const char *path, bool recursive) {
template<typename InodeId_t>
Error FileSystemTemplate<InodeId_t>::move(const char *src, const char *dest) {
auto fd = fileSystemData();
if (fd.ok()) {
auto rootDir = ox_malloca(sizeof(ox::fs::Directory<InodeId_t>), ox::fs::Directory<InodeId_t>, m_fs, fd.value.rootDirInode);
auto inode = rootDir->find(src);
oxReturnError(inode.error);
oxReturnError(rootDir->write(dest, inode));
oxReturnError(rootDir->remove(src));
return OxError(0);
} else {
return fd.error;
}
oxReturnError(fd.error);
auto rootDir = ox_malloca(sizeof(ox::fs::Directory<InodeId_t>), ox::fs::Directory<InodeId_t>, m_fs, fd.value.rootDirInode);
auto inode = rootDir->find(src);
oxReturnError(inode.error);
oxReturnError(rootDir->write(dest, inode));
oxReturnError(rootDir->remove(src));
return OxError(0);
}
template<typename InodeId_t>
Error FileSystemTemplate<InodeId_t>::read(const char *path, void *buffer, std::size_t buffSize) {
auto fd = fileSystemData();
if (fd.ok()) {
auto rootDir = ox_malloca(sizeof(ox::fs::Directory<InodeId_t>), ox::fs::Directory<InodeId_t>, m_fs, fd.value.rootDirInode);
auto inode = rootDir->find(path);
oxReturnError(inode.error);
return read(inode, buffer, buffSize);
} else {
return fd.error;
}
oxReturnError(fd.error);
auto rootDir = ox_malloca(sizeof(ox::fs::Directory<InodeId_t>), ox::fs::Directory<InodeId_t>, m_fs, fd.value.rootDirInode);
auto inode = rootDir->find(path);
oxReturnError(inode.error);
return read(inode, buffer, buffSize);
}
template<typename InodeId_t>
@ -160,67 +159,79 @@ Error FileSystemTemplate<InodeId_t>::read(uint64_t inode, std::size_t readStart,
template<typename InodeId_t>
Error FileSystemTemplate<InodeId_t>::remove(const char *path, bool recursive) {
auto fd = fileSystemData();
if (fd.ok()) {
auto rootDir = ox_malloca(sizeof(ox::fs::Directory<InodeId_t>), ox::fs::Directory<InodeId_t>, m_fs, fd.value.rootDirInode);
auto inode = rootDir->find(path);
oxReturnError(inode.error);
if (auto err = rootDir->remove(path)) {
// removal failed, try putting the index back
oxLogError(rootDir->write(path, inode));
return err;
}
return OxError(0);
} else {
return fd.error;
oxReturnError(fd.error);
auto rootDir = ox_malloca(sizeof(ox::fs::Directory<InodeId_t>), ox::fs::Directory<InodeId_t>, m_fs, fd.value.rootDirInode);
auto inode = rootDir->find(path);
oxReturnError(inode.error);
if (auto err = rootDir->remove(path)) {
// removal failed, try putting the index back
oxLogError(rootDir->write(path, inode));
return err;
}
return OxError(0);
}
template<typename InodeId_t>
void FileSystemTemplate<InodeId_t>::resize(uint64_t size) {
void FileSystemTemplate<InodeId_t>::resize(uint64_t size, void *buffer) {
m_fs->resize(size, buffer);
}
template<typename InodeId_t>
Error FileSystemTemplate<InodeId_t>::write(const char *path, void *buffer, uint64_t size, uint8_t fileType) {
return OxError(0);
auto inode = find(path);
oxReturnError(inode.error);
return write(inode, buffer, size, fileType);
}
template<typename InodeId_t>
Error FileSystemTemplate<InodeId_t>::write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType) {
return OxError(0);
// TODO: directory insert
return m_fs->write(inode, buffer, size, fileType);
}
template<typename InodeId_t>
FileStat FileSystemTemplate<InodeId_t>::stat(uint64_t inode) {
return {};
ValErr<FileStat> FileSystemTemplate<InodeId_t>::stat(uint64_t inode) {
auto s = m_fs->stat(inode);
FileStat out;
out.inode = s.value.inode;
out.links = s.value.links;
out.size = s.value.size;
out.fileType = s.value.fileType;
return {out, s.error};
}
template<typename InodeId_t>
FileStat FileSystemTemplate<InodeId_t>::stat(const char *path) {
return {};
ValErr<FileStat> FileSystemTemplate<InodeId_t>::stat(const char *path) {
auto inode = find(path);
if (inode.error) {
return {{}, inode.error};
}
return stat(inode.value);
}
template<typename InodeId_t>
uint64_t FileSystemTemplate<InodeId_t>::spaceNeeded(uint64_t size) {
return 0;
return m_fs->spaceNeeded(size);
}
template<typename InodeId_t>
uint64_t FileSystemTemplate<InodeId_t>::available() {
return 0;
return m_fs->available();
}
template<typename InodeId_t>
uint64_t FileSystemTemplate<InodeId_t>::size() {
return 0;
return m_fs->size();
}
template<typename InodeId_t>
uint8_t *FileSystemTemplate<InodeId_t>::buff() {
return nullptr;
return m_fs->buff();
}
template<typename InodeId_t>
void FileSystemTemplate<InodeId_t>::walk(int(*cb)(const char*, uint64_t, uint64_t)) {
Error FileSystemTemplate<InodeId_t>::walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) {
return m_fs->walk(cb);
}
template<typename InodeId_t>
@ -233,6 +244,16 @@ ValErr<typename FileSystemTemplate<InodeId_t>::FileSystemData> FileSystemTemplat
return fd;
}
template<typename InodeId_t>
ValErr<uint64_t> FileSystemTemplate<InodeId_t>::find(const char *path) {
auto fd = fileSystemData();
oxReturnError(fd.error);
auto rootDir = ox_malloca(sizeof(ox::fs::Directory<InodeId_t>), ox::fs::Directory<InodeId_t>, m_fs, fd.value.rootDirInode);
auto inode = rootDir->find(path);
oxReturnError(inode.error);
return inode.value;
}
extern template class Directory<uint16_t>;
extern template class Directory<uint32_t>;

View File

@ -416,7 +416,8 @@ map<string, int(*)(string)> tests = {
oxAssert(fs.format(), "FileSystem format failed");
oxTrace("ox::fs::test::FileSystem") << "mkdir";
oxAssert(fs.mkdir("/l1d1", true) == 0, "mkdir failed");
oxAssert(fs.mkdir("/l1d1/l2d1/l3d1", true), "mkdir failed");
oxAssert(fs.mkdir("/l1d1/l2d2", true), "mkdir failed");
return 0;
}

View File

@ -43,6 +43,10 @@ class __attribute__((packed)) NodeBuffer {
return m_current;
}
ItemPtr ptr() {
return m_current;
}
Item *get() {
return m_current;
}