Add ability to delete inodes
This commit is contained in:
+82
-8
@@ -52,12 +52,6 @@ class FileStore {
|
|||||||
FsSize_t m_rootInode;
|
FsSize_t m_rootInode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Initializes the memory chunk of this FileStore was given.
|
|
||||||
* This clears the previous contents.
|
|
||||||
*/
|
|
||||||
void init();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the given data to a "file" with the given id.
|
* Writes the given data to a "file" with the given id.
|
||||||
* @param id the id of the file
|
* @param id the id of the file
|
||||||
@@ -74,6 +68,12 @@ class FileStore {
|
|||||||
*/
|
*/
|
||||||
int write(InodeId_t id, void *data, FsSize_t dataLen);
|
int write(InodeId_t id, void *data, FsSize_t dataLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the inode of the given ID.
|
||||||
|
* @param id the id of the file
|
||||||
|
*/
|
||||||
|
int remove(InodeId_t id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the "file" at the given id. You are responsible for freeing
|
* Reads the "file" at the given id. You are responsible for freeing
|
||||||
* the data when done with it.
|
* the data when done with it.
|
||||||
@@ -106,6 +106,18 @@ class FileStore {
|
|||||||
*/
|
*/
|
||||||
Inode *getInode(Inode *root, InodeId_t id);
|
Inode *getInode(Inode *root, InodeId_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the inode of the given ID.
|
||||||
|
* @param id the id of the file
|
||||||
|
*/
|
||||||
|
int remove(Inode *root, InodeId_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given node from the linked list.
|
||||||
|
* @param node node to remove
|
||||||
|
*/
|
||||||
|
void unlink(Inode *node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an address for a new Inode.
|
* Gets an address for a new Inode.
|
||||||
* @param size the size of the Inode
|
* @param size the size of the Inode
|
||||||
@@ -191,7 +203,6 @@ template<typename FsSize_t>
|
|||||||
int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen) {
|
int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen) {
|
||||||
auto retval = 1;
|
auto retval = 1;
|
||||||
const FsSize_t size = sizeof(Inode) + dataLen;
|
const FsSize_t size = sizeof(Inode) + dataLen;
|
||||||
//printf("%d\n", m_rootInode);
|
|
||||||
auto inode = (Inode*) alloc(size);
|
auto inode = (Inode*) alloc(size);
|
||||||
if (inode) {
|
if (inode) {
|
||||||
auto root = ptr<Inode*>(m_rootInode);
|
auto root = ptr<Inode*>(m_rootInode);
|
||||||
@@ -204,6 +215,69 @@ int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen) {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
int FileStore<FsSize_t>::remove(InodeId_t id) {
|
||||||
|
return remove(ptr<Inode*>(m_rootInode), id);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
int FileStore<FsSize_t>::remove(Inode *root, InodeId_t id) {
|
||||||
|
auto err = 1;
|
||||||
|
|
||||||
|
if (root->m_id > id) {
|
||||||
|
if (root->left) {
|
||||||
|
auto node = ptr<Inode*>(root->left);
|
||||||
|
if (node->m_id != id) {
|
||||||
|
err = remove(node, id);
|
||||||
|
} else {
|
||||||
|
root->left = node->left;
|
||||||
|
if (node->right) {
|
||||||
|
insert(root, ptr<Inode*>(node->right));
|
||||||
|
}
|
||||||
|
if (node->left) {
|
||||||
|
insert(root, ptr<Inode*>(node->left));
|
||||||
|
}
|
||||||
|
unlink(node);
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (root->m_id < id) {
|
||||||
|
if (root->right) {
|
||||||
|
auto node = ptr<Inode*>(root->right);
|
||||||
|
if (node->m_id != id) {
|
||||||
|
err = remove(node, id);
|
||||||
|
} else {
|
||||||
|
root->right = node->right;
|
||||||
|
if (node->right) {
|
||||||
|
insert(root, ptr<Inode*>(node->right));
|
||||||
|
}
|
||||||
|
if (node->left) {
|
||||||
|
insert(root, ptr<Inode*>(node->left));
|
||||||
|
}
|
||||||
|
unlink(node);
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_rootInode = root->right;
|
||||||
|
if (root->left) {
|
||||||
|
insert(ptr<Inode*>(m_rootInode), ptr<Inode*>(root->left));
|
||||||
|
}
|
||||||
|
unlink(root);
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
int FileStore<FsSize_t>::read(InodeId_t id, void *data, FsSize_t *size) {
|
int FileStore<FsSize_t>::read(InodeId_t id, void *data, FsSize_t *size) {
|
||||||
auto inode = getInode(ptr<Inode*>(m_rootInode), id);
|
auto inode = getInode(ptr<Inode*>(m_rootInode), id);
|
||||||
@@ -328,7 +402,7 @@ typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::lastInode() {
|
|||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
uint8_t FileStore<FsSize_t>::version() {
|
uint8_t FileStore<FsSize_t>::version() {
|
||||||
return 0;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
|
|||||||
@@ -29,13 +29,29 @@ int test() {
|
|||||||
if (fs->write(2, (void*) "World", 6) ||
|
if (fs->write(2, (void*) "World", 6) ||
|
||||||
fs->read(2, (char*) out, &outSize) ||
|
fs->read(2, (char*) out, &outSize) ||
|
||||||
strcmp("World", out)) {
|
strcmp("World", out)) {
|
||||||
return 1;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure first value was not overwritten
|
// make sure first value was not overwritten
|
||||||
if (fs->read(1, (char*) out, &outSize) ||
|
if (fs->read(1, (char*) out, &outSize) ||
|
||||||
strcmp("Hello", out)) {
|
strcmp("Hello", out)) {
|
||||||
return 1;
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs->remove(1)) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure inode is not found
|
||||||
|
if (fs->read(1, (char*) out, &outSize) == 0) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure 2 is still available
|
||||||
|
if (fs->write(2, (void*) "World", 6) ||
|
||||||
|
fs->read(2, (char*) out, &outSize) ||
|
||||||
|
strcmp("World", out)) {
|
||||||
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user