aboutsummaryrefslogtreecommitdiff
path: root/kernel/fs/s5fs/s5fs_subr.c
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 /kernel/fs/s5fs/s5fs_subr.c
parent466ae74b0809c795d8977ef872a97d27292b7973 (diff)
more s5 fixes rip
Diffstat (limited to 'kernel/fs/s5fs/s5fs_subr.c')
-rw-r--r--kernel/fs/s5fs/s5fs_subr.c189
1 files changed, 81 insertions, 108 deletions
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) {