/* Closes INODE and writes it to disk. If this was the last reference to INODE, frees its memory. If INODE was also a removed inode, frees its blocks. */ void inode_close (struct inode *inode) { /* Ignore null pointer. */ if (inode == NULL) return; //Acquire both the internal and global inode locks. Internal is required so nobody can change the //open_cnt variable while the external lock is required so nobody can get a new pointer to the node //while it's being deleted and later freed which would result in a dangling pointer. lock_acquire(&inode_list_lock); lock_acquire(&inode->internal_lock); /* Release resources if this was the last opener. */ if (--inode->open_cnt == 0) { /* Remove from inode list and release lock. */ list_remove (&inode->elem); /* Deallocate blocks if removed. */ if (inode->removed) { free_map_release (inode->sector, 1); free_map_release (inode->data.start, bytes_to_sectors (inode->data.length)); } free (inode); } else { lock_release(&inode->internal_lock); } lock_release(&inode_list_lock); }
/* Closes INODE and writes it to disk. If this was the last reference to INODE, frees its memory. If INODE was also a removed inode, frees its blocks. */ void inode_close (struct inode *inode) { /* Ignore null pointer. */ if (inode == NULL) return; lock_acquire(&inode_list_lock); lock_acquire(&inode->inode_lock); /* Release resources if this was the last opener. */ if (--inode->open_cnt == 0) { /* Remove from inode list. */ list_remove (&inode->elem); /* Deallocate blocks if the file is marked as removed. */ if (inode->removed) { free_map_release (inode->sector, 1); free_map_release (inode->data.start, bytes_to_sectors (inode->data.length)); } lock_release(&inode->inode_lock); free (inode); lock_release(&inode_list_lock); return; } lock_release(&inode->inode_lock); lock_release(&inode_list_lock); }
static void deallocate_sectors(struct inode_disk *data) { size_t i, j; size_t sectors = bytes_to_sectors(data->length); struct sector_table *doubly_indirect_table = calloc(1, sizeof(struct sector_table)); cache_read(data->doubly_indirect, doubly_indirect_table, 512, 0); for(i = 0; i < 128; i++) { if(sectors == 0) break; struct sector_table *indirect_table = calloc(1, sizeof(struct sector_table)); cache_read(data->indirect, indirect_table, 512, 0); for(j = 0; j < 128; j++) { if(sectors == 0) break; free_map_release(indirect_table->table[j], 1); sectors--; } free_map_release(data->indirect, 1); free(indirect_table); } //free_map_release(data->doubly_indirect, 1); free(doubly_indirect_table); }
void inode_deallocate_data_blocks(struct inode* inode){ struct inode_disk disk_inode = inode->data; int i, size = disk_inode.length; if(size<=DIRECT_ACCESS){ for(i=0; i<DIV_ROUND_UP(size, BLOCK_SECTOR_SIZE); i++){ free_map_release(disk_inode.direct[i], 1); } return; } if(size<= DIRECT_ACCESS+INDIRECT_ACCESS){ for(i=0; i<N_DIRECT_BLOCKS; i++){ free_map_release(disk_inode.direct[i], 1); } size-=DIRECT_ACCESS; uint32_t* indirect_block = (uint32_t*)malloc(BLOCK_SECTOR_SIZE); cached_read(inode, disk_inode.indirect,indirect_block); for(i=0; i<DIV_ROUND_UP(size, BLOCK_SECTOR_SIZE); i++){ free_map_release(indirect_block[i], 1); } free_map_release(disk_inode.indirect, 1); free(indirect_block); return; } if(size<=DIRECT_ACCESS+INDIRECT_ACCESS+DOUBLE_INDIRECT_ACCESS){ uint32_t* buff = (uint32_t*)malloc(BLOCK_SECTOR_SIZE); for(i=0; i<N_DIRECT_BLOCKS; i++){ free_map_release(disk_inode.direct[i], 1); } size-=DIRECT_ACCESS; uint32_t* indirect_block = (uint32_t*)malloc(BLOCK_SECTOR_SIZE); cached_read(inode, disk_inode.indirect,indirect_block); for(i=0; i<N_INDIRECT_POINTERS; i++){ free_map_release(indirect_block[i], 1); } free_map_release(disk_inode.indirect, 1); free(indirect_block); size-=INDIRECT_ACCESS; uint32_t* double_indirect_block = (uint32_t*)malloc(BLOCK_SECTOR_SIZE); cached_read(inode, disk_inode.double_indirect,double_indirect_block); int c_size = size; int i,j; for(i=0; i<DIV_ROUND_UP(c_size, N_INDIRECT_POINTERS*BLOCK_SECTOR_SIZE); i++){ cached_read(inode, double_indirect_block[i], buff); for(j=0; j<N_INDIRECT_POINTERS && j<DIV_ROUND_UP(size, BLOCK_SECTOR_SIZE); j++){ free_map_release(buff[j], 1); } size-=BLOCK_SECTOR_SIZE*N_INDIRECT_POINTERS; free_map_release(double_indirect_block[i],1); } free_map_release(disk_inode.double_indirect, 1); free(double_indirect_block); free(buff); return; } }
/* Creates directory. True if successful. */ bool filesys_mkdir (const char *dir) { bool success = false; /*The string *dir cannot be empty.*/ if (*dir == NULL) { return success; } /* Locates the directory where the new directory should be created. */ struct dir *create_dir; char parsed_name[NAME_MAX + 1]; parse_path (dir, &create_dir, parsed_name); block_sector_t sector; /*Find a free sector for the directory.*/ if (!free_map_allocate (1, §or)) { return success; } success = dir_create (sector, 16); if (!success) { free_map_release (sector, 1); return success; } success = dir_add (create_dir, parsed_name, sector); if (!success) { free_map_release (sector, 1); return success; } /* Get the dir struct of the directory that is just created and add "." and "..". */ struct inode *inode = inode_open (sector); struct dir *new_dir = dir_open (inode); ASSERT (inode != NULL); ASSERT (new_dir != NULL); dir_add (new_dir, ".", sector); dir_add (new_dir, "..", create_dir->inode->sector); dir_close (new_dir); dir_close (create_dir); return success; }
/* Closes INODE and writes it to disk. If this was the last reference to INODE, frees its memory. If INODE was also a removed inode, frees its blocks. */ void inode_close (struct inode *inode) { /* Ignore null pointer. */ if (inode == NULL) return; /* Release resources if this was the last opener. */ if (--inode->open_cnt == 0) { /* Remove from inode list and release lock. */ list_remove (&inode->elem); /* Deallocate blocks if removed. */ if (inode->removed) { int sectors = bytes_to_sectors(inode->data.length); block_sector_t bounce[128]; block_sector_t inbounce[128]; int i,j; int doublesec = DIV_ROUND_UP(sectors,128); free_map_release (inode->sector, 1); lock_acquire(&device_lock); block_read(fs_device,inode->data.start,bounce); lock_release(&device_lock); for(i=0; i<doublesec; i++) { int loop = sectors < 128 ? sectors : 128; lock_acquire(&device_lock); block_read(fs_device,bounce[i],inbounce); lock_release(&device_lock); for(j=0; j<loop; j++) { free_map_release(inbounce[j],1); } sectors -=loop; free_map_release(bounce[i],1); } free_map_release(inode->data.start,1); //free_map_release (inode->data.start, // bytes_to_sectors (inode->data.length)); } free (inode); } }
/* Closes INODE and writes it to disk. If this was the last reference to INODE, frees its memory. If INODE was also a removed inode, frees its blocks. */ void inode_close (struct inode *inode) { /* Ignore null pointer. */ if (inode == NULL) return; /* Release resources if this was the last opener. */ if (--inode->open_cnt == 0) { /* Remove from inode list and release lock. */ list_remove (&inode->elem); /* Deallocate blocks if removed. */ if (inode->removed) { int num_sectors = bytes_to_sectors (inode->length); inode_release_allocated_sectors (inode, num_sectors); uint8_t buf[BLOCK_SECTOR_SIZE]; memset (buf, 0, BLOCK_SECTOR_SIZE); block_write (fs_device, inode->sector, buf); free_map_release (inode->sector, 1); } free (inode); } }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size) { block_sector_t inode_sector = 0; struct dir *dir; char parsed_name[NAME_MAX + 1]; if (*name == NULL || (strlen (name) > NAME_MAX)) { return false; } bool success = parse_path (name, &dir, parsed_name); if (!success) { return success; } struct inode *inode; success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, false) && dir_add (dir, parsed_name, inode_sector) && dir_lookup (dir, ".", &inode)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); return success; }
/* Closes INODE and writes it to disk. If this was the last reference to INODE, frees its memory. If INODE was also a removed inode, frees its blocks. */ void inode_close (struct inode *inode) { /* Ignore null pointer. */ if (inode == NULL) return; /* Release resources if this was the last opener. */ if (--inode->open_cnt == 0) { /* Remove from inode list and release lock. */ list_remove (&inode->elem); /* Deallocate blocks if removed. */ if (inode->removed) { free_map_release (inode->sector, 1); //free_map_release (inode->data.start, // bytes_to_sectors (inode->data.length)); deallocate_sectors(&inode->data); } free (inode); } }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *path, off_t initial_size) { block_sector_t inode_sector = 0; struct dir *dir = NULL; bool success = false; char *name = malloc (NAME_MAX + 1); if (name == NULL) goto done; if (!dir_follow_path (thread_current ()->cwd, path, &dir, name)) goto done; success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size) && dir_add (dir, name, inode_sector)); if (!success && inode_sector != 0) { cache_remove (fs_cache, inode_sector, 1); free_map_release (inode_sector, 1); } done: dir_close (dir); free (name); return success; }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size, enum file_type type) { block_sector_t inode_sector = 0; char * parse = parse_filename (name); //get the correct dir struct dir *dir = dir_lookup_rec (parse); bool success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, type) && dir_add (dir, parse, inode_sector)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); if( success == true && type == FILE_DIR ) { //we want to add . and .. as well if it is a dir //open the created directory struct file * created = filesys_open(parse); struct dir * mydir = dir_open(file_get_inode (created)); //add . to it dir_add (mydir, ".", inode_sector); struct inode * parent = dir_get_inode (dir); block_sector_t inode_sector_parent = inode_id(parent); //add .. to it dir_add (mydir, "..", inode_sector_parent); dir_close(mydir); file_close(created); } dir_close (dir); return success; }
/* help to free_map_release single indirect index sectors from beginning * to end_idx (exclusive) */ static void free_map_release_single_indirect(struct indirect_block *ib, int end_idx){ int i; for (i = 0; i < end_idx; i++) { free_map_release (ib->sectors[i], 1); } }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size, bool isdir) { block_sector_t inode_sector = 0; // Get directory struct dir *dir = get_containing_dir(name); char *file_name = get_filename(name); // Get file name char* file_name = get_filename(name); bool success = false; if (strcmp(file_name, ".") != 0 && strcmp(file_name, "..") != 0) { success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, isdir) && dir_add (dir, file_name, inode_sector)); } if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); free(file_name); return success; }
/* Closes INODE and writes it to disk. If this was the last reference to INODE, frees its memory. If INODE was also a removed inode, frees its blocks. */ void inode_close (struct inode *inode) { /* Ignore null pointer. */ if (inode == NULL) return; /* Release resources if this was the last opener. */ if (--inode->open_cnt == 0) { lock_acquire (&inode->lock); /* Remove from inode list and release lock. */ list_remove (&inode->elem); /* Deallocate blocks if removed. */ if (inode->removed) { inode_clear (inode); free_map_release (inode->sector, 1); } lock_release (&inode->lock); free (inode); } }
/* help to free_map_release direct index sectors from beginning to * end_idx (exclusive) */ static void free_map_release_direct(struct inode_disk *disk_inode, int end_idx) { int i; for (i = 0; i < end_idx; i++) { free_map_release(disk_inode->direct_idx[i], 1); } }
void inode_delete(disk_sector_t sector){ struct inode_disk *disk_inode; disk_inode = calloc (1, sizeof *disk_inode); if(disk_inode != NULL){ cache_read(sector, disk_inode, 0, DISK_SECTOR_SIZE); if(disk_inode->level == 0) free_map_release(disk_inode->inode_index, disk_inode->count); else{ size_t i; for(i=0;i<disk_inode->count;i++) inode_delete(disk_inode->inode_index[i]); } free(disk_inode); } free_map_release(§or, 1); }
/* Closes INODE and writes it to disk. If this was the last reference to INODE, frees its memory. If INODE was also a removed inode, frees its blocks. */ void inode_close (struct inode *inode) { /* Ignore null pointer. */ if (inode == NULL) return; /* Release resources if this was the last opener. */ if (--inode->open_cnt == 0) { /* Remove from inode list and release lock. */ list_remove (&inode->elem); /* Deallocate blocks if removed. */ if (inode->removed) //inode is to be deleted { cache_remove(inode,SECTOR_NONE); inode_deallocate_data_blocks(inode); free_map_release (inode->sector, 1); //free_map_release (inode->data.start, bytes_to_sectors (inode->data.length)); free(inode); return; } cache_flush(inode,SECTOR_NONE); cache_remove(inode,SECTOR_NONE); free (inode); } }
/* Closes INODE and writes it to disk. If this was the last reference to INODE, frees its memory. If INODE was also a removed inode, frees its blocks. */ void inode_close (struct inode *inode) { if(INODE_DEBUG || FILE_DEBUG) printf("INODE: closing inode %u \n", inode->sector); if(INODE_PRINT) inode_print(inode); /* Ignore null pointer. */ if (inode == NULL) return; /* Release resources if this was the last opener. */ if (--inode->open_cnt == 0) { lock_acquire(&inode->lock); /* Remove from inode list and release lock. */ list_remove (&inode->elem); /* Deallocate blocks if removed. */ if (inode->removed) { if(INODE_DEBUG) printf("INODE: removing inode %u\n", inode->sector); /* truncate inode to size 0 */ inode_truncate(inode); /* release inode */ free_map_release (inode->sector, 1); } lock_release(&inode->lock); free (inode); } }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size,bool is_dir) { // printf("create start: %s\n",name); // printf("%s size: %d\n",name,initial_size); disk_sector_t inode_sector = 0; char *file_name = get_file_name(name); bool success=true; if( strcmp(file_name,"")==0 ) { return false; } // if( is_dir) // printf("mkdir!\n"); // printf("file name : %s\n",file_name); struct dir *dir = get_directory(name); // printf("sector of dir : %d\n", inode_get_inumber(dir_get_inode(dir))); // if( inode_get_parent(dir_get_inode(dir)) ==0 ) // { // printf("its on root directory!\n"); // } /* if(dir == NULL) { printf("no directory\n"); success=false; } if(!free_map_allocate(1,&inode_sector)) { printf("no free map\n"); success=false; } if(!inode_create(inode_sector,initial_size,is_dir)) { printf("inode create fail\n"); success=false; } if(!dir_add(dir,file_name,inode_sector)) { printf("dir add fail\n"); success=false; }*/ // printf("file name:%s\n",file_name); success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, is_dir) && dir_add (dir, file_name, inode_sector)); if (!success && inode_sector != 0) { // printf("haha\n"); free_map_release (inode_sector, 1); } dir_close (dir); // printf("create end sector num : %d\n",inode_sector); free(file_name); return success; }
/* padding zeros from start_pos (inclusive) to end_pos (exclusive) */ bool zero_padding(struct inode *inode, struct inode_disk *id, off_t start_pos, off_t end_pos) { ASSERT(lock_held_by_current_thread (&inode->inode_lock)); static char zeros[BLOCK_SECTOR_SIZE]; /* padding the first partial sector */ if (start_pos % BLOCK_SECTOR_SIZE != 0) { block_sector_t eof_sector = byte_to_sector(inode, start_pos-1); off_t sector_ofs = start_pos % BLOCK_SECTOR_SIZE; size_t zero_bytes = BLOCK_SECTOR_SIZE - sector_ofs; cache_write(eof_sector, zeros, sector_ofs, zero_bytes); } /* padding full sectors until end_pos-1 */ int extra_sectors = (int)bytes_to_sectors(end_pos)- (int)bytes_to_sectors(start_pos); off_t* record_sectors=malloc(sizeof(off_t) * extra_sectors); off_t i,j; block_sector_t new_sector=-1; for(i=0;i<extra_sectors;i++){ if (!free_map_allocate (1, &new_sector)) { for(j=0;j<i;j++){ free_map_release(record_sectors[i],1); } free(record_sectors); return false; } if(!append_sector_to_inode(id,new_sector)){ for(j=0;j<i;j++){ free_map_release(record_sectors[i],1); } free(record_sectors); return false; } cache_write(new_sector, zeros, 0, BLOCK_SECTOR_SIZE); record_sectors[i]=new_sector; id->length += BLOCK_SECTOR_SIZE; } /*update the physical length info*/ id->length=end_pos; cache_write(inode->sector, id, 0, BLOCK_SECTOR_SIZE); free(record_sectors); return true; }
static bool exit_now(struct inode_disk *disk_inode, off_t length){ size_t cur = bytes_to_sectors(length); size_t i,loop; // Direct loop = cur > 124 ? 0 : cur; for (i = loop; i < 124; i++){ free_map_release(disk_inode->start + i, 1); } disk_inode->length = length; return false; }
/*! Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create(const char *name, off_t initial_size) { block_sector_t inode_sector = 0; struct dir *dir = dir_open_root(); bool success = (dir != NULL && free_map_allocate(1, &inode_sector) && inode_create(inode_sector, initial_size) && dir_add(dir, name, inode_sector)); if (!success && inode_sector != 0) free_map_release(inode_sector, 1); dir_close(dir); return success; }
void dinode_free (struct inode_disk *dinode) { /* Free double indirect block */ while (dinode->dindir_cnt != 0) { struct indir_block d_block, block; block_read(fs_device, dinode->dindirect[dinode->dindir_cnt-1], &d_block); /* We've just got the level 1 block, so now we have to free the level 2 block. */ while (dinode->dindir_curr_usage != 0) { block_read(fs_device, d_block.ptr[dinode->dindir_curr_usage-1], &block); /* We've just got the level 2 block, so now we have to free the actual data block. */ while (dinode->dindir_lv2_curr_usage != 0) { free_map_release(block.ptr[dinode->dindir_lv2_curr_usage-1],1); dinode->dindir_lv2_curr_usage--; } /* erase the level 2 block */ free_map_release(d_block.ptr[dinode->dindir_curr_usage-1],1); dinode->dindir_curr_usage--; if(dinode->dindir_curr_usage != 0) dinode->dindir_lv2_curr_usage = INDIR_BLOCK_PTRS; } /* erase the level 1 block */ free_map_release(dinode->dindirect[dinode->dindir_cnt-1],1); dinode->dindir_cnt--; if(dinode->dindir_cnt != 0) dinode->dindir_curr_usage = INDIR_BLOCK_PTRS; } /* Free single indirect block */ while (dinode->indir_cnt != 0) { struct indir_block block; block_read(fs_device, dinode->indirect[dinode->indir_cnt-1], &block); while (dinode->indir_curr_usage != 0) { free_map_release(block.ptr[dinode->indir_curr_usage-1],1); dinode->indir_curr_usage--; } free_map_release(dinode->indirect[dinode->indir_cnt-1],1); dinode->indir_cnt--; if(dinode->indir_cnt != 0) dinode->indir_curr_usage = INDIR_BLOCK_PTRS; } while (dinode->dir_cnt != 0) { free_map_release (dinode->direct[dinode->dir_cnt-1],1); dinode->dir_cnt--; } }
/* Creates a file named NAME with the given INITIAL_SIZE.*/ bool filesys_create (const char *name, off_t initial_size, bool isdir) { if (strlen(name) == 0) return false; block_sector_t inode_sector = 0; struct dir *dir_ = filesys_get_dir(name); char *name_ = filesys_get_name(name); bool success = false; if (strcmp (name_, "") == 0) goto done; success = (dir_ && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size) && dir_add (dir_, name_, inode_sector, isdir)); struct inode *ninode = NULL; struct dir *ndir = NULL; bool success1 = true; if (success && isdir){ success1 = ((ninode = inode_open (inode_sector)) && (ndir = dir_open (ninode)) && dir_add (ndir, ".", inode_sector, true) && dir_add (ndir, "..",inode_get_inumber (dir_get_inode (dir_)), true)); } if (inode_sector != 0 && !success) free_map_release (inode_sector, 1); if (success && !success1) { success = false; printf("Failure: create dir: %s\n", name); dir_remove (dir_, name_); } done: dir_close (dir_); free(name_); if (!ndir && ninode){ inode_close(ninode); } else if (ndir) { dir_close(ndir); } return success; }
/* Free all blocks allocated for a given inode on close. */ static void close_blocks_for_inode (struct inode *inode) { unsigned i = 0, j = 0, k = 0; /* Free direct blocks. */ for(; i < DIRECT_BLOCKS; i++) { if (inode->data.blocks[i] == NO_BLOCK) break; free_map_release (inode->data.blocks[i], 1); } /* Free indirect blocks. */ block_sector_t data[INDIRECT_SIZE]; for (; j < INDIRECT_BLOCKS; j++) { block_sector_t block = inode->data.blocks[j + DIRECT_BLOCKS]; if (block == NO_BLOCK) break; block_read_cache (fs_device, block, data, 0, BLOCK_SECTOR_SIZE, true, data[j + DIRECT_BLOCKS + 1]); for (; k < INDIRECT_SIZE; k++) { if (data[k] == NO_BLOCK) break; free_map_release (data[k], 1); } free_map_release (inode->data.blocks[j + DIRECT_BLOCKS], 1); } /* Free doubly indirect blocks && related storage. */ if (inode->data.blocks[DIRECT_BLOCKS + INDIRECT_BLOCKS] != NO_BLOCK) { block_sector_t indirect_data[INDIRECT_SIZE]; block_read_cache (fs_device, inode->data.blocks[DIRECT_BLOCKS + INDIRECT_BLOCKS], indirect_data, 0, BLOCK_SECTOR_SIZE, true, -1); j = 0; k = 0; for (; j < INDIRECT_SIZE; j++) { block_sector_t indirect = indirect_data[j]; if (indirect == NO_BLOCK) break; block_read_cache (fs_device, indirect, data, 0, BLOCK_SECTOR_SIZE, true, (j == INDIRECT_SIZE - 1) ? NO_BLOCK : indirect_data[j + 1]); for (; k < INDIRECT_SIZE; k++) { if (indirect == NO_BLOCK) break; free_map_release (data[k], 1); } free_map_release (indirect, 1); } free_map_release (inode->data.blocks[DIRECT_BLOCKS + INDIRECT_BLOCKS], 1); } free_map_release (inode->sector, 1); }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *path, off_t initial_size) { char *name = get_filename (path); block_sector_t inode_sector = 0; struct dir *dir = dir_get (path); bool success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, false) && dir_add (dir, name, inode_sector)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); free (name); return success; }
/*! Creates the directory named dir. Return true if successful, but false * if dir already exists or if any directory name in dir, besides the last * one does not exist. */ bool _mkdir(const char* dir) { /* Inode for the new directory created. */ struct inode* next_inode; /* Parent directory. */ struct dir* cur_dir; /* Name of the directory. */ char name[15]; /* Sector number allocated to the new directory. */ block_sector_t sector; /* Check the validity of the pointer*/ if (!checkva(dir)) exit(-1); /* The compose the path to a final dir name and its parent directory. */ if (!decompose_dir(dir, name, &cur_dir)){ return false; } ASSERT(cur_dir != NULL); /* Allocate a new sector for this new directory; * Create a new directory */ if (!free_map_allocate(1, §or) || !dir_create(sector, 0, dir_get_inode(cur_dir)->sector)){ dir_close(cur_dir); return false; } /* Add the new directory to its parent directory. */ if (!dir_add(cur_dir, name, sector)){ free_map_release(sector, 1); dir_close(cur_dir); return false; } dir_close(cur_dir); return true; }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size) { block_sector_t inode_sector = 0; struct thread *cur = thread_current(); struct dir *dir; if(cur->current_directory == NULL) dir = dir_open_root (); else dir = dir_open_current(); bool success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, false) && dir_add (dir, name, inode_sector)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); return success; }
static void free_inode_blocks_rec (int level, block_sector_t b) { if (b == 0) return; if (level > 0) { size_t i; size_t unit = sizeof(block_sector_t); for (i = 0; i < DIRECT_ENTRY_CNT; i++) { block_sector_t nb; cache_read (fs_cache, b, &nb, unit * i, unit); free_inode_blocks_rec (level-1, nb); } } cache_remove (fs_cache, b, 1); free_map_release (b, 1); }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size) { char *cp_name = malloc( sizeof(char) * (strlen(name) + 1) ); char *file_name = malloc( sizeof(char) * (strlen(name) + 1) ); if( cp_name == NULL || file_name == NULL) return false; strlcpy(cp_name, name, strlen(name)+1); block_sector_t inode_sector = 0; struct dir *dir = parse_path (cp_name, file_name); bool success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, IS_FILE) && dir_add (dir, file_name, inode_sector)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); free(cp_name); free(file_name); return success; }