|
|
|
@@ -22,17 +22,17 @@ class FileStore {
|
|
|
|
|
struct StatInfo {
|
|
|
|
|
InodeId_t inodeId;
|
|
|
|
|
FsSize_t size;
|
|
|
|
|
ox::std::uint8_t fileType;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
struct Inode {
|
|
|
|
|
// the next Inode in memory
|
|
|
|
|
FsSize_t prev, next;
|
|
|
|
|
|
|
|
|
|
// The following variables should not be assumed to exist
|
|
|
|
|
FsSize_t dataLen;
|
|
|
|
|
InodeId_t m_id;
|
|
|
|
|
ox::std::uint8_t refs;
|
|
|
|
|
ox::std::uint8_t fileType;
|
|
|
|
|
FsSize_t left, right;
|
|
|
|
|
|
|
|
|
|
FsSize_t size();
|
|
|
|
@@ -46,6 +46,7 @@ class FileStore {
|
|
|
|
|
|
|
|
|
|
ox::std::uint32_t m_fsType;
|
|
|
|
|
FsSize_t m_size;
|
|
|
|
|
FsSize_t m_firstInode;
|
|
|
|
|
FsSize_t m_rootInode;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
@@ -55,7 +56,7 @@ class FileStore {
|
|
|
|
|
* @param data the contents of the file
|
|
|
|
|
* @param dataLen the number of bytes data points to
|
|
|
|
|
*/
|
|
|
|
|
int write(void *data, FsSize_t dataLen, ox::std::uint8_t fileType = 0);
|
|
|
|
|
int write(void *data, FsSize_t dataLen);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Writes the given data to a "file" with the given id.
|
|
|
|
@@ -63,7 +64,7 @@ class FileStore {
|
|
|
|
|
* @param data the contents of the file
|
|
|
|
|
* @param dataLen the number of bytes data points to
|
|
|
|
|
*/
|
|
|
|
|
int write(InodeId_t id, void *data, FsSize_t dataLen, ox::std::uint8_t fileType = 0);
|
|
|
|
|
int write(InodeId_t id, void *data, FsSize_t dataLen);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removes the inode of the given ID.
|
|
|
|
@@ -103,15 +104,6 @@ class FileStore {
|
|
|
|
|
*/
|
|
|
|
|
Inode *getInode(Inode *root, InodeId_t id);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the inode at the given id.
|
|
|
|
|
* @param root the root node to start comparing on
|
|
|
|
|
* @param id id of the "file"
|
|
|
|
|
* @param pathLen number of characters in pathLen
|
|
|
|
|
* @return the requested Inode, if available
|
|
|
|
|
*/
|
|
|
|
|
Inode *getInodeParent(Inode *root, InodeId_t id);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removes the inode of the given ID.
|
|
|
|
|
* @param id the id of the file
|
|
|
|
@@ -124,12 +116,6 @@ class FileStore {
|
|
|
|
|
*/
|
|
|
|
|
void unlink(Inode *node);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the address of the next available inode, assuming there is a next
|
|
|
|
|
* available inode.
|
|
|
|
|
*/
|
|
|
|
|
FsSize_t nextInodeAddr();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets an address for a new Inode.
|
|
|
|
|
* @param size the size of the Inode
|
|
|
|
@@ -137,9 +123,9 @@ class FileStore {
|
|
|
|
|
void *alloc(FsSize_t size);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Compresses all of the inode into a contiguous space, starting at the first inode.
|
|
|
|
|
* Compresses all of the inode into a contiguous space, starting at m_firstInode.
|
|
|
|
|
*/
|
|
|
|
|
void compress(FsSize_t firstInode);
|
|
|
|
|
void compress();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Inserts the given insertValue into the tree of the given root.
|
|
|
|
@@ -154,15 +140,10 @@ class FileStore {
|
|
|
|
|
*/
|
|
|
|
|
FsSize_t iterator();
|
|
|
|
|
|
|
|
|
|
FsSize_t firstInode();
|
|
|
|
|
Inode *firstInode();
|
|
|
|
|
|
|
|
|
|
Inode *lastInode();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Updates the address of the inode in the tree.
|
|
|
|
|
*/
|
|
|
|
|
void updateInodeAddress(InodeId_t id, FsSize_t addr);
|
|
|
|
|
|
|
|
|
|
ox::std::uint8_t *begin() {
|
|
|
|
|
return (ox::std::uint8_t*) this;
|
|
|
|
|
}
|
|
|
|
@@ -212,21 +193,19 @@ void *FileStore<FsSize_t>::Inode::data() {
|
|
|
|
|
// FileStore
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
int FileStore<FsSize_t>::write(void *data, FsSize_t dataLen, ox::std::uint8_t fileType) {
|
|
|
|
|
int FileStore<FsSize_t>::write(void *data, FsSize_t dataLen) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen, ox::std::uint8_t fileType) {
|
|
|
|
|
int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen) {
|
|
|
|
|
auto retval = 1;
|
|
|
|
|
const FsSize_t size = sizeof(Inode) + dataLen;
|
|
|
|
|
auto inode = (Inode*) alloc(size);
|
|
|
|
|
if (inode) {
|
|
|
|
|
remove(id);
|
|
|
|
|
inode->m_id = id;
|
|
|
|
|
inode->fileType = fileType;
|
|
|
|
|
inode->setData(data, dataLen);
|
|
|
|
|
auto root = ptr<Inode*>(m_rootInode);
|
|
|
|
|
inode->m_id = id;
|
|
|
|
|
inode->setData(data, dataLen);
|
|
|
|
|
if (insert(root, inode) || root == inode) {
|
|
|
|
|
retval = 0;
|
|
|
|
|
}
|
|
|
|
@@ -249,7 +228,7 @@ int FileStore<FsSize_t>::remove(Inode *root, InodeId_t id) {
|
|
|
|
|
if (node->m_id != id) {
|
|
|
|
|
err = remove(node, id);
|
|
|
|
|
} else {
|
|
|
|
|
root->left = 0;
|
|
|
|
|
root->left = node->left;
|
|
|
|
|
if (node->right) {
|
|
|
|
|
insert(root, ptr<Inode*>(node->right));
|
|
|
|
|
}
|
|
|
|
@@ -257,9 +236,6 @@ int FileStore<FsSize_t>::remove(Inode *root, InodeId_t id) {
|
|
|
|
|
insert(root, ptr<Inode*>(node->left));
|
|
|
|
|
}
|
|
|
|
|
unlink(node);
|
|
|
|
|
node->m_id = 0;
|
|
|
|
|
node->left = 0;
|
|
|
|
|
node->right = 0;
|
|
|
|
|
err = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -269,7 +245,7 @@ int FileStore<FsSize_t>::remove(Inode *root, InodeId_t id) {
|
|
|
|
|
if (node->m_id != id) {
|
|
|
|
|
err = remove(node, id);
|
|
|
|
|
} else {
|
|
|
|
|
root->right = 0;
|
|
|
|
|
root->right = node->right;
|
|
|
|
|
if (node->right) {
|
|
|
|
|
insert(root, ptr<Inode*>(node->right));
|
|
|
|
|
}
|
|
|
|
@@ -277,21 +253,15 @@ int FileStore<FsSize_t>::remove(Inode *root, InodeId_t id) {
|
|
|
|
|
insert(root, ptr<Inode*>(node->left));
|
|
|
|
|
}
|
|
|
|
|
unlink(node);
|
|
|
|
|
node->m_id = 0;
|
|
|
|
|
node->left = 0;
|
|
|
|
|
node->right = 0;
|
|
|
|
|
err = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (ptr<Inode*>(m_rootInode)->m_id == id) {
|
|
|
|
|
} else {
|
|
|
|
|
m_rootInode = root->right;
|
|
|
|
|
if (root->left) {
|
|
|
|
|
insert(ptr<Inode*>(m_rootInode), ptr<Inode*>(root->left));
|
|
|
|
|
}
|
|
|
|
|
unlink(root);
|
|
|
|
|
root->m_id = 0;
|
|
|
|
|
root->left = 0;
|
|
|
|
|
root->right = 0;
|
|
|
|
|
err = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -299,27 +269,11 @@ int FileStore<FsSize_t>::remove(Inode *root, InodeId_t id) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
void FileStore<FsSize_t>::unlink(Inode *inode) {
|
|
|
|
|
auto next = ptr<Inode*>(inode->next);
|
|
|
|
|
auto prev = ptr<Inode*>(inode->prev);
|
|
|
|
|
void FileStore<FsSize_t>::unlink(Inode *node) {
|
|
|
|
|
auto next = ptr<Inode*>(node->next);
|
|
|
|
|
auto prev = ptr<Inode*>(node->prev);
|
|
|
|
|
prev->next = ptr(next);
|
|
|
|
|
next->prev = ptr(prev);
|
|
|
|
|
|
|
|
|
|
ox::std::memset(inode, 0, inode->size());
|
|
|
|
|
inode->prev = firstInode();
|
|
|
|
|
inode->next = firstInode();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
void FileStore<FsSize_t>::updateInodeAddress(InodeId_t id, FsSize_t addr) {
|
|
|
|
|
auto parent = getInodeParent(ptr<Inode*>(m_rootInode), id);
|
|
|
|
|
if (parent) {
|
|
|
|
|
if (parent->left && ptr<Inode*>(parent->left)->m_id == id) {
|
|
|
|
|
parent->left = addr;
|
|
|
|
|
} else if (parent->right && ptr<Inode*>(parent->right)->m_id == id) {
|
|
|
|
|
parent->right = addr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
@@ -368,79 +322,36 @@ typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::getInode(Inode *root,
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::getInodeParent(Inode *root, InodeId_t id) {
|
|
|
|
|
Inode *retval = nullptr;
|
|
|
|
|
|
|
|
|
|
if (root->m_id > id) {
|
|
|
|
|
if (root->left) {
|
|
|
|
|
if (ptr<Inode*>(root->left)->m_id == id) {
|
|
|
|
|
retval = root;
|
|
|
|
|
} else {
|
|
|
|
|
retval = getInode(ptr<Inode*>(root->left), id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (root->m_id < id) {
|
|
|
|
|
if (root->right) {
|
|
|
|
|
if (ptr<Inode*>(root->right)->m_id == id) {
|
|
|
|
|
retval = root;
|
|
|
|
|
} else {
|
|
|
|
|
retval = getInode(ptr<Inode*>(root->right), id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
FsSize_t FileStore<FsSize_t>::nextInodeAddr() {
|
|
|
|
|
FsSize_t next = ptr(lastInode()) + lastInode()->size();
|
|
|
|
|
return next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
void *FileStore<FsSize_t>::alloc(FsSize_t size) {
|
|
|
|
|
FsSize_t next = nextInodeAddr();
|
|
|
|
|
if ((next + size) > (ox::std::uint64_t) end()) {
|
|
|
|
|
compress(firstInode());
|
|
|
|
|
next = nextInodeAddr();
|
|
|
|
|
if ((next + size) > (ox::std::uint64_t) end()) {
|
|
|
|
|
if ((lastInode()->next + size) > (ox::std::uint64_t) end()) {
|
|
|
|
|
compress();
|
|
|
|
|
if ((lastInode()->next + size) > (ox::std::uint64_t) end()) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto retval = next;
|
|
|
|
|
const auto retval = lastInode()->next;
|
|
|
|
|
const auto inode = ptr<Inode*>(retval);
|
|
|
|
|
ox::std::memset(inode, 0, size);
|
|
|
|
|
inode->prev = ptr<Inode*>(firstInode())->prev;
|
|
|
|
|
inode->next = retval + size;
|
|
|
|
|
ptr<Inode*>(firstInode())->prev = retval;
|
|
|
|
|
ptr<Inode*>(m_firstInode)->prev = retval;
|
|
|
|
|
return inode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
void FileStore<FsSize_t>::compress(FsSize_t start) {
|
|
|
|
|
auto dest = ptr<Inode*>(firstInode());
|
|
|
|
|
auto current = ptr<Inode*>(start);
|
|
|
|
|
while (current->next > ptr(begin()) && current->next < ptr(end())) {
|
|
|
|
|
ox::std::memcpy(dest, current, current->size());
|
|
|
|
|
if (dest->next != firstInode()) {
|
|
|
|
|
dest->next = ptr(dest) + dest->size();
|
|
|
|
|
void FileStore<FsSize_t>::compress() {
|
|
|
|
|
auto current = ptr<Inode*>(m_firstInode);
|
|
|
|
|
while (current->next) {
|
|
|
|
|
auto prevEnd = current + current->size();
|
|
|
|
|
auto prev = ptr(current);
|
|
|
|
|
current->next = ptr(current) + current->size();
|
|
|
|
|
current = ptr<Inode*>(current->next);
|
|
|
|
|
current->prev = prev;
|
|
|
|
|
if (prevEnd != current) {
|
|
|
|
|
ox::std::memcpy(prevEnd, current, current->size());
|
|
|
|
|
current = prevEnd;
|
|
|
|
|
}
|
|
|
|
|
ptr<Inode*>(dest->next)->prev = ptr(dest);
|
|
|
|
|
current = ptr<Inode*>(dest->next);
|
|
|
|
|
dest = ptr<Inode*>(ptr(dest) + dest->size());
|
|
|
|
|
updateInodeAddress(dest->m_id, ptr(dest));
|
|
|
|
|
//auto prevEnd = current + current->size();
|
|
|
|
|
//auto prev = ptr(current);
|
|
|
|
|
//current->next = ptr(current) + current->size();
|
|
|
|
|
//current = ptr<Inode*>(current->next);
|
|
|
|
|
//current->prev = prev;
|
|
|
|
|
//if (prevEnd != current) {
|
|
|
|
|
// ox::std::memcpy(prevEnd, current, current->size());
|
|
|
|
|
// current = prevEnd;
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -462,9 +373,6 @@ bool FileStore<FsSize_t>::insert(Inode *root, Inode *insertValue) {
|
|
|
|
|
root->right = ptr(insertValue);
|
|
|
|
|
retval = true;
|
|
|
|
|
}
|
|
|
|
|
} else if (m_rootInode == 0) {
|
|
|
|
|
m_rootInode = ptr(insertValue);
|
|
|
|
|
retval = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
@@ -481,13 +389,13 @@ FsSize_t FileStore<FsSize_t>::ptr(void *ptr) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
FsSize_t FileStore<FsSize_t>::firstInode() {
|
|
|
|
|
return sizeof(FileStore<FsSize_t>);
|
|
|
|
|
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::firstInode() {
|
|
|
|
|
return ptr<Inode*>(sizeof(FileStore<FsSize_t>));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
|
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::lastInode() {
|
|
|
|
|
return ptr<Inode*>(ptr<Inode*>(firstInode())->prev);
|
|
|
|
|
return ptr<Inode*>(ptr<Inode*>(m_firstInode)->prev);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FsSize_t>
|
|
|
|
@@ -503,7 +411,8 @@ ox::std::uint8_t *FileStore<FsSize_t>::format(ox::std::uint8_t *buffer, FsSize_t
|
|
|
|
|
fs->m_fsType = fsType;
|
|
|
|
|
fs->m_size = size;
|
|
|
|
|
fs->m_rootInode = sizeof(FileStore<FsSize_t>);
|
|
|
|
|
((Inode*) (fs + 1))->prev = fs->firstInode();
|
|
|
|
|
fs->m_firstInode = sizeof(FileStore<FsSize_t>);
|
|
|
|
|
fs->firstInode()->prev = fs->m_firstInode;
|
|
|
|
|
fs->lastInode()->next = sizeof(FileStore<FsSize_t>);
|
|
|
|
|
|
|
|
|
|
return (ox::std::uint8_t*) buffer;
|
|
|
|
|