[ox/fs] Fix inode generation check to check for outside the reserved range
This commit is contained in:
parent
00339ee4fd
commit
71af674eef
118
deps/ox/src/ox/fs/filestore/filestoretemplate.hpp
vendored
118
deps/ox/src/ox/fs/filestore/filestoretemplate.hpp
vendored
@ -50,8 +50,11 @@ class FileStoreTemplate: public FileStore {
|
|||||||
using ItemPtr = typename ptrarith::NodeBuffer<size_t, FileStoreItem<size_t>>::ItemPtr;
|
using ItemPtr = typename ptrarith::NodeBuffer<size_t, FileStoreItem<size_t>>::ItemPtr;
|
||||||
using Buffer = ptrarith::NodeBuffer<size_t, FileStoreItem<size_t>>;
|
using Buffer = ptrarith::NodeBuffer<size_t, FileStoreItem<size_t>>;
|
||||||
|
|
||||||
|
static constexpr InodeId_t ReservedInodeEnd = 100;
|
||||||
|
|
||||||
struct __attribute__((packed)) FileStoreData {
|
struct __attribute__((packed)) FileStoreData {
|
||||||
ox::LittleEndian<size_t> rootNode = 0;
|
ox::LittleEndian<size_t> rootNode = 0;
|
||||||
|
ox::Random random;
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t m_buffSize = 0;
|
size_t m_buffSize = 0;
|
||||||
@ -70,6 +73,8 @@ class FileStoreTemplate: public FileStore {
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
Error remove(InodeId_t id);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
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);
|
||||||
@ -91,7 +96,9 @@ class FileStoreTemplate: public FileStore {
|
|||||||
FsSize_t readSize, T *data,
|
FsSize_t readSize, T *data,
|
||||||
FsSize_t *size);
|
FsSize_t *size);
|
||||||
|
|
||||||
StatInfo stat(InodeId_t id);
|
ValErr<StatInfo> stat(InodeId_t id);
|
||||||
|
|
||||||
|
Error resize(std::size_t size, void *newBuff = nullptr);
|
||||||
|
|
||||||
InodeId_t spaceNeeded(FsSize_t size);
|
InodeId_t spaceNeeded(FsSize_t size);
|
||||||
|
|
||||||
@ -99,6 +106,8 @@ class FileStoreTemplate: public FileStore {
|
|||||||
|
|
||||||
InodeId_t available();
|
InodeId_t available();
|
||||||
|
|
||||||
|
ValErr<InodeId_t> generateInodeId();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void compact();
|
void compact();
|
||||||
|
|
||||||
@ -116,12 +125,20 @@ class FileStoreTemplate: public FileStore {
|
|||||||
*/
|
*/
|
||||||
Error placeItem(ItemPtr root, ItemPtr item, int depth = 0);
|
Error placeItem(ItemPtr root, ItemPtr item, int depth = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given Item at the given ID. If it already exists, the
|
||||||
|
* existing value will be overwritten.
|
||||||
|
*/
|
||||||
|
Error unplaceItem(ItemPtr item);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given Item at the given ID. If it already exists, the
|
* Removes the given Item at the given ID. If it already exists, the
|
||||||
* existing value will be overwritten.
|
* existing value will be overwritten.
|
||||||
*/
|
*/
|
||||||
Error unplaceItem(ItemPtr root, ItemPtr item, int depth = 0);
|
Error unplaceItem(ItemPtr root, ItemPtr item, int depth = 0);
|
||||||
|
|
||||||
|
Error remove(ItemPtr item);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the parent an inode by its ID.
|
* Finds the parent an inode by its ID.
|
||||||
*/
|
*/
|
||||||
@ -144,6 +161,8 @@ class FileStoreTemplate: public FileStore {
|
|||||||
|
|
||||||
bool canWrite(ItemPtr existing, size_t size);
|
bool canWrite(ItemPtr existing, size_t size);
|
||||||
|
|
||||||
|
bool valid() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
@ -195,6 +214,7 @@ Error FileStoreTemplate<size_t>::decLinks(InodeId_t id) {
|
|||||||
auto item = find(id);
|
auto item = find(id);
|
||||||
if (item.valid()) {
|
if (item.valid()) {
|
||||||
item->links--;
|
item->links--;
|
||||||
|
// TODO: remove item if links is 0
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
return OxError(1);
|
return OxError(1);
|
||||||
@ -204,7 +224,11 @@ template<typename size_t>
|
|||||||
Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, FsSize_t dataSize, uint8_t fileType) {
|
Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, FsSize_t dataSize, uint8_t fileType) {
|
||||||
oxTrace("ox::fs::FileStoreTemplate::write") << "Attempting to write to inode" << id;
|
oxTrace("ox::fs::FileStoreTemplate::write") << "Attempting to write to inode" << id;
|
||||||
auto existing = find(id);
|
auto existing = find(id);
|
||||||
// TODO: try compacting if unable to write
|
if (canWrite(existing, dataSize)) {
|
||||||
|
compact();
|
||||||
|
existing = find(id);
|
||||||
|
}
|
||||||
|
|
||||||
if (canWrite(existing, dataSize)) {
|
if (canWrite(existing, dataSize)) {
|
||||||
// delete the old node if it exists
|
// delete the old node if it exists
|
||||||
if (existing.valid()) {
|
if (existing.valid()) {
|
||||||
@ -255,6 +279,11 @@ Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, FsSize_t dataSi
|
|||||||
return OxError(1);
|
return OxError(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
Error FileStoreTemplate<size_t>::remove(InodeId_t id) {
|
||||||
|
return remove(find(id));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
Error FileStoreTemplate<size_t>::read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size) {
|
Error FileStoreTemplate<size_t>::read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size) {
|
||||||
oxTrace("ox::fs::FileStoreTemplate::read") << "Attempting to read from inode" << id;
|
oxTrace("ox::fs::FileStoreTemplate::read") << "Attempting to read from inode" << id;
|
||||||
@ -346,17 +375,22 @@ const ptrarith::Ptr<uint8_t, std::size_t> FileStoreTemplate<size_t>::read(InodeI
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
typename FileStoreTemplate<size_t>::StatInfo FileStoreTemplate<size_t>::stat(InodeId_t id) {
|
Error FileStoreTemplate<size_t>::resize(std::size_t size, void *newBuff) {
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
ValErr<typename FileStoreTemplate<size_t>::StatInfo> FileStoreTemplate<size_t>::stat(InodeId_t id) {
|
||||||
auto inode = find(id);
|
auto inode = find(id);
|
||||||
if (inode.valid()) {
|
if (inode.valid()) {
|
||||||
return {
|
return ValErr<StatInfo>({
|
||||||
.inodeId = id,
|
.inodeId = id,
|
||||||
.links = inode->links,
|
.links = inode->links,
|
||||||
.size = inode->size(),
|
.size = inode->size(),
|
||||||
.fileType = inode->fileType,
|
.fileType = inode->fileType,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
return {};
|
return ValErr<StatInfo>({}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
@ -374,6 +408,21 @@ InodeId_t FileStoreTemplate<size_t>::available() {
|
|||||||
return m_buffer->available();
|
return m_buffer->available();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
ValErr<InodeId_t> FileStoreTemplate<size_t>::generateInodeId() {
|
||||||
|
auto fsData = fileStoreData();
|
||||||
|
if (fsData) {
|
||||||
|
for (auto i = 0; i < 100; i++) {
|
||||||
|
auto inode = fsData->random.gen() % MaxValue<InodeId_t>;
|
||||||
|
if (inode > ReservedInodeEnd && !find(inode).valid()) {
|
||||||
|
return inode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {0, OxError(2)};
|
||||||
|
}
|
||||||
|
return {0, OxError(1)};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
void FileStoreTemplate<size_t>::compact() {
|
void FileStoreTemplate<size_t>::compact() {
|
||||||
}
|
}
|
||||||
@ -449,6 +498,42 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr item) {
|
||||||
|
auto fsData = fileStoreData();
|
||||||
|
if (fsData) {
|
||||||
|
auto root = m_buffer->ptr(fsData->rootNode);
|
||||||
|
if (root.valid()) {
|
||||||
|
if (root->id == item->id) {
|
||||||
|
item->left = root->left;
|
||||||
|
item->right = root->right;
|
||||||
|
auto left = m_buffer->ptr(item->left);
|
||||||
|
auto right = m_buffer->ptr(item->right);
|
||||||
|
if (right.valid()) {
|
||||||
|
auto oldRoot = fsData->rootNode;
|
||||||
|
fsData->rootNode = item->right;
|
||||||
|
if (left.valid()) {
|
||||||
|
auto err = placeItem(left);
|
||||||
|
// undo if unable to place the left side of the tree
|
||||||
|
if (err) {
|
||||||
|
fsData->rootNode = oldRoot;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (left.valid()) {
|
||||||
|
fsData->rootNode = item->left;
|
||||||
|
} else {
|
||||||
|
fsData->rootNode = 0;
|
||||||
|
}
|
||||||
|
return OxError(0);
|
||||||
|
} else {
|
||||||
|
return unplaceItem(root, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OxError(1);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr root, ItemPtr item, int depth) {
|
Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr root, ItemPtr item, int depth) {
|
||||||
if (depth < 5000) {
|
if (depth < 5000) {
|
||||||
@ -470,11 +555,20 @@ Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr root, ItemPtr item, int dep
|
|||||||
} else {
|
} else {
|
||||||
return unplaceItem(left, item, depth + 1);
|
return unplaceItem(left, item, depth + 1);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
oxTrace("ox::fs::FileStoreTemplate::unplaceItem::fail") << "Item already exists.";
|
|
||||||
}
|
}
|
||||||
|
return OxError(1);
|
||||||
} else {
|
} else {
|
||||||
oxTrace("ox::fs::FileStoreTemplate::unplaceItem::fail") << "Excessive recursion depth, stopping before stack overflow.";
|
oxTrace("ox::fs::FileStoreTemplate::unplaceItem::fail") << "Excessive recursion depth, stopping before stack overflow.";
|
||||||
|
return OxError(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
Error FileStoreTemplate<size_t>::remove(ItemPtr item) {
|
||||||
|
if (item.valid()) {
|
||||||
|
oxReturnError(unplaceItem(item));
|
||||||
|
oxReturnError(m_buffer->free(item));
|
||||||
|
return OxError(0);
|
||||||
}
|
}
|
||||||
return OxError(1);
|
return OxError(1);
|
||||||
}
|
}
|
||||||
@ -508,10 +602,13 @@ typename FileStoreTemplate<size_t>::ItemPtr FileStoreTemplate<size_t>::find(Item
|
|||||||
if (depth < 5000) {
|
if (depth < 5000) {
|
||||||
if (item.valid()) {
|
if (item.valid()) {
|
||||||
if (id > item->id) {
|
if (id > item->id) {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::find") << "Not a match, searching on" << item->right;
|
||||||
return find(m_buffer->ptr(item->right), id, depth + 1);
|
return find(m_buffer->ptr(item->right), id, depth + 1);
|
||||||
} else if (id < item->id) {
|
} else if (id < item->id) {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::find") << "Not a match, searching on" << item->left;
|
||||||
return find(m_buffer->ptr(item->left), id, depth + 1);
|
return find(m_buffer->ptr(item->left), id, depth + 1);
|
||||||
} else if (id == item->id) {
|
} else if (id == item->id) {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::find") << "Found" << id << "at" << item;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -558,6 +655,11 @@ bool FileStoreTemplate<size_t>::canWrite(ItemPtr existing, size_t size) {
|
|||||||
return existing.size() >= size || m_buffer->spaceNeeded(size) <= m_buffer->available();
|
return existing.size() >= size || m_buffer->spaceNeeded(size) <= m_buffer->available();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
bool FileStoreTemplate<size_t>::valid() const {
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
extern template class FileStoreTemplate<uint16_t>;
|
extern template class FileStoreTemplate<uint16_t>;
|
||||||
extern template class FileStoreTemplate<uint32_t>;
|
extern template class FileStoreTemplate<uint32_t>;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user