[ox/fs] Cleanup

This commit is contained in:
2024-09-13 00:05:26 -05:00
parent 8dd837b359
commit 702b166b8d
5 changed files with 75 additions and 160 deletions

View File

@ -43,13 +43,14 @@ struct OX_PACKED DirectoryEntry {
public:
constexpr DirectoryEntry() noexcept = default;
Error init(InodeId_t inode, const char *name, InodeId_t bufferSize) noexcept {
m_bufferSize = bufferSize;
Error init(InodeId_t inode, ox::CRStringView name, size_t bufferSize) noexcept {
m_bufferSize = static_cast<InodeId_t>(bufferSize);
auto d = data();
if (d.valid()) {
d->inode = inode;
ox::strncpy(d->name, name, ox::min(bufferSize, static_cast<InodeId_t>(MaxFileNameLength)));
return OxError(0);
auto const maxStrSz = bufferSize - 1 - sizeof(*this);
ox::strncpy(d->name, name.data(), ox::min(maxStrSz, name.len()));
return {};
}
return OxError(1);
}
@ -103,23 +104,23 @@ class Directory {
*/
Error init() noexcept;
Error mkdir(PathIterator path, bool parents, FileName *nameBuff = nullptr);
Error mkdir(PathIterator path, bool parents);
/**
* @param parents indicates the operation should create non-existent directories in the path, like mkdir -p
*/
Error write(PathIterator path, uint64_t inode64, FileName *nameBuff = nullptr) noexcept;
Error write(PathIterator path, uint64_t inode64) noexcept;
Error remove(PathIterator path, FileName *nameBuff = nullptr) noexcept;
Error remove(PathIterator path) noexcept;
template<typename F>
Error ls(F cb) noexcept;
[[nodiscard]]
Result<typename FileStore::InodeId_t> findEntry(const FileName &name) const noexcept;
Result<typename FileStore::InodeId_t> findEntry(const StringView &name) const noexcept;
[[nodiscard]]
Result<typename FileStore::InodeId_t> find(PathIterator name, FileName *nameBuff = nullptr) const noexcept;
Result<typename FileStore::InodeId_t> find(PathIterator path) const noexcept;
};
@ -145,22 +146,17 @@ Error Directory<FileStore, InodeId_t>::init() noexcept {
}
new (buff) Buffer(Size);
m_size = Size;
return OxError(0);
return {};
}
template<typename FileStore, typename InodeId_t>
Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents, FileName *nameBuff) {
Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents) {
if (path.valid()) {
oxTrace("ox.fs.Directory.mkdir", path.fullPath());
// reuse nameBuff if it has already been allocated, as it is a rather large variable
if (nameBuff == nullptr) {
nameBuff = new (ox_alloca(sizeof(FileName))) FileName;
}
// determine if already exists
auto name = nameBuff;
oxReturnError(path.get(*name));
auto childInode = find(PathIterator(*name));
ox::StringView name;
oxReturnError(path.get(name));
auto childInode = find(PathIterator(name));
if (!childInode.ok()) {
// if this is not the last item in the path and parents is disabled,
// return an error
@ -171,12 +167,10 @@ Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents, Fi
oxTracef("ox.fs.Directory.mkdir", "Generated Inode ID: {}", childInode.value);
oxLogError(childInode.error);
oxReturnError(childInode.error);
// initialize the directory
Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
oxReturnError(child.init());
auto err = write(PathIterator(*name), childInode.value);
auto err = write(PathIterator(name), childInode.value);
if (err) {
oxLogError(err);
// could not index the directory, delete it
@ -184,46 +178,34 @@ Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents, Fi
return err;
}
}
Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
if (path.hasNext()) {
oxReturnError(child.mkdir(path.next(), parents, nameBuff));
oxReturnError(child.mkdir(path.next(), parents));
}
}
return OxError(0);
return {};
}
template<typename FileStore, typename InodeId_t>
Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64, FileName *nameBuff) noexcept {
Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64) noexcept {
const auto inode = static_cast<InodeId_t>(inode64);
// reuse nameBuff if it has already been allocated, as it is a rather large variable
if (nameBuff == nullptr) {
nameBuff = new (ox_alloca(sizeof(FileName))) FileName;
}
auto name = nameBuff;
ox::StringView name;
oxReturnError(path.next(name));
if (path.next().hasNext()) { // not yet at target directory, recurse to next one
oxReturnError(path.get(*name));
oxTracef("ox.fs.Directory.write", "Attempting to write to next sub-Directory: {} of {}",
*name, path.fullPath());
oxRequire(nextChild, findEntry(*name));
oxTracef("ox.fs.Directory.write", "{}: {}", *name, nextChild);
name, path.fullPath());
oxRequire(nextChild, findEntry(name));
oxTracef("ox.fs.Directory.write", "{}: {}", name, nextChild);
if (nextChild) {
// reuse name because it is a rather large variable and will not be used again
// be attentive that this remains true
name = nullptr;
return Directory(m_fs, nextChild).write(path.next(), inode, nameBuff);
return Directory(m_fs, nextChild).write(path.next(), inode);
} else {
oxTracef("ox.fs.Directory.write", "{} not found and not allowed to create it.", *name);
oxTracef("ox.fs.Directory.write", "{} not found and not allowed to create it.", name);
return OxError(1, "File not found and not allowed to create it.");
}
} else {
oxTrace("ox.fs.Directory.write", path.fullPath());
// insert the new entry on this directory
// get the name
oxReturnError(path.next(*name));
// find existing version of directory
oxTracef("ox.fs.Directory.write", "Searching for directory inode {}", m_inodeId);
oxRequire(oldStat, m_fs.stat(m_inodeId));
@ -233,8 +215,7 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
oxTrace("ox.fs.Directory.write.fail", "Could not read existing version of Directory");
return OxError(1, "Could not read existing version of Directory");
}
const auto pathSize = name->len() + 1;
const auto pathSize = name.len() + 1;
const auto entryDataSize = DirectoryEntry<InodeId_t>::DirectoryEntryData::spaceNeeded(pathSize);
const auto newSize = oldStat.size + Buffer::spaceNeeded(entryDataSize);
auto cpy = ox_malloca(newSize, Buffer, *old, oldStat.size);
@ -242,29 +223,22 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for copy of Directory");
return OxError(1, "Could not allocate memory for copy of Directory");
}
oxReturnError(cpy->setSize(newSize));
auto val = cpy->malloc(entryDataSize).value;
if (!val.valid()) {
oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for new directory entry");
return OxError(1, "Could not allocate memory for new directory entry");
}
oxTracef("ox.fs.Directory.write", "Attempting to write Directory entry: {}", name->data());
oxReturnError(val->init(inode, name->data(), val.size()));
oxTracef("ox.fs.Directory.write", "Attempting to write Directory entry: {}", name);
oxReturnError(val->init(inode, name, val.size()));
return m_fs.write(m_inodeId, cpy.get(), cpy->size(), static_cast<uint8_t>(FileType::Directory));
}
}
template<typename FileStore, typename InodeId_t>
Error Directory<FileStore, InodeId_t>::remove(PathIterator path, FileName *nameBuff) noexcept {
// reuse nameBuff if it has already been allocated, as it is a rather large variable
if (nameBuff == nullptr) {
nameBuff = new (ox_alloca(sizeof(FileName))) FileName;
}
auto &name = *nameBuff;
Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
ox::StringView name;
oxReturnError(path.get(name));
oxTrace("ox.fs.Directory.remove", name);
auto buff = m_fs.read(m_inodeId).template to<Buffer>();
if (buff.valid()) {
@ -283,7 +257,7 @@ Error Directory<FileStore, InodeId_t>::remove(PathIterator path, FileName *nameB
oxTrace("ox.fs.Directory.remove.fail", "Could not find directory buffer");
return OxError(1, "Could not find directory buffer");
}
return OxError(0);
return {};
}
template<typename FileStore, typename InodeId_t>
@ -295,7 +269,6 @@ Error Directory<FileStore, InodeId_t>::ls(F cb) noexcept {
oxTrace("ox.fs.Directory.ls.fail", "Could not directory buffer");
return OxError(1, "Could not directory buffer");
}
oxTrace("ox.fs.Directory.ls", "Found directory buffer.");
for (auto i = buff->iterator(); i.valid(); i.next()) {
auto data = i->data();
@ -305,12 +278,11 @@ Error Directory<FileStore, InodeId_t>::ls(F cb) noexcept {
oxTrace("ox.fs.Directory.ls", "INVALID DIRECTORY ENTRY");
}
}
return OxError(0);
return {};
}
template<typename FileStore, typename InodeId_t>
Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::findEntry(const FileName &name) const noexcept {
Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::findEntry(CRStringView name) const noexcept {
oxTrace("ox.fs.Directory.findEntry", name);
auto buff = m_fs.read(m_inodeId).template to<Buffer>();
if (!buff.valid()) {
@ -327,7 +299,7 @@ Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::findEntry
return static_cast<InodeId_t>(data->inode);
}
} else {
oxTrace("ox.fs.Directory.findEntry") << "INVALID DIRECTORY ENTRY";
oxTrace("ox.fs.Directory.findEntry", "INVALID DIRECTORY ENTRY");
}
}
oxTrace("ox.fs.Directory.findEntry.fail", "Entry not present");
@ -335,22 +307,15 @@ Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::findEntry
}
template<typename FileStore, typename InodeId_t>
Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::find(PathIterator path, FileName *nameBuff) const noexcept {
// reuse nameBuff if it has already been allocated, as it is a rather large variable
if (nameBuff == nullptr) {
nameBuff = new (ox_alloca(sizeof(FileName))) FileName;
}
Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::find(PathIterator path) const noexcept {
// determine if already exists
auto name = nameBuff;
oxReturnError(path.get(*name));
oxRequire(v, findEntry(*name));
ox::StringView name;
oxReturnError(path.get(name));
oxRequire(v, findEntry(name));
// recurse if not at end of path
if (auto p = path.next(); p.valid()) {
Directory dir(m_fs, v);
name = nullptr;
return dir.find(p, nameBuff);
return dir.find(p);
}
return v;
}