int fs_rename(char* a, char* b) { unsigned int a_inode_index = FS_MAXFILEBLOCKS; unsigned int b_inode_index = FS_MAXFILEBLOCKS; unsigned int a_dir_index = FS_DIRENTRIES; fs_direntry dir_block[FS_DIRENTRIES]; fs_direntry dir_a[FS_DIRENTRIES]; fs_direntry dir_b[FS_DIRENTRIES]; for ( int i = 0; i < dir_inode.size / FS_BLOCKSIZE; i++ ) { disk_readblock(dir_inode.blocks[i], dir_block); for ( int j = 0; j < FS_DIRENTRIES; j++ ) { if ( dir_block[j].inode_block != 0 ) { if ( strcmp(dir_block[j].name, a) ) { a_inode_index = i; a_dir_index = j; memcpy(dir_a, dir_block, FS_BLOCKSIZE); strcpy(dir_a[j].name, b); } if ( strcmp(dir_block[j].name, b) ) { b_inode_index = i; memcpy(dir_b, dir_block, FS_BLOCKSIZE); mark_all_file_blocks_free(dir_b[j].inode_block); dir_b[j].inode_block = 0; } } } if ( a_inode_index != FS_MAXFILEBLOCKS && b_inode_index != FS_MAXFILEBLOCKS && a_inode_index == b_inode_index ) { strcpy(dir_b[a_dir_index].name, b); disk_writeblock(dir_inode.blocks[b_inode_index], dir_b); return 0; } } if ( a_inode_index == FS_MAXFILEBLOCKS ) { return -1; } if ( b_inode_index == FS_MAXFILEBLOCKS ) { disk_writeblock(dir_inode.blocks[a_inode_index], dir_a); return 0; } unsigned int old_a_dir_block = dir_inode.blocks[a_inode_index]; unsigned int old_b_dir_block = dir_inode.blocks[b_inode_index]; unsigned int new_a_dir_block = get_free_block(); unsigned int new_b_dir_block = get_free_block(); dir_inode.blocks[a_inode_index] = new_a_dir_block; dir_inode.blocks[b_inode_index] = new_b_dir_block; disk_writeblock(new_a_dir_block, dir_a); disk_writeblock(new_b_dir_block, dir_b); disk_writeblock(dir_inode, 0); mark_block_free(old_a_dir_block); mark_block_free(old_b_dir_block); return 0; }
void serve(void) { uint32_t req, whom; int perm, r=0; // I have initialized it..... void *pg; void *blockva; while (1) { perm = 0; req = ipc_recv((int32_t *) &whom, fsreq, &perm); if (debug) cprintf("fs req %d from %08x [page %08x: %s]\n", req, whom, vpt[VPN(fsreq)], fsreq); // if the request is to swap out the page, then get the blockva, swap out the block and unmap the page. if(req == SWAP_OUT_PAGE) { blockva = (void *)fsreq->swap.blockva; flush_block(blockva); r = sys_page_unmap(0,blockva); } // get the page mapped from the disk. if(req == SWAP_IN_PAGE) { blockva = (void *)fsreq->swap.blockva; // call this function to map the page from disk. r = map_page_from_disk(blockva); } // get the page unmapped and mark block free, as it has been swapped in by swap in env. if(req == SWAP_IN_SUCCESS) { blockva = (void *)fsreq->swap.blockva; r = mark_block_free(blockva); if(r >= 0) r = sys_page_unmap(0,blockva); } if(req == SWAP_IN_ERROR) { blockva = (void *)fsreq->swap.blockva; r = sys_page_unmap(0,blockva); } // All requests must contain an argument page if (!(perm & PTE_P)) { // Added for project.....To retrieve the free block and pass it to the swap out env. if(req == SWAP_OUT_REQUEST_BLOCK) { if((blockva = get_free_swap_block())!=NULL) r = (uint32_t)blockva; else r = -E_INVAL; } else { cprintf("Invalid request from %08x: no argument page\n", whom); continue; // just leave it hanging... } } pg = NULL; if (req == FSREQ_OPEN) { r = serve_open(whom, (struct Fsreq_open*)fsreq, &pg, &perm); } else if (req < NHANDLERS && handlers[req]) { r = handlers[req](whom, fsreq); } // added for project else if ( req == SWAP_OUT_REQUEST_BLOCK || req == SWAP_OUT_PAGE || req == SWAP_IN_PAGE || req == SWAP_IN_ERROR || req == SWAP_IN_SUCCESS ) { //do nothing, just to prevent it from going in the else block } else { cprintf("Invalid request code %d from %08x\n", whom, req); r = -E_INVAL; } ipc_send(whom, r, pg, perm); sys_page_unmap(0, fsreq); } }
BD_t * mem_bd(uint32_t blocks, uint16_t blocksize) { struct mem_info * info = malloc(sizeof(*info)); BD_t * bd; struct JOSFS_File * f; struct JOSFS_Super * s; int i; if(blocks < 1) return NULL; if(!info) return NULL; bd = &info->my_bd; bd->numblocks = blocks; bd->blocksize = blocksize; bd->atomicsize = blocksize; /* When running in the Linux kernel, we can't allocate this much * memory with kmalloc(). So, we use vmalloc() instead. */ info->blocks = vmalloc(blocks * blocksize); if(!info->blocks) { free(info); return NULL; } if(blockman_init(&info->blockman) < 0) { free(info->blocks); free(info); return NULL; } memset(info->blocks, 0, blocks * blocksize); // Set up JOS fs on the mem device... such a hack s = (struct JOSFS_Super *) &info->blocks[blocksize]; s->s_magic = JOSFS_FS_MAGIC; s->s_nblocks = blocks; f = &s->s_root; strcpy(f->f_name, "/"); f->f_size = 0; f->f_type = JOSFS_TYPE_DIR; for(i = 0; i < JOSFS_NDIRECT; i++) f->f_direct[i] = 0; f->f_indirect = 0; for(i = 0; i < blocks; i++) mark_block_free(&info->blocks[blocksize * 2], i); mark_block_used(&info->blocks[blocksize * 2], 0); mark_block_used(&info->blocks[blocksize * 2], 1); for(i = 0; i < (blocks + JOSFS_BLKBITSIZE - 1) / JOSFS_BLKBITSIZE; i++) mark_block_used(&info->blocks[blocksize * 2], i + 2); // done setting up JOS fs BD_INIT(bd, mem_bd); bd->level = 0; bd->graph_index = 0; if(bd->graph_index >= NBDINDEX) { DESTROY(bd); return NULL; } if(modman_add_anon_bd(bd, __FUNCTION__)) { DESTROY(bd); return NULL; } return bd; }