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; }
static void make_bad_inode(void) { struct minix1_inode *inode = &INODE_BUF1[MINIX_BAD_INO]; int i, j, zone; int ind = 0, dind = 0; /* moved to globals to reduce stack usage unsigned short ind_block[BLOCK_SIZE >> 1]; unsigned short dind_block[BLOCK_SIZE >> 1]; */ #define ind_block (G.ind_block1) #define dind_block (G.dind_block1) #define NEXT_BAD (zone = next(zone)) if (!G.badblocks) return; mark_inode(MINIX_BAD_INO); inode->i_nlinks = 1; /* BTW, setting this makes all images different */ /* it's harder to check for bugs then - diff isn't helpful :(... */ inode->i_time = CUR_TIME; inode->i_mode = S_IFREG + 0000; inode->i_size = G.badblocks * BLOCK_SIZE; zone = next(0); for (i = 0; i < 7; i++) { inode->i_zone[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[7] = ind = get_free_block(); memset(ind_block, 0, BLOCK_SIZE); for (i = 0; i < 512; i++) { ind_block[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[8] = dind = get_free_block(); memset(dind_block, 0, BLOCK_SIZE); for (i = 0; i < 512; i++) { write_block(ind, (char *) ind_block); dind_block[i] = ind = get_free_block(); memset(ind_block, 0, BLOCK_SIZE); for (j = 0; j < 512; j++) { ind_block[j] = zone; if (!NEXT_BAD) goto end_bad; } } bb_error_msg_and_die("too many bad blocks"); end_bad: if (ind) write_block(ind, (char *) ind_block); if (dind) write_block(dind, (char *) dind_block); #undef ind_block #undef dind_block }
static void make_bad_inode2(void) { struct minix2_inode *inode = &INODE_BUF2[MINIX_BAD_INO]; int i, j, zone; int ind = 0, dind = 0; /* moved to globals to reduce stack usage unsigned long ind_block[BLOCK_SIZE >> 2]; unsigned long dind_block[BLOCK_SIZE >> 2]; */ #define ind_block (G.ind_block2) #define dind_block (G.dind_block2) if (!G.badblocks) return; mark_inode(MINIX_BAD_INO); inode->i_nlinks = 1; inode->i_atime = inode->i_mtime = inode->i_ctime = CUR_TIME; inode->i_mode = S_IFREG + 0000; inode->i_size = G.badblocks * BLOCK_SIZE; zone = next(0); for (i = 0; i < 7; i++) { inode->i_zone[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[7] = ind = get_free_block(); memset(ind_block, 0, BLOCK_SIZE); for (i = 0; i < 256; i++) { ind_block[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[8] = dind = get_free_block(); memset(dind_block, 0, BLOCK_SIZE); for (i = 0; i < 256; i++) { write_block(ind, (char *) ind_block); dind_block[i] = ind = get_free_block(); memset(ind_block, 0, BLOCK_SIZE); for (j = 0; j < 256; j++) { ind_block[j] = zone; if (!NEXT_BAD) goto end_bad; } } /* Could make triple indirect block here */ bb_error_msg_and_die("too many bad blocks"); end_bad: if (ind) write_block(ind, (char *) ind_block); if (dind) write_block(dind, (char *) dind_block); #undef ind_block #undef dind_block }
static void make_bad_inode_v1(struct fs_control *ctl) { struct minix_inode * inode = &Inode[MINIX_BAD_INO]; int i,j,zone; int ind=0,dind=0; unsigned short ind_block[MINIX_BLOCK_SIZE>>1]; unsigned short dind_block[MINIX_BLOCK_SIZE>>1]; #define NEXT_BAD (zone = next(zone)) if (!ctl->fs_bad_blocks) return; mark_inode(MINIX_BAD_INO); inode->i_nlinks = 1; inode->i_time = mkfs_minix_time(NULL); inode->i_mode = S_IFREG + 0000; inode->i_size = ctl->fs_bad_blocks * MINIX_BLOCK_SIZE; zone = next(0); for (i=0 ; i<7 ; i++) { inode->i_zone[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[7] = ind = get_free_block(ctl); memset(ind_block,0,MINIX_BLOCK_SIZE); for (i=0 ; i<512 ; i++) { ind_block[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[8] = dind = get_free_block(ctl); memset(dind_block,0,MINIX_BLOCK_SIZE); for (i=0 ; i<512 ; i++) { write_block(ctl, ind,(char *) ind_block); dind_block[i] = ind = get_free_block(ctl); memset(ind_block,0,MINIX_BLOCK_SIZE); for (j=0 ; j<512 ; j++) { ind_block[j] = zone; if (!NEXT_BAD) goto end_bad; } } errx(MKFS_EX_ERROR, _("%s: too many bad blocks"), ctl->device_name); end_bad: if (ind) write_block(ctl, ind, (char *) ind_block); if (dind) write_block(ctl, dind, (char *) dind_block); }
static void make_bad_inode(void) { struct minix_inode * inode = &Inode[MINIX_BAD_INO]; int i,j,zone; int ind=0,dind=0; unsigned short ind_block[BLOCK_SIZE>>1]; unsigned short dind_block[BLOCK_SIZE>>1]; #define NEXT_BAD (zone = next(zone)) if (!badblocks) return; mark_inode(MINIX_BAD_INO); inode->i_nlinks = 1; inode->i_time = time(NULL); inode->i_mode = S_IFREG + 0000; inode->i_size = badblocks*BLOCK_SIZE; zone = next(0); for (i=0 ; i<7 ; i++) { inode->i_zone[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[7] = ind = get_free_block(); memset(ind_block,0,BLOCK_SIZE); for (i=0 ; i<512 ; i++) { ind_block[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[8] = dind = get_free_block(); memset(dind_block,0,BLOCK_SIZE); for (i=0 ; i<512 ; i++) { write_block(ind,(char *) ind_block); dind_block[i] = ind = get_free_block(); memset(ind_block,0,BLOCK_SIZE); for (j=0 ; j<512 ; j++) { ind_block[j] = zone; if (!NEXT_BAD) goto end_bad; } } die(_("too many bad blocks")); end_bad: if (ind) write_block(ind, (char *) ind_block); if (dind) write_block(dind, (char *) dind_block); }
static void make_bad_inode_v2_v3 (struct fs_control *ctl) { struct minix2_inode *inode = &Inode2[MINIX_BAD_INO]; int i, j, zone; int ind = 0, dind = 0; unsigned long ind_block[MINIX_BLOCK_SIZE >> 2]; unsigned long dind_block[MINIX_BLOCK_SIZE >> 2]; if (!ctl->fs_bad_blocks) return; mark_inode (MINIX_BAD_INO); inode->i_nlinks = 1; inode->i_atime = inode->i_mtime = inode->i_ctime = mkfs_minix_time(NULL); inode->i_mode = S_IFREG + 0000; inode->i_size = ctl->fs_bad_blocks * MINIX_BLOCK_SIZE; zone = next (0); for (i = 0; i < 7; i++) { inode->i_zone[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[7] = ind = get_free_block (ctl); memset (ind_block, 0, MINIX_BLOCK_SIZE); for (i = 0; i < 256; i++) { ind_block[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[8] = dind = get_free_block (ctl); memset (dind_block, 0, MINIX_BLOCK_SIZE); for (i = 0; i < 256; i++) { write_block (ctl, ind, (char *) ind_block); dind_block[i] = ind = get_free_block (ctl); memset (ind_block, 0, MINIX_BLOCK_SIZE); for (j = 0; j < 256; j++) { ind_block[j] = zone; if (!NEXT_BAD) goto end_bad; } } /* Could make triple indirect block here */ errx(MKFS_EX_ERROR, _("%s: too many bad blocks"), ctl->device_name); end_bad: if (ind) write_block (ctl, ind, (char *) ind_block); if (dind) write_block (ctl, dind, (char *) dind_block); }
static void make_bad_inode2 (void) { struct minix2_inode *inode = &Inode2[MINIX_BAD_INO]; int i, j, zone; int ind = 0, dind = 0; unsigned long ind_block[BLOCK_SIZE >> 2]; unsigned long dind_block[BLOCK_SIZE >> 2]; if (!badblocks) return; mark_inode (MINIX_BAD_INO); inode->i_nlinks = 1; inode->i_atime = inode->i_mtime = inode->i_ctime = time (NULL); inode->i_mode = S_IFREG + 0000; inode->i_size = badblocks * BLOCK_SIZE; zone = next (0); for (i = 0; i < 7; i++) { inode->i_zone[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[7] = ind = get_free_block (); memset (ind_block, 0, BLOCK_SIZE); for (i = 0; i < 256; i++) { ind_block[i] = zone; if (!NEXT_BAD) goto end_bad; } inode->i_zone[8] = dind = get_free_block (); memset (dind_block, 0, BLOCK_SIZE); for (i = 0; i < 256; i++) { write_block (ind, (char *) ind_block); dind_block[i] = ind = get_free_block (); memset (ind_block, 0, BLOCK_SIZE); for (j = 0; j < 256; j++) { ind_block[j] = zone; if (!NEXT_BAD) goto end_bad; } } /* Could make triple indirect block here */ die (_("too many bad blocks")); end_bad: if (ind) write_block (ind, (char *) ind_block); if (dind) write_block (dind, (char *) dind_block); }
void* seg_pool::malloc_one() { pool_block* ba=get_free_block(); if(!ba){ malloc_block(); ba=get_free_block(); if(!ba) return NULL; } void* p=ba->malloc_one(); if(ba->full()){ ba->erase_from_list(); reg_full_block(ba); } return p; }
void make_root_inode(void) { struct minix_inode * inode = &Inode[MINIX_ROOT_INO]; mark_inode(MINIX_ROOT_INO); inode->i_zone[0] = get_free_block(); inode->i_nlinks = 2; inode->i_time = time(NULL); root_block[2*dirsize] = '\0'; root_block[2*dirsize+1] = '\0'; inode->i_size = 2*dirsize; inode->i_mode = S_IFDIR + 0755; write_block(inode->i_zone[0],root_block); }
void make_root_inode(void) { struct minix_inode *inode = &Inode[MINIX_ROOT_INO]; mark_inode(MINIX_ROOT_INO); inode->i_zone[0] = get_free_block(); inode->i_nlinks = 2; inode->i_time = time(NULL); if (badblocks) inode->i_size = 48; else inode->i_size = 32; inode->i_mode = S_IFDIR + 0755; write_block(inode->i_zone[0],root_block); }
int split_rec(int current_list, int list_size, int current_size, int required_size) { if(current_list < 0) { return 0; } if(heap[current_list] == -1 && !split_rec((current_list - 1)/2, list_size / 2, current_size*2, required_size)) { return 0; } if(required_size == current_size && heap[current_list] != -1) { return 1; } int temp = get_free_block(current_list,list_size); add_to_list(2*current_list+1, temp + current_size/2); add_to_list(2*current_list+1, temp); return 1; }
/* Create file with given id in the file system. If file exists already, abort and return FALSE. Otherwise, return TRUE. */ BOOLEAN FileSystem::CreateFile(int _file_id) { if(this->dir[_file_id].start_block != 0) return FALSE; unsigned long free_block; if(get_free_block(&free_block, 0)) { struct dir_node x; x.start_block = free_block; x.size = 0; memcpy(&this->dir[_file_id], &x, sizeof(struct dir_node)); //TODO:write dir to disk this->write_dir_to_disk(); return TRUE; } return FALSE; }
//initializes the ramdisk, 1 if sucessful, -1 if failed int init_ramdisk(){ disk = malloc(RAMDISK_SIZE); if(disk == NULL){ printf("ramdisk allocation failed\n"); return -1; } s_block = disk; inode_array = getblockoffset(1, disk); block_bitmap = getblockoffset(257, disk); free_block_addr = getblockoffset(260, disk); s_block->free_blocks = (RAMDISK_SIZE-256-64-256*4)/256; s_block->free_inodes = (65536/64)-1;//number of inodes //probably not necessary since there's already globals for block_bitmap and free_blocks s_block->bitmap = block_bitmap; s_block->free_block_addr = free_block_addr; //initialize the block_bitmap int i; //set everything to zero for(i = 0; i < 1024; i++){ *block_bitmap = 0; block_bitmap++; } //initialize the inode_array for(i = 0; i < INDEX_NODE_COUNT; i++){ inode_array[i].id = i; inode_array[i].allocated = 0; inode_array[i].type = 0; inode_array[i].size = 0; int j; for(j = 0; j < 10; j++){ inode_array[i].block_pointer[j] = NULL; } inode_array[i].bp_count = 0; } //need a notion of a root directory: inode_array[0].allocated = 1; inode_array[0].type = 1; inode_array[0].block_pointer[0] = get_free_block(); inode_array[0].bp_count = 1; return 1; }
static void make_root_inode_v1(struct fs_control *ctl) { struct minix_inode * inode = &Inode[MINIX_ROOT_INO]; mark_inode(MINIX_ROOT_INO); inode->i_zone[0] = get_free_block(ctl); inode->i_nlinks = 2; inode->i_time = mkfs_minix_time(NULL); if (ctl->fs_bad_blocks) inode->i_size = 3 * ctl->fs_dirsize; else { memset(&root_block[2 * ctl->fs_dirsize], 0, ctl->fs_dirsize); inode->i_size = 2 * ctl->fs_dirsize; } inode->i_mode = S_IFDIR + 0755; inode->i_uid = getuid(); if (inode->i_uid) inode->i_gid = getgid(); write_block(ctl, inode->i_zone[0],root_block); }
static void make_root_inode_v1(void) { struct minix_inode * inode = &Inode[MINIX_ROOT_INO]; mark_inode(MINIX_ROOT_INO); inode->i_zone[0] = get_free_block(); inode->i_nlinks = 2; inode->i_time = time(NULL); if (badblocks) inode->i_size = 3*dirsize; else { root_block[2*dirsize] = '\0'; root_block[2*dirsize+1] = '\0'; inode->i_size = 2*dirsize; } inode->i_mode = S_IFDIR + 0755; inode->i_uid = getuid(); if (inode->i_uid) inode->i_gid = getgid(); write_block(inode->i_zone[0],root_block); }
static void make_root_inode2(void) { struct minix2_inode *inode = &INODE_BUF2[MINIX_ROOT_INO]; mark_inode(MINIX_ROOT_INO); inode->i_zone[0] = get_free_block(); inode->i_nlinks = 2; inode->i_atime = inode->i_mtime = inode->i_ctime = CUR_TIME; if (G.badblocks) inode->i_size = 3 * G.dirsize; else { G.root_block[2 * G.dirsize] = '\0'; G.root_block[2 * G.dirsize + 1] = '\0'; inode->i_size = 2 * G.dirsize; } inode->i_mode = S_IFDIR + 0755; inode->i_uid = GETUID; if (inode->i_uid) inode->i_gid = GETGID; write_block(inode->i_zone[0], G.root_block); }
void* malloc(size_t size) { size_t total_size; void *block; struct header_t *header; if (!size) return NULL; if (header = get_free_block(size)) { header->is_free = 0; // malloc false return NULL;/* FIXME */ } total_size = sizeof(struct header_t) + size; if ((block = sbrk(total_size)) == (void *) -1) return NULL; header = block; header->size = size; header->is_free = 0; header->next = NULL; /* FIXME */ /*DO something*/ return header;/* FIXME */ }
void *malloc(size_t size) { metadata_t *block; // TODO: align size? if (unlikely(size <= 0)) { return 0; } if (unlikely(!base)) { // first pthread_mutex_init(&list_lock, NULL); pthread_mutex_lock(&list_lock); block = get_space(0, size); if (unlikely(!block)) { pthread_mutex_unlock(&list_lock); return 0; } base = block; // pthread_mutex_unlock(&list_lock); } else { pthread_mutex_lock(&list_lock); metadata_t *last = base; block = get_free_block(&last, size); if (!block) { block = get_space(last, size); if (unlikely(!block)) { pthread_mutex_unlock(&list_lock); return 0; } } else { // TODO: split block->free = 0; block->magic1 = MAGIC_USED; block->magic2 = MAGIC_USED; } } alloc_count++; pthread_mutex_unlock(&list_lock); return (block+1); }
int main(int argc, char **argv) { if (argc != 4) { fprintf(stderr, "Usage: readimg <image file name> filepath \n"); exit(1); } // open source file int fd_src = open(argv[2], O_RDONLY); if (fd_src < 0){ fprintf(stderr, "No such file exists in the native file system \n"); exit(ENOENT); } int filesize_src = lseek(fd_src, 0, SEEK_END); // mmap cannot map size 0 file. if (filesize_src <= 0){ fprintf(stderr, "The source file is empty \n"); exit(ENOENT); } int req_block_num = (filesize_src - 1) / EXT2_BLOCK_SIZE + 1; // open the image int fd = open(argv[1], O_RDWR); if (fd < 0){ fprintf(stderr, "No such virtual disk exists \n"); exit(ENOENT); } // map the virtual disk and source file on memory ptr_disk = mmap(NULL, BLOCK_NUM * BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); unsigned char* ptr_disk_src = mmap(NULL, filesize_src, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_src, 0); if (ptr_disk == MAP_FAILED || ptr_disk_src == MAP_FAILED) { perror("mmap"); exit(1); } struct ext2_group_desc *ptr_group_desc = (struct ext2_group_desc *)(ptr_disk + EXT2_SB_OFFSET + EXT2_BLOCK_SIZE); // get the inode table struct ext2_inode *ptr_inode = (struct ext2_inode *)(ptr_disk + EXT2_BLOCK_SIZE * ptr_group_desc->bg_inode_table); unsigned char *bm_inode = (ptr_disk + (ptr_group_desc -> bg_inode_bitmap) * BLOCK_SIZE); unsigned char *bm_block = (ptr_disk + (ptr_group_desc -> bg_block_bitmap) * BLOCK_SIZE); struct ext2_super_block *ptr_super_block = (struct ext2_super_block *)(ptr_disk + EXT2_SB_OFFSET); char *ptr_path_src = strdup(argv[2]); char *ptr_path_dest = strdup(argv[3]); char *table_path_src[10]; char *table_path_dest[10]; int count_path_src = get_path_table(table_path_src, ptr_path_src); int count_path_dest = get_path_table(table_path_dest, ptr_path_dest); // Find the destination directory in the virtual disk struct ext2_dir_entry_2 *ptr_dir_dest = recurse_inode(ptr_inode + 1, table_path_dest, count_path_dest, 0, ptr_group_desc->bg_inode_table); if(ptr_dir_dest == 0) { printf("No such directory exists on virtual disk\n"); return -1; } int table_new_block[req_block_num]; int copy_flag = 0; int i = 0; while(i < req_block_num) { int free_block = get_free_block(bm_block, ptr_super_block); SETBIT(bm_block, free_block); table_new_block[i] = free_block; if(filesize_src - copy_flag <= BLOCK_SIZE) { memcpy(ptr_disk + EXT2_BLOCK_SIZE * (free_block + 1), ptr_disk_src + BLOCK_SIZE * i, filesize_src - copy_flag - 1); } else { memcpy(ptr_disk + EXT2_BLOCK_SIZE * (free_block + 1), ptr_disk_src + BLOCK_SIZE * i, EXT2_BLOCK_SIZE); copy_flag += BLOCK_SIZE; } i++; } int block_id_inderect; if(req_block_num > 11) { block_id_inderect = get_free_block(bm_block, ptr_super_block); int *indirect_block = (int *)(ptr_disk + EXT2_BLOCK_SIZE * (block_id_inderect + 1)); SETBIT(bm_block, block_id_inderect); for(i = 12; i < req_block_num; i++) { *indirect_block = table_new_block[i]; indirect_block++; } } int fr_inode = get_free_inode(bm_inode, ptr_super_block); struct ext2_inode *node_new = ptr_inode + (fr_inode); SETBIT(bm_inode, fr_inode); node_new->i_links_count = 1; node_new->i_mode = EXT2_S_IFREG; node_new->i_size = filesize_src; node_new->i_blocks = req_block_num * 2; i = 0; while (i < 11 && req_block_num != i) { node_new->i_block[i] = table_new_block[i]; i++; } if(req_block_num > 11) { node_new -> i_block[12] = block_id_inderect; } struct ext2_inode *in_src = (struct ext2_inode *)(ptr_disk + EXT2_BLOCK_SIZE * ptr_group_desc->bg_inode_table); struct ext2_inode *in_cur = (struct ext2_inode *)(ptr_disk + EXT2_BLOCK_SIZE * ptr_group_desc->bg_inode_table); in_src = in_src + ptr_dir_dest -> inode - 1; in_cur = in_cur + ptr_dir_dest -> inode - 1; in_cur->i_links_count++; int len_req = strlen(table_path_src[count_path_src - 1]) + 8; struct ext2_dir_entry_2 *ptr_dir = get_free_space(in_cur, len_req); if(ptr_dir == 0) { int free_block_new = get_free_block(bm_block, ptr_super_block); ptr_dir = (void*)ptr_disk + EXT2_BLOCK_SIZE * (free_block_new + 1); ptr_dir -> inode = fr_inode + 1; ptr_dir -> name_len = strlen(table_path_dest[count_path_dest - 1]); ptr_dir -> file_type = EXT2_FT_DIR; strcpy(ptr_dir -> name, table_path_dest[count_path_dest - 1]); ptr_dir -> rec_len = BLOCK_SIZE; in_src -> i_blocks += 2; in_src ->i_block[in_src -> i_size / BLOCK_SIZE] = free_block_new + 1; in_src -> i_size += BLOCK_SIZE; } else { int new_rec_len = ptr_dir -> rec_len - (4 * (ptr_dir -> name_len) + 8); ptr_dir -> rec_len = 4 * (ptr_dir -> name_len) + 8; ptr_dir = (void*)ptr_dir + ptr_dir -> rec_len; ptr_dir -> rec_len = new_rec_len; ptr_dir -> inode = fr_inode + 1; ptr_dir -> name_len = strlen(table_path_dest[count_path_dest - 1]); ptr_dir -> file_type = EXT2_FT_REG_FILE; strcpy(ptr_dir -> name, table_path_dest[count_path_dest - 1]); } ptr_group_desc->bg_used_dirs_count++; return 0; }
int main(int argc,char *argv[]) { int error = -1; int i; int flc; int index; int free_FLC; struct fileinfo info; int new_flc; int new_index; int status; int num; char *last; char buffer[260]; char buffer1[260]; char file_name[10]; char name[10]; char ext[4]; char* etmp; /*Checks number of arguments*/ if(argc != 2) { printf("Please specify one directory.\n"); return error; } /*Right number of arguments*/ else { init_util(); status = parse_path(argv[1],&flc,&index); /*Checks if directory exists*/ if(status != E_NOTEXIST) { printf("Directory already exists.\n"); return error; } /*Directory does not exist, make a new one!*/ else { last = rindex(argv[1],'/'); /*Check if path is relative*/ if(last == 0) { get_abs_path(buffer1,argv[1]); last = rindex(buffer1,'/'); num = (int)(last-buffer1+1); strncpy(buffer,buffer1,num); buffer[num] = '\0'; //printf("Buffer is:%s\n",buffer); strcpy(name,argv[1]); //printf("I am here and name is:%s\n",name); } /*Path may still be relative, but there is at least one '/'*/ else { /*Check if there is an ending '/'*/ if(strlen(last) == 1) { //Checks if the last character is "/" get_abs_path(buffer, argv[1]); //printf("Buffer is:%s\n",buffer); strncpy(buffer1,buffer,(strlen(buffer)-1)); //printf("Buffer1 is:%s\n",buffer1); buffer1[strlen(buffer)-1]='\0'; last = rindex(buffer1,'/'); if(last == 0) { buffer[0] = '\0'; num = 1; } else { num = (int)(last-buffer1+1); strncpy(buffer,buffer1,num); buffer[num] = '\0'; //printf("Buffer is:%s\n",buffer); last = rindex(buffer1,'/'); if(last == 0) { buffer[0] = '\0'; } } } /*No ending '/', continue*/ else { //printf("Last is:%d\n",strlen(last)); num = (int)(last-argv[1]+1); strncpy(buffer,argv[1],num); strcpy(buffer1,argv[1]); //printf("Buffer is:%s\n",buffer); buffer[num] = '\0'; } /*Check if the path is really relative*/ if(argv[1][0] != '/' && last != 0) { last = rindex(buffer1,'/'); num = (int)(last-buffer1+1); //printf("%d\n",num); strcpy(name,&buffer1[num]); } else if(argv[1][0] != '/' && last == 0) { strcpy(name,buffer1); } /*Path is not relative, continue*/ else { strcpy(file_name,&buffer1[num]); //Keeps track of the new directory name //printf("%d\n",strlen(buffer1)-1); file_name[strlen(buffer1)-1]='\0'; //printf("File name is:%s\n",file_name); if(file_name[0] == '/') { //Checks if the first character is the "/" for(i=0;i<(strlen(buffer1)-1);i++) { name[i] = file_name[i+1]; } name[strlen(buffer1)-1]= '\0'; } else { strcpy(name,file_name); } } } //printf("num: %d buffer: %s\n", num, buffer); status = parse_path(buffer,&flc,&index); free_FLC = get_free_block(); info = get_file_info(flc,index); info.attrib = '\x10'; etmp = (char*)strtok(name, "."); strcpy(info.filename,etmp); etmp = (char*)strtok(NULL,"."); strcpy(info.ext, ((etmp == NULL) ? " " : etmp)); allocate_block(free_FLC,info,info.FLC,&new_flc,&new_index); strcpy(info.filename,".."); strcpy(info.ext," "); allocate_block(0,info,free_FLC,&new_flc,&new_index); strcpy(info.filename,"."); strcpy(info.ext," "); info.FLC = free_FLC; allocate_block(0,info,free_FLC,&new_flc,&new_index); return 1; } } kill_util(); }
/* * ======== cmm_calloc_buf ======== * Purpose: * Allocate a SM buffer, zero contents, and return the physical address * and optional driver context virtual address(pp_buf_va). * * The freelist is sorted in increasing size order. Get the first * block that satifies the request and sort the remaining back on * the freelist; if large enough. The kept block is placed on the * inUseList. */ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, struct cmm_attrs *pattrs, OUT void **pp_buf_va) { struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; void *buf_pa = NULL; struct cmm_mnode *pnode = NULL; struct cmm_mnode *new_node = NULL; struct cmm_allocator *allocator = NULL; u32 delta_size; u8 *pbyte = NULL; s32 cnt; if (pattrs == NULL) pattrs = &cmm_dfltalctattrs; if (pp_buf_va != NULL) *pp_buf_va = NULL; if (cmm_mgr_obj && (usize != 0)) { if (pattrs->ul_seg_id > 0) { /* SegId > 0 is SM */ /* get the allocator object for this segment id */ allocator = get_allocator(cmm_mgr_obj, pattrs->ul_seg_id); /* keep block size a multiple of ul_min_block_size */ usize = ((usize - 1) & ~(cmm_mgr_obj->ul_min_block_size - 1)) + cmm_mgr_obj->ul_min_block_size; mutex_lock(&cmm_mgr_obj->cmm_lock); pnode = get_free_block(allocator, usize); } if (pnode) { delta_size = (pnode->ul_size - usize); if (delta_size >= cmm_mgr_obj->ul_min_block_size) { /* create a new block with the leftovers and * add to freelist */ new_node = get_node(cmm_mgr_obj, pnode->dw_pa + usize, pnode->dw_va + usize, (u32) delta_size); if (new_node) { /* leftovers go free */ add_to_free_list(allocator, new_node); } /* adjust our node's size */ pnode->ul_size = usize; } /* Tag node with client process requesting allocation * We'll need to free up a process's alloc'd SM if the * client process goes away. */ /* Return TGID instead of process handle */ pnode->client_proc = current->tgid; /* put our node on InUse list */ lst_put_tail(allocator->in_use_list_head, (struct list_head *)pnode); buf_pa = (void *)pnode->dw_pa; /* physical address */ /* clear mem */ pbyte = (u8 *) pnode->dw_va; for (cnt = 0; cnt < (s32) usize; cnt++, pbyte++) *pbyte = 0; if (pp_buf_va != NULL) { /* Virtual address */ *pp_buf_va = (void *)pnode->dw_va; } } mutex_unlock(&cmm_mgr_obj->cmm_lock); } return buf_pa; }
int main(int argc, char const *argv[]){ if(argc != 4) { fprintf(stderr, "Usage: ext2_cp <formatted virtual disk> <local path> <absolute disk path>\n"); exit(1); } int fd = open(argv[1], O_RDWR); disk = mmap(NULL, 128 * EXT2_BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if(disk == MAP_FAILED) { perror("mmap"); exit(1); } FILE * fp; fp = fopen(argv[2], "r"); if (fp == NULL) { printf("File not found\n"); exit(ENOENT); } //get file size fseek(fp, 0L, SEEK_END); int file_sz = ftell(fp); fseek(fp, 0L, SEEK_SET); //number of blocks needed to copy file int num_blocks_needed = (int) (file_sz / EXT2_BLOCK_SIZE) + 1; //get the superblock struct ext2_super_block *superblock = (struct ext2_super_block *) (disk + EXT2_BLOCK_SIZE); int first_data_block = superblock->s_first_data_block; if (num_blocks_needed > superblock->s_free_blocks_count){ fprintf(stderr, "No space left on device\n"); exit(ENOSPC); } // get the group descriptor table // we know that this table always start at third datablock (index 2) struct ext2_group_desc *group_des_table = (struct ext2_group_desc*) (disk + EXT2_BLOCK_SIZE * 2); int inode_bitmap = group_des_table->bg_inode_bitmap; int block_bitmap = group_des_table->bg_block_bitmap; int inode_table = group_des_table->bg_inode_table; void *tablestart = disk + EXT2_BLOCK_SIZE * inode_table; //check that the path does not already exist int found_inode; found_inode = search_inode(argv[3]); if (found_inode != -1){ // has to be not found fprintf(stderr, "File exists\n"); exit(EEXIST); } //get the parent directory into which to copy the file int parent_inode_num = parent_conversion(argv[3]); if (parent_inode_num == -1){ fprintf(stderr, "No such file or directory\n"); exit(ENOENT); } //get the inode of that parent directory struct ext2_inode *parent_inode = (struct ext2_inode*) (tablestart) + (parent_inode_num - 1); if (parent_inode->i_mode & EXT2_S_IFREG){ fprintf(stderr, "No such file or directory\n"); exit(ENOENT); } //get block bitmap int block_bitmap_block = block_bitmap * EXT2_BLOCK_SIZE; void * block_bits = (void *)(disk + block_bitmap_block); //get inode bitmap unsigned long inode_bitmap_block = inode_bitmap * EXT2_BLOCK_SIZE; void * inode_bits = (void *)(disk + inode_bitmap_block); //find free inode int inode_indx = get_free_inode(inode_bits); if (inode_indx == -1){ fprintf(stderr, "No space left on device\n"); exit(ENOSPC); } //update superblock superblock->s_free_inodes_count = superblock->s_free_inodes_count - 1; //init new inode struct ext2_inode *new_inode = (struct ext2_inode*)(tablestart) + (inode_indx); new_inode->i_mode = 32768; //is file new_inode->i_size = file_sz; new_inode->i_blocks = 1; new_inode->i_links_count = 1; //global variables for indirect block if necessary void *indirect_block; unsigned int indr_block[15]; void *data_block; int i; for (i = 0; i < num_blocks_needed; i++){ if (i < 12){ int free_block_num = get_free_block(block_bits); if (free_block_num == -1){ fprintf(stderr, "No space left on device\n"); exit(ENOSPC); } superblock->s_free_blocks_count = superblock->s_free_blocks_count - 1; new_inode->i_blocks += 1; new_inode->i_block[i] = first_data_block + free_block_num -1; data_block = (void *)(disk + (EXT2_BLOCK_SIZE * new_inode->i_block[i])); } else if (i == 12){ //i_blocks[12] entry is the 13th entry in the array //It holds the block number of the indirect block //- this block contains an array of block numbers //for the next data blocks of the file. //get free block for indirect block int indirect_block_num = get_free_block(block_bits); if (indirect_block_num == -1){ fprintf(stderr, "No space left on device\n"); exit(ENOSPC); } new_inode->i_block[i] = first_data_block + indirect_block_num; //initialize indirect block indirect_block = (void *)(disk + (EXT2_BLOCK_SIZE * new_inode->i_block[i])); //get data block int free_block_num = get_free_block(block_bits); if (free_block_num == -1){ fprintf(stderr, "No space left on device\n"); exit(ENOSPC); } superblock->s_free_blocks_count = superblock->s_free_blocks_count - 1; new_inode->i_blocks += 1; indr_block[i - 12] = first_data_block + free_block_num -1; memcpy(indirect_block, (void *) indr_block, 16); data_block = (void *)(disk + (EXT2_BLOCK_SIZE * indr_block[i - 12])); } else if (i > 12){ int free_block_num = get_free_block(block_bits); if (free_block_num == -1){ fprintf(stderr, "No space left on device\n"); exit(ENOSPC); } superblock->s_free_blocks_count = superblock->s_free_blocks_count - 1; new_inode->i_blocks += 1; indr_block[i - 12] = first_data_block + free_block_num -1; memcpy(indirect_block, (void *) indr_block, 16); data_block = (void *)(disk + (EXT2_BLOCK_SIZE * indr_block[i - 12])); } //read data from file to data block int num_read = fread(data_block, 1, EXT2_BLOCK_SIZE, fp); if (num_read == 0){ perror("Error reading file"); } } fclose(fp); //add this new file's directory entry to the parent directory int c; //loop through directory entries to get to the last entry for (c = 0; c < EXT2_BLOCK_SIZE;){ struct ext2_dir_entry_2 *node_dir = (struct ext2_dir_entry_2 *) (disk + (EXT2_BLOCK_SIZE * parent_inode->i_block[0]) + c); if (c + node_dir->rec_len == EXT2_BLOCK_SIZE){ //this is the last block in the directory int new_rec_len = node_dir->rec_len - node_dir->name_len - 8; node_dir->rec_len = node_dir->name_len + 8; //create directory entry struct ext2_dir_entry_2 *par_dir = (struct ext2_dir_entry_2 *) (disk + (EXT2_BLOCK_SIZE * parent_inode->i_block[0] + c + node_dir->rec_len)); par_dir->inode = inode_indx + 1; par_dir->file_type = 1; //get name of new file char dup_path[strlen(argv[3])]; strcpy(dup_path, argv[3]); char *ret; ret = strrchr(dup_path, '/'); if (ret[0] == '/'){ ret++; } par_dir->rec_len = new_rec_len; par_dir->name_len = strlen(ret); strcpy(par_dir->name, ret); break; } c += node_dir->rec_len; } return 0; }
int mk_new_directory(jfs_t *jfs, char *pathname, int parent_inodenum, int grandparent_inodenum) { /* we need to create this directory */ /* round size up to nearest 4 byte boundary */ int size, prev_size, bytes_done=0; int new_inodenum, new_blocknum; char block[BLOCKSIZE]; struct inode* new_inode, *parent_inode; /* calculate the size of the new parent dirent */ size = (((strlen(pathname)/4) + 1) * 4) + 16; /* does it fit?*/ if (bytes_done + size > BLOCKSIZE) { fprintf(stderr, "No more space in the directory to add another entry\n"); exit(1); } /* allocate an inode for this directory */ if (strcmp(pathname, ".")==0) { new_inodenum = parent_inodenum; } else if (strcmp(pathname, "..")==0) { new_inodenum = grandparent_inodenum; } else { new_inodenum = get_free_inode(jfs); } /* update the parent directories inode size field */ jfs_read_block(jfs, block, inode_to_block(parent_inodenum)); parent_inode = (struct inode*)(block + (parent_inodenum % INODES_PER_BLOCK) * INODE_SIZE); prev_size = parent_inode->size; parent_inode->size += size; jfs_write_block(jfs, block, inode_to_block(parent_inodenum)); /* create an entry in the parent directory */ create_dirent(jfs, pathname, DT_DIRECTORY, parent_inode->blockptrs[0], prev_size, size, new_inodenum); if (strcmp(pathname, ".")!=0 && strcmp(pathname, "..")!=0) { /* it's a real directory */ /* get a block to hold the directory */ new_blocknum = get_free_block(jfs); /* read in the block that contains our new inode */ jfs_read_block(jfs, block, inode_to_block(new_inodenum)); new_inode = (struct inode*)(block + (new_inodenum % INODES_PER_BLOCK) * INODE_SIZE); new_inode->flags = FLAG_DIR; new_inode->blockptrs[0] = new_blocknum; new_inode->size = 0; /* write back the inode block */ jfs_write_block(jfs, block, inode_to_block(new_inodenum)); return new_inodenum; } return parent_inodenum; }
void* Ps_Malloc(long size) { struct mm_block *block; char *ret; int index; int d = size; size += sizeof(struct mm_head); index = SIZE2INDEX(size); size = ROUND(size); //待申请的内存太大,使用普通的内存分配方法 if(size > SMALL_MEM_LIMIT) { ret = (char*)malloc(size); /*((struct mm_head*)ret)->size = size; ret += sizeof(struct mm_head); return ret;*/ WRAP_TO_RET(ret, size); } MM_GET_LOCK(); if(mm_structs[index].frees) { ret = (char*)(mm_structs[index].frees); mm_structs[index].frees = (void*)(*(long*)ret); /*((struct mm_head*)ret)->size = size; ret += sizeof(struct mm_head); return ret;*/ WRAP_TO_RET(ret, size); } //没有找到适合的内存块 if(get_perfect_index(size) == -1) { block = get_free_block(); if(!block) { MM_RELEASE_LOCK(); return NULL; } block->next = mm_structs[index].block; mm_structs[index].block = block; block->begin = (void*)((char*)block + BLOCK_STRUCT_SIZE); ret = block->begin; block->free_number = (BLOCK_SIZE - BLOCK_STRUCT_SIZE) / size - 1; block->frees = (void*)((char*)ret + size); WRAP_TO_RET(ret, size); } else { int pi = get_perfect_index(size); int tmp; int remain; assert(mm_structs[pi].block->free_number > 0); if(pi < index) { tmp = (index + 1) / (pi + 1); tmp = (tmp * (pi + 1) == index + 1) ? tmp : (tmp + 1); ret = mm_structs[pi].block->frees; remain = tmp * INDEX2SIZE(pi) - size; assert(tmp <= mm_structs[pi].block->free_number); mm_structs[pi].block->free_number -= tmp; mm_structs[pi].block->frees = (void*)((char*)mm_structs[pi].block->frees + tmp * INDEX2SIZE(pi)); assert(remain >= 0); assert(remain < size); if(remain) { struct mm_head *head = (struct mm_head*)(ret + size); *(long*)head = (long)mm_structs[SIZE2INDEX(remain)].frees; mm_structs[SIZE2INDEX(remain)].frees = (void*)head; } WRAP_TO_RET(ret, size); } else if(pi == index) { mm_structs[index].block->free_number --; ret = (char*)mm_structs[index].block->frees; mm_structs[index].block->frees = (void*)((char*)ret + size); WRAP_TO_RET(ret, size); } else { void *rp; mm_structs[pi].block->free_number --; ret = (char*)mm_structs[pi].block->frees; mm_structs[pi].block->frees = (void*)((char*)ret + INDEX2SIZE(pi)); remain = INDEX2SIZE(pi) - size; rp = ret + size; *(long*)rp = (long)mm_structs[SIZE2INDEX(remain)].frees; mm_structs[SIZE2INDEX(remain)].frees = rp; WRAP_TO_RET(ret, size); } } }
/* Reads from or writes to the given sector at bytes i such that from <= i < to, * reading them to or writing them from buffer. buffer must have size at least * from - to. * * For internal use. */ static void cached_read_write(block_sector_t sector, bool write, uint32_t from, uint32_t to, void *buffer) { ASSERT (from < to); ASSERT (to <= BLOCK_SECTOR_SIZE); struct cached_block *cb; while (true) { reader_acquire(§or_lock); cb = find_cached_sector(sector); if (cb != NULL) { reader_release(§or_lock); rw_acquire(&cb->rw_lock, write); if (cb->sector == sector && (cb->state == CLEAN || cb->state == DIRTY)) { /* Typical case: Found the sector in cache, and it didn't * change before we got a chance to see it. */ if (write) { memcpy(cb->data + from, buffer, (to - from)); cb->state = DIRTY; } else { memcpy(buffer, cb->data + from, (to - from)); } cb->accessed = true; /* XXX synchronized? */ rw_release(&cb->rw_lock, write); return; } /* Atypical case: We found the sector in cache, but it changed * before we got a chance to see it: Try again. */ rw_release(&cb->rw_lock, write); } else { cb = get_free_block(); reader_release(§or_lock); writer_acquire(§or_lock); if (find_cached_sector(sector) == NULL) { /* Typical case: We didn't find the sector in cache, and it * didn't pop up before we could add it */ cb->sector = sector; cb->state = IN_IO; writer_release(§or_lock); block_read(fs_device, cb->sector, cb->data); cb->state = CLEAN; if (write) { memcpy(cb->data + from, buffer, (to - from)); cb->state = DIRTY; } else { memcpy(buffer, cb->data + from, (to - from)); } cb->accessed = true; writer_release(&cb->rw_lock); return; } /* Atypical case: We didn't find the sector in cache, but it * popped up before we could add it: Try again. */ writer_release(§or_lock); writer_release(&cb->rw_lock); } } }
/** * Allocate a block of memory * * @param sz size of the required block * @returns pointer to block */ void *kmalloc(u32 sz) { kerror(ERR_DETAIL, "Allocating %d bytes of memory", sz); // We don't want two processes using the same memory block! lock(&alloc_lock); // Find the smallest memory block that we can use u32 idx = find_hole(sz); // Couldn't find one... if(idx == 0xFFFFFFFF) return 0; int block = idx >> 16; int index = idx & 0xFFFF; if(empty_slots(block) == 4) // Get ready ahead of time { u32 asz = ALLOC_BLOCK * sizeof(struct alcent); u32 idx = find_hole(asz); if(idx == 0xFFFFFFFF) kpanic("Could not create another allocation block!"); int block = idx >> 16; int index = idx & 0xFFFF; if(allocs[block][index].size == asz) { allocs[block][index].used = 1; allocs[get_free_block()] = (struct alcent *)allocs[block][index].addr; } else { allocs[block][index].size -= asz; struct alcent ae = { .valid = 1, .used = 1, .addr = allocs[block][index].addr, .size = asz }; allocs[block][index].addr += asz; add_alloc(&ae); allocs[get_free_block()] = (struct alcent *)ae.addr; } } // If the previous block of code was used, we may have to reinitialize these idx = find_hole(sz); if(idx == 0xFFFFFFFF) return 0; block = idx >> 16; index = idx & 0xFFFF; if(allocs[block][index].size == sz) { allocs[block][index].used = 1; unlock(&alloc_lock); kerror(ERR_DETAIL, " -> %08X W", allocs[block][index].addr); return (void *)allocs[block][index].addr; } allocs[block][index].size -= sz; // We are using part of this block struct alcent ae = { .valid = 1, .used = 1, .addr = allocs[block][index].addr, .size = sz }; allocs[block][index].addr += sz; // We don't want anything else using the allocated memory add_alloc(&ae); // We will just assume this worked, the worst that could happen is we can't `free` it (FIXME) // Let other processes allocate memory unlock(&alloc_lock); kerror(ERR_DETAIL, " -> %08X P", ae.addr); return (void *)ae.addr; } /** * Free an allocated block of memory * * @param ptr pointer to the previously allocated memory block */ void kfree(void *ptr) { kerror(ERR_DETAIL, "Freeing %08X", ptr); lock(&alloc_lock); int i, j = 0; // Find the corresponding memory block for(; j < ALLOC_BLOCKS; j++) { if(!allocs[j]) continue; for(i = 0; i < ALLOC_BLOCK; i++) if(allocs[j][i].valid) // Is it valid? if(allocs[j][i].addr == (u32)ptr) // Is it the correct block? rm_alloc(j, i); // Free it! } unlock(&alloc_lock); }