[ox/fs] Fix DirectoryEntry base size
This commit is contained in:
parent
06013211d4
commit
ad956ffd70
89
deps/ox/src/ox/fs/filesystem2/directory.hpp
vendored
89
deps/ox/src/ox/fs/filesystem2/directory.hpp
vendored
@ -18,37 +18,55 @@ namespace ox::fs {
|
|||||||
template<typename InodeId_t>
|
template<typename InodeId_t>
|
||||||
struct __attribute__((packed)) DirectoryEntry {
|
struct __attribute__((packed)) DirectoryEntry {
|
||||||
|
|
||||||
|
struct __attribute__((packed)) DirectoryEntryData {
|
||||||
|
// DirectoryEntry fields
|
||||||
|
LittleEndian<InodeId_t> inode = 0;
|
||||||
|
BString<MaxFileNameLength> name;
|
||||||
|
};
|
||||||
|
|
||||||
// NodeBuffer fields
|
// NodeBuffer fields
|
||||||
LittleEndian<InodeId_t> prev = 0;
|
LittleEndian<InodeId_t> prev = 0;
|
||||||
LittleEndian<InodeId_t> next = 0;
|
LittleEndian<InodeId_t> next = 0;
|
||||||
|
|
||||||
// DirectoryEntry fields
|
|
||||||
LittleEndian<InodeId_t> inode = 0;
|
|
||||||
BString<MaxFileNameLength> name;
|
|
||||||
|
|
||||||
DirectoryEntry() = default;
|
DirectoryEntry() = default;
|
||||||
|
|
||||||
explicit DirectoryEntry(const char *name) {
|
explicit DirectoryEntry(InodeId_t inode, const char *name) {
|
||||||
this->name = name;
|
auto d = data();
|
||||||
|
if (d.valid()) {
|
||||||
|
d->inode = inode;
|
||||||
|
d->name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptrarith::Ptr<DirectoryEntryData, InodeId_t> data() {
|
||||||
|
return ptrarith::Ptr<DirectoryEntryData, InodeId_t>(this, this->fullSize(), sizeof(*this), this->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
const ptrarith::Ptr<DirectoryEntryData, InodeId_t> data() const {
|
||||||
|
return ptrarith::Ptr<DirectoryEntryData, InodeId_t>(const_cast<DirectoryEntry*>(this), this->fullSize(), sizeof(*this), this->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the size of the data + the size of the Item type
|
* @return the size of the data + the size of the Item type
|
||||||
*/
|
*/
|
||||||
InodeId_t fullSize() const {
|
InodeId_t fullSize() const {
|
||||||
return offsetof(DirectoryEntry, name) + name.size();
|
auto d = data();
|
||||||
|
if (d.valid()) {
|
||||||
|
return sizeof(*this) + offsetof(DirectoryEntryData, name) + d->name.size();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
InodeId_t size() const {
|
InodeId_t size() const {
|
||||||
return fullSize() - offsetof(DirectoryEntry, inode);
|
return fullSize() - offsetof(DirectoryEntryData, inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSize(InodeId_t) {
|
void setSize(InodeId_t) {
|
||||||
// ignore set value
|
// ignore set value
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrarith::Ptr<uint8_t, InodeId_t> data() {
|
static std::size_t spaceNeeded(std::size_t chars) {
|
||||||
return ptrarith::Ptr<uint8_t, InodeId_t>(this, this->size(), sizeof(*this), this->size() - sizeof(*this));
|
return sizeof(DirectoryEntry) + chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -59,6 +77,8 @@ class Directory {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
using Buffer = ptrarith::NodeBuffer<InodeId_t, DirectoryEntry<InodeId_t>>;
|
using Buffer = ptrarith::NodeBuffer<InodeId_t, DirectoryEntry<InodeId_t>>;
|
||||||
|
|
||||||
|
InodeId_t m_inodeId = 0;
|
||||||
std::size_t m_size = 0;
|
std::size_t m_size = 0;
|
||||||
Buffer *m_buff = nullptr;
|
Buffer *m_buff = nullptr;
|
||||||
FileStore *m_fs = nullptr;
|
FileStore *m_fs = nullptr;
|
||||||
@ -80,16 +100,23 @@ class Directory {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename InodeId_t>
|
template<typename InodeId_t>
|
||||||
Directory<InodeId_t>::Directory(fs::FileStore *fs, InodeId_t) {
|
Directory<InodeId_t>::Directory(fs::FileStore *fs, InodeId_t id) {
|
||||||
m_fs = fs;
|
m_fs = fs;
|
||||||
//m_size = size;
|
m_inodeId = id;
|
||||||
//m_buff = reinterpret_cast<decltype(m_buff)>(buff);
|
auto buff = fs->read(id).template to<Buffer>();
|
||||||
|
if (buff.valid()) {
|
||||||
|
m_size = buff.size();
|
||||||
|
m_buff = buff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename InodeId_t>
|
template<typename InodeId_t>
|
||||||
Error Directory<InodeId_t>::init() noexcept {
|
Error Directory<InodeId_t>::init() noexcept {
|
||||||
if (m_size >= sizeof(Buffer)) {
|
constexpr auto Size = sizeof(Buffer);
|
||||||
new (m_buff) Buffer(m_size);
|
m_fs->write(m_inodeId, nullptr, Size);
|
||||||
|
auto buff = m_fs->read(m_inodeId);
|
||||||
|
if (buff.valid()) {
|
||||||
|
new (buff) Buffer(Size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -100,17 +127,24 @@ Error Directory<InodeId_t>::write(PathIterator path, InodeId_t inode) noexcept {
|
|||||||
// find existing entry and update if exists
|
// find existing entry and update if exists
|
||||||
|
|
||||||
if (!path.hasNext()) {
|
if (!path.hasNext()) {
|
||||||
|
Error err = 1;
|
||||||
BString<MaxFileNameLength> name;
|
BString<MaxFileNameLength> name;
|
||||||
path.next(&name);
|
path.next(&name);
|
||||||
|
|
||||||
auto val = m_buff->malloc(name.size());
|
// find existing version of directory
|
||||||
|
auto old = m_fs->read(m_inodeId);
|
||||||
|
if (old.valid()) {
|
||||||
|
const auto newSize = m_size + DirectoryEntry<InodeId_t>::spaceNeeded(name.size());
|
||||||
|
auto cpy = new (ox_malloca(newSize)) Buffer(old);
|
||||||
|
cpy->setSize(newSize);
|
||||||
|
auto val = cpy->malloc(name.size());
|
||||||
if (val.valid()) {
|
if (val.valid()) {
|
||||||
new (val) DirectoryEntry<InodeId_t>(name.data());
|
new (val) DirectoryEntry<InodeId_t>(inode, name.data());
|
||||||
val->name = name;
|
err = m_fs->write(m_inodeId, cpy, cpy->size());
|
||||||
val->inode = inode;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return 1;
|
ox_freea(newSize, cpy);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get sub directory and call its write instead of recursing on this directory
|
// TODO: get sub directory and call its write instead of recursing on this directory
|
||||||
@ -124,15 +158,18 @@ Error Directory<InodeId_t>::rm(PathIterator) noexcept {
|
|||||||
|
|
||||||
template<typename InodeId_t>
|
template<typename InodeId_t>
|
||||||
ValErr<InodeId_t> Directory<InodeId_t>::find(PathIterator it) const noexcept {
|
ValErr<InodeId_t> Directory<InodeId_t>::find(PathIterator it) const noexcept {
|
||||||
|
ValErr<InodeId_t> retval = {0, 1};
|
||||||
auto size = it.nextSize();
|
auto size = it.nextSize();
|
||||||
char name[size + 1];
|
auto name = reinterpret_cast<char*>(ox_alloca(size + 1));
|
||||||
it.next(name, size);
|
it.next(name, size);
|
||||||
for (auto i = m_buff->iterator(); i.hasNext(); i.next()) {
|
auto buff = m_fs->read(m_inodeId).template to<Buffer>();
|
||||||
if (i->name == name) {
|
for (auto i = buff->iterator(); i.hasNext(); i.next()) {
|
||||||
return static_cast<InodeId_t>(i->inode);
|
auto data = i->data();
|
||||||
|
if (data.valid() && data->name == name) {
|
||||||
|
retval = static_cast<InodeId_t>(data->inode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {0, 1};
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user