static int inumber_handler (int fd) { struct file_struct * f = get_file(fd); if (f != NULL) { if (f->sys_dir != NULL) { return inode_get_inumber(dir_get_inode(f->sys_dir)); } else { return inode_get_inumber(file_get_inode(f->sys_file)); } } return -1; }
/* Formats the file system. */ static void do_format (void) { struct dir *root_dir = dir_open_root(); struct inode *root_inode = dir_get_inode(root_dir); printf ("Formatting file system..."); free_map_create (); if (!dir_create (ROOT_DIR_SECTOR, 16)) PANIC ("root directory creation failed"); /* add . and .. entry to root directory */ dir_add(root_dir, ".", inode_get_inumber(root_inode)); dir_add(root_dir,"..", inode_get_inumber(root_inode)); free_map_close (); printf ("done.\n"); }
int filesys_inumber (int fd) { struct file *file = file_find (fd); if (file == NULL) return false; struct inode *inode = file_get_inode (file); return inode_get_inumber (inode); }
bool dir_is_root (struct dir* dir) { if (!dir) { return false; } if (inode_get_inumber (dir_get_inode(dir)) == ROOT_DIR_SECTOR) { return true; } return false; }
/* get ondisk block sector */ uint32_t sys_inumber(int fd) { struct file *file = process_get_file(fd); struct inode *inode; if(file != NULL) { /* return ondisk block sector number */ inode = file_get_inode(file); return inode_get_inumber(inode); } /* if file is not exist, return -1*/ return -1; }
struct file_synch_status *status_for_inode (struct inode *inode) { if (inode_get_inumber (inode) == FREE_MAP_SECTOR) return &free_map_synch; lock_acquire (&(fm->file_map_lock)); struct fpm_info *start = fm->fp_map[hash_inode(inode)]; while (start) { if (start->inode == inode) break; start = start->next; } struct file_synch_status *retval = (start == NULL) ? add_dir_entry (inode) : &start->status; lock_release (&(fm->file_map_lock)); return retval; }
/* Adds a file named NAME to DIR, which must not already contain a file by that name. The file's inode is in sector INODE_SECTOR. Returns true if successful, false on failure. Fails if NAME is invalid (i.e. too long) or a disk or memory error occurs. */ bool dir_add (struct dir *dir, const char *name, block_sector_t inode_sector) { struct dir_entry e; off_t ofs; bool success = false; ASSERT (dir != NULL); ASSERT (name != NULL); inode_lock(dir_get_inode (dir)); /* Check NAME for validity. */ if (*name == '\0' || strlen (name) > NAME_MAX) { inode_unlock (dir_get_inode(dir)); return false; } /* Check that NAME is not in use. */ if (lookup (dir, name, NULL, NULL)) goto done; if (!inode_add_parent (inode_get_inumber (dir_get_inode(dir)),inode_sector)) { goto done; } /* Set OFS to offset of free slot. If there are no free slots, then it will be set to the current end-of-file. inode_read_at() will only return a short read at end of file. Otherwise, we'd need to verify that we didn't get a short read due to something intermittent such as low memory. */ for (ofs = 0; inode_read_at (dir->inode, &e, sizeof e, ofs) == sizeof e; ofs += sizeof e) if (!e.in_use) break; /* Write slot. */ e.in_use = true; strlcpy (e.name, name, sizeof e.name); e.inode_sector = inode_sector; success = inode_write_at (dir->inode, &e, sizeof e, ofs) == sizeof e; done: inode_unlock (dir_get_inode(dir)); return success; }
/* 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; }
/* Searches DIR for a file with the given NAME and returns true if one exists, false otherwise. On success, sets *INODE to an inode for the file, otherwise to a null pointer. The caller must close *INODE. */ bool dir_lookup (const struct dir *dir, const char *name, struct inode **inode) { struct dir_entry e; ASSERT (dir != NULL); if (name == NULL) *inode = inode_open (inode_get_inumber (dir->inode)); else if (lookup (dir, name, &e, NULL)) *inode = inode_open (e.inode_sector); else *inode = NULL; return *inode != NULL; }
bool filesys_chdir(const char *name) { bool success=false; struct inode *inode = NULL; struct thread *t = thread_current(); char *file_name = get_file_name(name); struct dir *dir = get_directory(name); // printf("lookup start\n"); if (dir != NULL) { if( strcmp(file_name,".")==0) { t->curr_dir = dir_reopen(dir); free(file_name); return true; } else if(strcmp(file_name,"..")==0) { if( inode_get_inumber(dir_get_inode(dir))==1 ) { t->curr_dir = dir_open(inode_open(1)); free(file_name); dir_close(dir); return true; } else { t->curr_dir = dir_open( inode_open(inode_get_parent(dir_get_inode(dir)))); free(file_name); dir_close(dir); return true; } } success=dir_lookup (dir, file_name, &inode); } dir_close (dir); if(success) { t->curr_dir = dir_open(inode); } free(file_name); /* printf("changed dir sector: %d\n",inode_get_inumber(dir_get_inode(t->curr_dir))); printf("value %d\n",inode_get_data(dir_get_inode(t->curr_dir),0));*/ return success; }
/* Returns inumber for file. */ int get_inumber (const char *file_name) { struct inode *inode = NULL; int inode_number; /* Root directory is special case. */ if (!strcmp (file_name, "/")) { return ROOT_DIR_SECTOR; } /* Look up file and get its inode. */ ASSERT (recursive_dir_lookup (file_name, &inode)); inode_number = inode_get_inumber (inode); inode_close (inode); return inode_number; }
bool filesys_chdir (const char *full_path) { char leaf_name[NAME_MAX + 1]; if (!dir_get_leaf_name (full_path, leaf_name)) return false; struct dir *parent_dir = dir_get_parent_dir (full_path); if (parent_dir == NULL) return false; struct inode *tmp; if (!dir_lookup (parent_dir, leaf_name, &tmp)) return false; if (!inode_is_dir (tmp)) return false; struct dir *actual_dir = dir_open (tmp); thread_current()->cwd_sector = inode_get_inumber(dir_get_inode (actual_dir)); dir_close (actual_dir); return true; }
/* create directory file */ bool filesys_create_dir(const char *name) { struct dir *parent_dir; struct inode *parent_inode; struct inode *tmp; struct dir *new_dir; bool result = false; /* if dir name is NULL, return false*/ if(name == NULL) return result; /* copy name to cp_name */ char *cp_name = malloc( sizeof(char) * (strlen(name)+1) ); strlcpy(cp_name, name, strlen(name)+1 ); char *file_name; file_name = malloc( sizeof(char) * (strlen(name)+1) ); if(file_name == NULL) { free(cp_name); return result; } parent_dir = parse_path(cp_name, file_name); /* if already same name file exist in directory, return false*/ if(dir_lookup(parent_dir, file_name, &tmp) == true) return result; /* allocate bitmap */ block_sector_t sector_idx; free_map_allocate(1, §or_idx); /* create directory */ dir_create(sector_idx, 16); /* add new entry to parent directory */ dir_add(parent_dir, file_name, sector_idx); /* add entry '.' and '..' to directory */ new_dir = dir_open( inode_open(sector_idx) ); dir_add(new_dir,".",sector_idx); parent_inode = dir_get_inode(parent_dir); dir_add(new_dir,"..", inode_get_inumber(parent_inode)); free(cp_name); free(file_name); result = true; return result; }
/* Returns inode for a file */ int file_inumber (struct file *file) { ASSERT (file != NULL); return inode_get_inumber (file->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, uint32_t is_dir) { block_sector_t inode_sector = (block_sector_t) -1; struct inode *inode = NULL; struct dir *search_dir = get_cwd(name); if (search_dir == NULL) { return false; } char *part = malloc(NAME_MAX + 1); if (part == NULL) { return false; } memset(part, 0, NAME_MAX + 1); int retrieved_next_part; for (retrieved_next_part = get_next_part(part, &name); retrieved_next_part > 0; retrieved_next_part = get_next_part(part, &name)) { if (dir_lookup (search_dir, part, &inode)) { if (!inode_is_dir(inode)) { break; } else { dir_close(search_dir); search_dir = dir_open(inode); if (search_dir == NULL) { free(part); return false; } } } else { inode = NULL; break; } } if (inode != NULL || get_next_part(part, &name) != 0) { if (inode != NULL && !inode_is_dir(inode)) { inode_close(inode); } dir_close(search_dir); free(part); return false; } bool success = false; if (is_dir) { block_sector_t parent_sector = inode_get_inumber(dir_get_inode(search_dir)); success = (search_dir != NULL && free_map_allocate (1, &inode_sector) && dir_create (inode_sector, initial_size, parent_sector) && dir_add (search_dir, part, inode_sector)); } else { success = (search_dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, is_dir) && dir_add (search_dir, part, inode_sector)); } if (!success) free_map_release (inode_sector, 1); dir_close (search_dir); free(part); 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) { char name_copy[MAX_FULL_PATH]; char *file_name = NULL; char *token, *save_ptr; block_sector_t inode_sector = 0; /* Null file name not allowed. */ if (name[0] == '\0') { return false; } if (strlen (name) > MAX_FULL_PATH) { return false; } /* Open parent directory. */ struct dir *dir = recursive_dir_open (name); if (!dir) { return false; } /* extract only file name from entire path. */ strlcpy (name_copy, name, strlen (name) + 1); for (token = strtok_r (name_copy, "/", &save_ptr); token != NULL; token = strtok_r (NULL, "/", &save_ptr)) { file_name = token; } if (file_name[0] == '\0') { dir_close (dir); return false; } if (strlen (file_name) > NAME_MAX) { dir_close (dir); return false; } /* Check for and prevent simultaneous accesses. */ struct list_elem *e; block_sector_t parent_dir_sector = inode_get_inumber (dir_get_inode (dir)); lock_acquire (&cur_name_list_lock); for (e = list_begin (&cur_name_list); e != list_end (&cur_name_list); e = list_next (e)) { struct cur_name_list_entry *cur_name_list_entry = NULL; cur_name_list_entry = list_entry (e, struct cur_name_list_entry, elem); if ((cur_name_list_entry->parent_dir_sector == parent_dir_sector) && (!strcmp (file_name, cur_name_list_entry->file_name))) { dir_close (dir); return false; } } struct cur_name_list_entry *name_entry = NULL; name_entry = malloc (sizeof (struct cur_name_list_entry)); if (name_entry == NULL) { dir_close (dir); lock_release (&cur_name_list_lock); return false; } strlcpy (name_entry->file_name, file_name, strlen (file_name) + 1); name_entry->parent_dir_sector = parent_dir_sector; list_push_back (&cur_name_list, &name_entry->elem); lock_release (&cur_name_list_lock); /* Create file. and add directory entry. */ bool success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size) && dir_add (dir, file_name, inode_sector, true)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); lock_acquire (&cur_name_list_lock); list_remove (&name_entry->elem); lock_release (&cur_name_list_lock); free (name_entry); return success; }
/* Deletes the file named NAME. Returns true if successful, false on failure. Fails if no file named NAME exists, or if an internal memory allocation fails. */ bool filesys_remove (const char *name) { char name_copy[MAX_FULL_PATH]; char *file_name = NULL; char *token = NULL, *save_ptr = NULL; struct dir *dir = NULL; /* Null name not allowed. */ if (name[0] == '\0') { return false; } /* Open parent directory. */ dir = recursive_dir_open (name); /* extract only file name from full path. */ strlcpy (name_copy, name, strlen (name) + 1); for (token = strtok_r (name_copy, "/", &save_ptr); token != NULL; token = strtok_r (NULL, "/", &save_ptr)) { file_name = token; } if (!file_name) { dir_close (dir); return false; } /* Check for and prevent simultaneous accesses. */ struct list_elem *e; block_sector_t parent_dir_sector = inode_get_inumber (dir_get_inode (dir)); lock_acquire (&cur_name_list_lock); for (e = list_begin (&cur_name_list); e != list_end (&cur_name_list); e = list_next (e)) { struct cur_name_list_entry *cur_name_list_entry = NULL; cur_name_list_entry = list_entry (e, struct cur_name_list_entry, elem); if ((cur_name_list_entry->parent_dir_sector == parent_dir_sector) && (!strcmp (file_name, cur_name_list_entry->file_name))) { dir_close (dir); return false; } } struct cur_name_list_entry *name_entry = NULL; name_entry = malloc (sizeof (struct cur_name_list_entry)); if (name_entry == NULL) { dir_close (dir); lock_release (&cur_name_list_lock); return false; } strlcpy (name_entry->file_name, file_name, strlen (file_name) + 1); name_entry->parent_dir_sector = parent_dir_sector; list_push_back (&cur_name_list, &name_entry->elem); lock_release (&cur_name_list_lock); /* Remove dirctory entry of file. */ bool success = dir != NULL && dir_remove (dir, file_name); dir_close (dir); lock_acquire (&cur_name_list_lock); list_remove (&name_entry->elem); lock_release (&cur_name_list_lock); free (name_entry); return success; }
static struct dir *get_directory(char *path) { char s[1024]; memcpy(s,path,strlen(path)+1); char *token, *save_ptr,*prev_token="", *next_token="";//,*save,*real; token = strtok_r(s,"/",&save_ptr); // real = strtok_r(token,"/",&save); struct dir *start; struct inode *inode; if( s[0]=='/' || !thread_current()->curr_dir ) { // printf("when create a/b\n"); start = dir_open_root(); } else { // printf("come on\n"); if( inode_is_removed(dir_get_inode(thread_current()->curr_dir))) return NULL; else start = dir_reopen(thread_current()->curr_dir); } /* if( strcmp(token,"." )==0) { } else if( strcmp(token,"..") == 0) { if( thread_current()->curr_dir) start = dir_get_parent(thread_current()->curr_dir); else start = dir_open_root(); } else { printf("here\n"); if(thread_current()->curr_dir) { // printf("also here\n"); start = dir_reopen(thread_current()->curr_dir); } else { // printf("when create a/b\n"); start = dir_open_root(); } }*/ // printf("first setting\n"); // real = strtok_r(token,"/",&save); // printf("token %s s %s\n",token,s); if(token) { next_token = strtok_r(NULL,"/",&save_ptr); /* if(next_token == NULL) printf("AAAA\n"); else printf("%s\n",next_token);*/ // printf("first %s second %s\n",token,next_token); } while( next_token!=NULL) { // printf("but not here\n"); if( strcmp(token,"." )==0) { continue; } else if( strcmp(token,"..") == 0) { if(inode_get_inumber(dir_get_inode(start))!=1) { start=dir_get_parent(start); } } else { if(dir_lookup(start ,token, &inode)) { // printf("when create a/b token:%s\n",token); // printf("aaaa\n"); dir_close(start); start = dir_open(inode); } else return NULL; // dir_close(start); /* if( inode==NULL ) { return NULL; } else if(inode_is_removed(inode)) return NULL;*/ // start = dir_open(inode); } prev_token = token; token = next_token; next_token = strtok_r(NULL,"/",&save_ptr); // printf("first %s second %s\n",token,next_token); } // printf("directory name : %s \n",token); return start; }
/* Returns the inumber associated with the underlying inode */ int file_inumber (struct file *file) { return inode_get_inumber(file->inode); }