diff options
author | sotech117 <michael_foiani@brown.edu> | 2024-05-15 07:48:27 +0000 |
---|---|---|
committer | sotech117 <michael_foiani@brown.edu> | 2024-05-15 07:48:27 +0000 |
commit | e3e0b874c1ca34d16abafd96f804f4bdd63e245f (patch) | |
tree | 80193dc7b65c58ee725c91701fbed76b949394a1 | |
parent | 466ae74b0809c795d8977ef872a97d27292b7973 (diff) |
more s5 fixes rip
-rw-r--r-- | kernel/fs/s5fs/s5fs.c | 106 | ||||
-rw-r--r-- | kernel/fs/s5fs/s5fs_subr.c | 189 |
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) { |