From e3e0b874c1ca34d16abafd96f804f4bdd63e245f Mon Sep 17 00:00:00 2001 From: sotech117 Date: Wed, 15 May 2024 07:48:27 +0000 Subject: more s5 fixes rip --- kernel/fs/s5fs/s5fs_subr.c | 189 +++++++++++++++++++-------------------------- 1 file changed, 81 insertions(+), 108 deletions(-) (limited to 'kernel/fs/s5fs/s5fs_subr.c') 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) { -- cgit v1.2.3-70-g09d2