aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2024-05-15 07:48:27 +0000
committersotech117 <michael_foiani@brown.edu>2024-05-15 07:48:27 +0000
commite3e0b874c1ca34d16abafd96f804f4bdd63e245f (patch)
tree80193dc7b65c58ee725c91701fbed76b949394a1
parent466ae74b0809c795d8977ef872a97d27292b7973 (diff)
more s5 fixes rip
-rw-r--r--kernel/fs/s5fs/s5fs.c106
-rw-r--r--kernel/fs/s5fs/s5fs_subr.c189
2 files changed, 86 insertions, 209 deletions
diff --git a/kernel/fs/s5fs/s5fs.c b/kernel/fs/s5fs/s5fs.c
index dedadaf..9a907a3 100644
--- a/kernel/fs/s5fs/s5fs.c
+++ b/kernel/fs/s5fs/s5fs.c
@@ -657,97 +657,7 @@ static long s5fs_rename(vnode_t *olddir, const char *oldname, size_t oldnamelen,
size_t newnamelen)
{
// NOT_YET_IMPLEMENTED("S5FS: s5fs_rename");
-
- // Check if the new name is too long
- if (newnamelen >= NAME_LEN)
- {
- return -ENAMETOOLONG;
- }
-
- // Find the old directory entry
- s5_node_t *s5_node = VNODE_TO_S5NODE(olddir);
- size_t filepos;
- long ino = s5_find_dirent(s5_node, oldname, oldnamelen, &filepos);
- // Check if the directory entry was not found
- if (ino < 0)
- {
- return ino;
- }
-
- // Get the found vnode
- vnode_t *child = vget_locked(olddir->vn_fs, ino);
- KASSERT(!S_ISDIR(child->vn_mode) && "should be handled at the VFS level");
-
- // Check if the new directory is not a directory
- if (!S_ISDIR(newdir->vn_mode))
- {
- vput_locked(&child);
- return -ENOTDIR;
- }
-
- // Find the new directory entry
- s5_node_t *new_s5_node = VNODE_TO_S5NODE(newdir);
- size_t new_filepos;
- long new_ino = s5_find_dirent(new_s5_node, newname, newnamelen, &new_filepos);
- // Check if the directory entry is new
- if (new_ino == -ENOENT)
- {
- // Link the new directory
- long link = s5_link(new_s5_node, newname, newnamelen, VNODE_TO_S5NODE(child));
- // Check if the link operation failed
- if (link < 0)
- {
- vput_locked(&child);
- return link;
- }
-
- // Remove the old directory entry
- s5_remove_dirent(s5_node, oldname, oldnamelen, VNODE_TO_S5NODE(olddir));
- // Check if this failed (TODO: ask in hours)
-
- return link;
- }
-
- // Else, the new directory entry was found and we need to replace it
- // Get the new found vnode
- vnode_t *new_child = vget_locked(newdir->vn_fs, new_ino);
- KASSERT(!S_ISDIR(new_child->vn_mode) && "should be handled at the VFS level");
-
- // Check if the old and new vnodes are the same
- if (child->vn_vno == new_child->vn_vno)
- {
- vput_locked(&child);
- vput_locked(&new_child);
- return 0;
- }
-
- // Check if the new vnode is a directory
- if (S_ISDIR(new_child->vn_mode))
- {
- vput_locked(&child);
- vput_locked(&new_child);
- return -EISDIR;
- }
-
- // Remove the new directory entry
- s5_remove_dirent(new_s5_node, newname, newnamelen, new_filepos);
- // Check if this failed (TODO: ask in hours)
- // Link the new directory
- long link = s5_link(new_s5_node, newname, newnamelen, VNODE_TO_S5NODE(child));
- // Check if the link operation failed
- if (link < 0)
- {
- vput_locked(&child);
- vput_locked(&new_child);
- return link;
- }
-
- // Remove the old directory entry
- s5_remove_dirent(s5_node, oldname, oldnamelen, VNODE_TO_S5NODE(olddir));
-
- vput_locked(&child);
- vput_locked(&new_child);
- return link;
+ return -1;
}
/* Create a directory.
@@ -786,7 +696,7 @@ static long s5fs_mkdir(vnode_t *dir, const char *name, size_t namelen,
// Allocate the inode
s5_inode_t *s5_inode;
- long inode_num = s5_alloc_inode(s5fs, type, &s5_inode);
+ long inode_num = s5_alloc_inode(s5fs, type, 0);
// Check if the inode allocation failed
if (inode_num < 0)
{
@@ -809,8 +719,7 @@ static long s5fs_mkdir(vnode_t *dir, const char *name, size_t namelen,
// Check if the link operation failed
if (link < 0)
{
- vput(new_vnode);
- s5_free_inode(s5fs, inode_num);
+ vput(&new_vnode);
return link;
}
@@ -821,9 +730,7 @@ static long s5fs_mkdir(vnode_t *dir, const char *name, size_t namelen,
// Check if the link operation failed
if (link2 < 0)
{
- s5_remove_dirent(VNODE_TO_S5NODE(new_vnode), ".", 1, VNODE_TO_S5FS(dir));
- vput(new_vnode);
- s5_free_inode(s5fs, inode_num);
+ vput(&new_vnode);
return link2;
}
@@ -834,10 +741,7 @@ static long s5fs_mkdir(vnode_t *dir, const char *name, size_t namelen,
// Check if the link operation failed
if (link3 < 0)
{
- s5_remove_dirent(VNODE_TO_S5NODE(new_vnode), ".", 1, VNODE_TO_S5FS(dir));
- s5_remove_dirent(VNODE_TO_S5NODE(new_vnode), "..", 2, VNODE_TO_S5FS(dir));
- vput(new_vnode);
- s5_free_inode(s5fs, inode_num);
+ vput(&new_vnode);
return link3;
}
diff --git a/kernel/fs/s5fs/s5fs_subr.c b/kernel/fs/s5fs/s5fs_subr.c
index 55dd932..bd6b886 100644
--- a/kernel/fs/s5fs/s5fs_subr.c
+++ b/kernel/fs/s5fs/s5fs_subr.c
@@ -131,130 +131,103 @@ static inline void s5_release_file_block(pframe_t **pfp)
long s5_file_block_to_disk_block(s5_node_t *sn, size_t file_blocknum,
int alloc, int *newp)
{
- // NOT_YET_IMPLEMENTED("S5FS: s5_file_block_to_disk_block");
- *newp = 0; // assign any garbage values to 0
+ // NOT_YET_IMPLEMENTED("S5FS: s5_file_block_to_disk_block");
+ // return 0;
+ *newp=0;
- // Check if file_blocknum is greater than or equal to S5_MAX_FILE_BLOCKS
- if (file_blocknum >= S5_MAX_FILE_BLOCKS)
- {
- return -EINVAL;
- }
-
- // clearer renaming
- int is_indirect_block_allocated = sn->inode.s5_indirect_block;
+ s5fs_t *s5 = VNODE_TO_S5FS(&sn->vnode);
+ long block_num = 0;
+ pframe_t *pf;
// Case 1: file_blocknum < S5_NDIRECT_BLOCKS
- if (file_blocknum < S5_NDIRECT_BLOCKS)
- {
- size_t disk_blocknum = sn->inode.s5_direct_blocks[file_blocknum];
- // Check if disk_blocknum has been already. If so, ret it
- if (disk_blocknum)
+ if (file_blocknum < S5_NDIRECT_BLOCKS){
+ block_num = sn->inode.s5_direct_blocks[file_blocknum];
+ if (!block_num && alloc)
{
- return disk_blocknum;
- }
-
- // Check if alloc is clear. If so, ret 0
- if (!alloc)
- {
- return 0;
- }
-
- // Else, allocate the block
- long alloced_blocknum = s5_alloc_block(VNODE_TO_S5FS(&sn->vnode));
- // Propogate errors from s5_alloc_block
- if (alloced_blocknum < 0)
- {
- return alloced_blocknum;
+ long alloced_block_num = s5_alloc_block(s5);
+
+ if (alloced_block_num > 0)
+ {
+ sn->inode.s5_direct_blocks[file_blocknum] = (uint32_t)alloced_block_num;
+ sn->dirtied_inode = 1;
+ *newp = 1;
+ return alloced_block_num;
+ }
}
- // Update the inode
- sn->inode.s5_direct_blocks[file_blocknum] = alloced_blocknum;
- sn->dirtied_inode = 1;
-
- // set ret params and return
- *newp = 1;
- return alloced_blocknum;
}
-
- // Case 2: Indirect block is not allocated but alloc is set
- else if (!is_indirect_block_allocated && alloc)
+ else if (file_blocknum >= S5_NDIRECT_BLOCKS && file_blocknum < S5_MAX_FILE_BLOCKS)
{
- long disk_blocknum = s5_alloc_block(VNODE_TO_S5FS(&sn->vnode));
- // Propogate errors from s5_alloc_block
- if (disk_blocknum < 0)
- {
- return disk_blocknum;
- }
- // Update the inode
- sn->inode.s5_indirect_block = disk_blocknum;
- sn->dirtied_inode = 1;
-
- // Create a corresponding pframe_t on the mob
- s5fs_t *s5 = VNODE_TO_S5FS(&sn->vnode);
- mobj_lock(&s5->s5f_mobj);
- pframe_t *pf = s5_cache_and_clear_block(&sn->vnode.vn_mobj, disk_blocknum, 0);
- mobj_unlock(&s5->s5f_mobj);
- // memset(pf->pf_addr, 0, PAGE_SIZE);
- // pf->pf_dirty = 1; (already done in s5_cache_and_clear_block
-
- // Release now that we have the desired block number
- s5_release_disk_block(&pf);
-
- // set ret params and return
- *newp = 1;
- return disk_blocknum;
- }
-
- // Case 3: Indirect block is allocated
- else if (is_indirect_block_allocated)
- {
- size_t indirect_blocknum = sn->inode.s5_indirect_block;
-
- // Get the disk block number of the desired file block
- pframe_t *pf;
- s5_get_meta_disk_block(VNODE_TO_S5FS(&sn->vnode), indirect_blocknum, 0, &pf);
- uint32_t *indirect_block = pf->pf_addr;
-
- // Get the index of the indirect block
- size_t indirect_block_index = file_blocknum - S5_NDIRECT_BLOCKS;
- size_t disk_blocknum = indirect_block[indirect_block_index];
-
- // Release the indirect block, now that we have the desired block number
- s5_release_disk_block(&pf);
+ uint32_t indirect_block_num = sn->inode.s5_indirect_block;
+ mobj_t * mobjp = &s5->s5f_mobj;
+
+ // Case 2: Indirect block is not allocated but alloc is set
+ if (!indirect_block_num && alloc){
+ long retval = s5_alloc_block(s5);
+
+ if (retval < 0) return (long)retval;
+
+ mobj_lock(mobjp);
+ pframe_t *indir_pf = s5_cache_and_clear_block(mobjp, retval, retval);
+ mobj_unlock(mobjp);
+
+ block_num = s5_alloc_block(s5);
+
+
+ if (block_num <= 0)
+ {
+ s5_free_block(s5, sn->inode.s5_indirect_block);
+ mobj_delete_pframe(&s5->s5f_mobj, retval);
+ return (long) block_num;
+ }
+ else
+ {
+ sn->inode.s5_indirect_block = retval;
+ s5_get_meta_disk_block(s5, sn->inode.s5_indirect_block, 1, &pf);
+ memcpy(
+ (uint32_t*)pf->pf_addr + (file_blocknum - S5_NDIRECT_BLOCKS),
+ &block_num,
+ sizeof(uint32_t)
+ );
+
+ s5_release_disk_block(&pf);
+
+ sn->dirtied_inode = 1;
+ *newp = 1;
+ }
- // Check if disk_blocknum has been already. If so, ret it
- if (disk_blocknum)
- {
- return disk_blocknum;
+ s5_release_disk_block(&indir_pf);
}
- // Check if alloc is clear. If so, we're done.
- if (!alloc)
+ // Case 3: Indirect block is allocated
+ else if (indirect_block_num)
{
- return 0;
- }
+ s5_get_meta_disk_block(s5, indirect_block_num, 1, &pf);
+ file_blocknum = file_blocknum - S5_NDIRECT_BLOCKS;
+ memcpy(
+ &block_num,
+ (uint32_t*)(pf->pf_addr) + file_blocknum,
+ sizeof(uint32_t)
+ );
- // Else, allocate the block
- long alloced_blocknum = s5_alloc_block(VNODE_TO_S5FS(&sn->vnode));
- // Propogate errors from s5_alloc_block
- if (alloced_blocknum < 0)
- {
- return alloced_blocknum;
+ if (!block_num && alloc)
+ {
+ block_num = s5_alloc_block(s5);
+
+ if (block_num > 0)
+ {
+ memcpy((uint32_t*)(pf->pf_addr) + file_blocknum, &block_num , sizeof(uint32_t));
+ *newp = 1;
+ }
+ }
+ s5_release_disk_block(&pf);
}
- // Update the inode
- indirect_block[indirect_block_index] = alloced_blocknum;
- sn->dirtied_inode = 1;
-
- // set ret params and return
- *newp = 1;
- return alloced_blocknum;
}
-
- // Case 4: The indirect block has not been allocated and alloc is clear
- else
+ else
{
- // TODO: check if this is correct (update -> passes tests so ok)
- return 0;
+ return -EINVAL;
}
+
+ return block_num;
}
pframe_t *s5_cache_and_clear_block(mobj_t *mo, long block, long loc) {