[ox/fs] Fix problems with creating and reading directories

This commit is contained in:
Gary Talent 2019-11-03 16:44:57 -06:00
parent c30ef720c4
commit deaa293c67
7 changed files with 63 additions and 56 deletions

View File

@ -729,6 +729,7 @@ typename FileStoreTemplate<size_t>::ItemPtr FileStoreTemplate<size_t>::find(Item
template<typename size_t>
typename FileStoreTemplate<size_t>::ItemPtr FileStoreTemplate<size_t>::find(InodeId_t id) const {
oxTrace("ox::fs::FileStoreTemplate::find") << "Searching for inode:" << id;
auto fsData = fileStoreData();
if (fsData) {
auto root = m_buffer->ptr(fsData->rootNode);

View File

@ -133,13 +133,13 @@ ox::Error Directory<FileStore, InodeId_t>::init() noexcept {
oxTrace("ox::fs::Directory::init") << "Initializing Directory with Inode ID:" << m_inodeId;
oxReturnError(m_fs.write(m_inodeId, nullptr, Size));
auto buff = m_fs.read(m_inodeId).template to<Buffer>();
if (buff.valid()) {
new (buff) Buffer(Size);
m_size = Size;
return OxError(0);
if (!buff.valid()) {
m_size = 0;
return OxError(1);
}
m_size = 0;
return OxError(1);
new (buff) Buffer(Size);
m_size = Size;
return OxError(0);
}
template<typename FileStore, typename InodeId_t>
@ -217,25 +217,27 @@ ox::Error Directory<FileStore, InodeId_t>::write(PathIterator path, InodeId_t in
return OxError(1);
}
} else {
oxTrace("ox::fs::Directory::write") << path.fullPath();
// insert the new entry on this directory
// get the name
path.next(name);
oxTrace("ox::fs::Directory::write") << "Attempting to write Directory to FileStore";
// find existing version of directory
oxTrace("ox::fs::Directory::write") << "Searching for inode" << m_inodeId;
auto old = m_fs.read(m_inodeId);
oxTrace("ox::fs::Directory::write") << "Searching for directory inode" << m_inodeId;
auto oldStat = m_fs.stat(m_inodeId);
oxReturnError(oldStat);
oxTrace("ox::fs::Directory::write") << "Found existing directory of size" << oldStat.value.size;
auto old = m_fs.read(m_inodeId).template to<Buffer>();
if (!old.valid()) {
oxTrace("ox::fs::Directory::write::fail") << "Could not read existing version of Directory";
return OxError(1);
}
const auto entrySize = DirectoryEntry<InodeId_t>::spaceNeeded(name->len() + 1); // add 1 for \0
const auto entryDataSize = DirectoryEntry<InodeId_t>::DirectoryEntryData::spaceNeeded(name->len());
const auto entryDataSize = DirectoryEntry<InodeId_t>::DirectoryEntryData::spaceNeeded(name->len() + 1);
const auto entrySize = DirectoryEntry<InodeId_t>::spaceNeeded(entryDataSize);
const auto newSize = Buffer::spaceNeeded(m_size + entrySize);
auto cpy = ox_malloca(newSize, Buffer, old);
auto cpy = ox_malloca(newSize, Buffer, *old, oldStat.value.size);
if (cpy == nullptr) {
oxTrace("ox::fs::Directory::write::fail") << "Could not allocate memory for copy of Directory";
return OxError(1);
@ -346,16 +348,14 @@ ValErr<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::find(Path
oxReturnError(path.get(name));
auto v = findEntry(name->c_str());
if (!v.error) {
return v;
oxReturnError(v);
// recurse if not at end of path
if (auto p = path.next(); p.valid()) {
Directory dir(m_fs, v.value);
name = nullptr;
return dir.find(p, nameBuff);
}
name = nullptr;
v = find(path.next(), nameBuff);
if (!v.error) {
return v;
}
return {0, OxError(1)};
return v;
}

View File

@ -10,7 +10,7 @@
namespace ox {
[[nodiscard]] ox::ValErr<const uint8_t*> FileSystem::read(FileAddress addr) {
[[nodiscard]] ox::ValErr<uint8_t*> FileSystem::read(FileAddress addr) {
switch (addr.type()) {
case FileAddressType::Inode:
return read(addr.getInode().value);

View File

@ -32,19 +32,19 @@ class FileSystem {
[[nodiscard]] virtual ox::Error read(const char *path, void *buffer, std::size_t buffSize) = 0;
[[nodiscard]] virtual ox::ValErr<const uint8_t*> read(const char *path) = 0;
[[nodiscard]] virtual ox::ValErr<uint8_t*> read(const char *path) = 0;
[[nodiscard]] virtual ox::Error read(uint64_t inode, void *buffer, std::size_t size) = 0;
[[nodiscard]] virtual ox::Error read(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) = 0;
[[nodiscard]] virtual ox::ValErr<const uint8_t*> read(uint64_t inode) = 0;
[[nodiscard]] virtual ox::ValErr<uint8_t*> read(uint64_t inode) = 0;
[[nodiscard]] ox::Error read(FileAddress addr, void *buffer, std::size_t size);
[[nodiscard]] ox::Error read(FileAddress addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size);
[[nodiscard]] ox::ValErr<const uint8_t*> read(FileAddress addr);
[[nodiscard]] ox::ValErr<uint8_t*> read(FileAddress addr);
[[nodiscard]] virtual ox::Error remove(const char *path, bool recursive = false) = 0;
@ -110,13 +110,13 @@ class FileSystemTemplate: public FileSystem {
[[nodiscard]] ox::Error read(const char *path, void *buffer, std::size_t buffSize) override;
[[nodiscard]] ox::ValErr<const uint8_t*> read(const char*) override;
[[nodiscard]] ox::ValErr<uint8_t*> read(const char*) override;
[[nodiscard]] ox::Error read(uint64_t inode, void *buffer, std::size_t size) override;
[[nodiscard]] ox::Error read(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) override;
[[nodiscard]] ox::ValErr<const uint8_t*> read(uint64_t) override;
[[nodiscard]] ox::ValErr<uint8_t*> read(uint64_t) override;
template<typename F>
[[nodiscard]] ox::Error ls(const char *dir, F cb);
@ -185,8 +185,9 @@ ox::Error FileSystemTemplate<FileStore, Directory>::format(void *buff, uint64_t
oxTrace("ox::fs::FileSystemTemplate::format") << "rootDirInode:" << fd.rootDirInode;
oxReturnError(fs.write(InodeFsData, &fd, sizeof(fd)));
if (fs.read(fd.rootDirInode).valid()) {
if (!fs.read(fd.rootDirInode).valid()) {
oxTrace("ox::fs::FileSystemTemplate::format::error") << "FileSystemTemplate::format did not correctly create root directory";
return OxError(1);
}
return OxError(0);
@ -223,7 +224,7 @@ ox::Error FileSystemTemplate<FileStore, Directory>::read(const char *path, void
}
template<typename FileStore, typename Directory>
[[nodiscard]] ox::ValErr<const uint8_t*> FileSystemTemplate<FileStore, Directory>::read(const char *path) {
[[nodiscard]] ox::ValErr<uint8_t*> FileSystemTemplate<FileStore, Directory>::read(const char *path) {
auto fd = fileSystemData();
oxReturnError(fd.error);
Directory rootDir(m_fs, fd.value.rootDirInode);
@ -243,7 +244,7 @@ ox::Error FileSystemTemplate<FileStore, Directory>::read(uint64_t inode, std::si
}
template<typename FileStore, typename Directory>
[[nodiscard]] ox::ValErr<const uint8_t*> FileSystemTemplate<FileStore, Directory>::read(uint64_t inode) {
[[nodiscard]] ox::ValErr<uint8_t*> FileSystemTemplate<FileStore, Directory>::read(uint64_t inode) {
auto data = m_fs.read(inode);
if (!data.valid()) {
return OxError(1);

View File

@ -58,7 +58,7 @@ Error PassThroughFS::read(const char *path, void *buffer, std::size_t buffSize)
return OxError(1);
}
ValErr<const uint8_t*> PassThroughFS::read(const char*) {
ValErr<uint8_t*> PassThroughFS::read(const char*) {
return OxError(1);
}
@ -72,7 +72,7 @@ Error PassThroughFS::read(uint64_t, std::size_t, std::size_t, void*, std::size_t
return OxError(1);
}
ValErr<const uint8_t*> PassThroughFS::read(uint64_t) {
ValErr<uint8_t*> PassThroughFS::read(uint64_t) {
return OxError(1);
}

View File

@ -43,13 +43,13 @@ class PassThroughFS: public FileSystem {
ox::Error read(const char *path, void *buffer, std::size_t buffSize) override;
ox::ValErr<const uint8_t*> read(const char*) override;
ox::ValErr<uint8_t*> read(const char*) override;
ox::Error read(uint64_t inode, void *buffer, std::size_t size) override;
ox::Error read(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) override;
ox::ValErr<const uint8_t*> read(uint64_t) override;
ox::ValErr<uint8_t*> read(uint64_t) override;
template<typename F>
ox::Error ls(const char *dir, F cb);

View File

@ -8,6 +8,7 @@
#include <ox/std/memops.hpp>
#include <ox/std/strops.hpp>
#include <ox/std/trace.hpp>
#include "pathiterator.hpp"
namespace ox {
@ -59,33 +60,37 @@ Error PathIterator::fileName(char *out, std::size_t outSize) {
// Gets the get item in the path
Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
std::size_t size = 0;
auto retval = OxError(1);
if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) {
retval = OxError(0);
auto start = m_iterator;
if (m_path[start] == '/') {
start++;
}
// end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next /
if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
}
std::size_t end = substr - m_path;
size = end - start;
// cannot fit the output in the output parameter
if (size >= pathOutSize || size == 0) {
return OxError(1);
}
ox_memcpy(pathOut, &m_path[start], size);
if (m_iterator >= m_maxSize) {
oxTrace("ox::fs::PathIterator::get") << "m_iterator >= m_maxSize";
return OxError(1);
}
if (!ox_strlen(&m_path[m_iterator])) {
oxTrace("ox::fs::PathIterator::get") << "!ox_strlen(&m_path[m_iterator])";
return OxError(1);
}
auto start = m_iterator;
if (m_path[start] == '/') {
start++;
}
// end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next /
if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
}
std::size_t end = substr - m_path;
size = end - start;
// cannot fit the output in the output parameter
if (size >= pathOutSize || size == 0) {
return OxError(1);
}
ox_memcpy(pathOut, &m_path[start], size);
// truncate trailing /
if (size && pathOut[size - 1] == '/') {
size--;
}
pathOut[size] = 0; // end with null terminator
return retval;
return OxError(0);
}
// Gets the get item in the path