[ox/fs] Fix various file system bugs
This commit is contained in:
41
deps/ox/src/ox/ptrarith/nodebuffer.hpp
vendored
41
deps/ox/src/ox/ptrarith/nodebuffer.hpp
vendored
@@ -117,6 +117,12 @@ class __attribute__((packed)) NodeBuffer {
|
||||
|
||||
[[nodiscard]] ItemPtr next(Item *item);
|
||||
|
||||
/**
|
||||
* Like pointer but omits checks that assume the memory at the offset has
|
||||
* already been initialed as an Item.
|
||||
*/
|
||||
[[nodiscard]] ItemPtr uninitializedPtr(size_t offset);
|
||||
|
||||
[[nodiscard]] ItemPtr ptr(size_t offset);
|
||||
|
||||
[[nodiscard]] ItemPtr ptr(void *item);
|
||||
@@ -147,7 +153,7 @@ class __attribute__((packed)) NodeBuffer {
|
||||
* @return the actual number a bytes need to store the given number of
|
||||
* bytes
|
||||
*/
|
||||
size_t spaceNeeded(size_t size);
|
||||
static size_t spaceNeeded(size_t size);
|
||||
|
||||
template<typename F>
|
||||
[[nodiscard]] ox::Error compact(F cb = [](uint64_t, ItemPtr) {});
|
||||
@@ -213,6 +219,23 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::next(Item *
|
||||
return ptr(item->next);
|
||||
}
|
||||
|
||||
template<typename size_t, typename Item>
|
||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::uninitializedPtr(size_t itemOffset) {
|
||||
// make sure this can be read as an Item, and then use Item::size for the size
|
||||
std::size_t itemSpace = m_header.size - itemOffset;
|
||||
if (itemOffset >= sizeof(Header) &&
|
||||
itemOffset + itemSpace <= size() &&
|
||||
itemSpace >= sizeof(Item)) {
|
||||
return ItemPtr(this, m_header.size, itemOffset, itemSpace);
|
||||
} else {
|
||||
//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemOffset:" << itemOffset;
|
||||
//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemOffset >= sizeof(Header):" << (itemOffset >= sizeof(Header));
|
||||
//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemSpace >= sizeof(Item):" << (itemSpace >= sizeof(Item));
|
||||
//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemSpace >= item->fullSize():" << (itemSpace >= item->fullSize());
|
||||
return ItemPtr(this, m_header.size, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename size_t, typename Item>
|
||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t itemOffset) {
|
||||
// make sure this can be read as an Item, and then use Item::size for the size
|
||||
@@ -320,11 +343,12 @@ Error NodeBuffer<size_t, Item>::free(ItemPtr item) {
|
||||
|
||||
template<typename size_t, typename Item>
|
||||
Error NodeBuffer<size_t, Item>::setSize(size_t size) {
|
||||
oxTrace("ox::ptrarith::NodeBuffer::setSize") << size;
|
||||
oxTrace("ox::ptrarith::NodeBuffer::setSize") << m_header.size << "to" << size;
|
||||
auto last = lastItem();
|
||||
auto end = last.valid() ? last.end() : sizeof(m_header);
|
||||
oxTrace("ox::ptrarith::NodeBuffer::setSize") << "end:" << end;
|
||||
if (end > size) {
|
||||
// resizing to less than buffer size
|
||||
return OxError(1);
|
||||
} else {
|
||||
m_header.size = size;
|
||||
@@ -357,9 +381,16 @@ template<typename F>
|
||||
ox::Error NodeBuffer<size_t, Item>::compact(F cb) {
|
||||
auto src = firstItem();
|
||||
auto dest = ptr(sizeof(*this));
|
||||
while (src.valid() && dest.valid() && dest.offset() <= src.offset()) {
|
||||
while (dest.offset() <= src.offset()) {
|
||||
if (!src.valid()) {
|
||||
return OxError(1);
|
||||
}
|
||||
if (!dest.valid()) {
|
||||
dest.valid();
|
||||
return OxError(2);
|
||||
}
|
||||
// move node
|
||||
ox_memcpy(dest, src, src.size());
|
||||
ox_memcpy(dest, src, src->fullSize());
|
||||
oxReturnError(cb(src, dest));
|
||||
// update surrounding nodes
|
||||
auto prev = ptr(dest->prev);
|
||||
@@ -372,7 +403,7 @@ ox::Error NodeBuffer<size_t, Item>::compact(F cb) {
|
||||
}
|
||||
// update iterators
|
||||
src = ptr(dest->next);
|
||||
dest = ptr(dest.offset() + dest.size());
|
||||
dest = uninitializedPtr(dest.offset() + dest->fullSize());
|
||||
}
|
||||
return OxError(0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user