/* Reads an inode from SECTOR and returns a `struct inode' that contains it. Returns a null pointer if memory allocation fails. */ struct inode * inode_open (block_sector_t sector) { struct list_elem *e; struct inode *inode; /* Check whether this inode is already open. */ for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { inode = list_entry (e, struct inode, elem); if (inode->sector == sector) { inode_reopen (inode); return inode; } } /* Allocate memory. */ inode = malloc (sizeof *inode); if (inode == NULL) return NULL; /* Initialize. */ list_push_front (&open_inodes, &inode->elem); inode->sector = sector; inode->open_cnt = 1; inode->deny_write_cnt = 0; inode->removed = false; cache_read (fs_cache, inode->sector, &inode->data, 0, BLOCK_SECTOR_SIZE); return inode; }
/* 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); ASSERT (name != NULL); //we have to stop / lookup in / if( strcmp(name,"/") == 0 && inode_id(dir->inode) == ROOT_DIR_SECTOR) *inode = inode_reopen(dir->inode); else { //lock the directory for the rest of the lookup operation inode_lock(dir->inode); name = getfilename(name); if (lookup (dir, name, &e, NULL)) *inode = inode_open (e.inode_sector); else *inode = NULL; //unlock the dir again inode_unlock(dir->inode); } return *inode != NULL; }
/* Reads an inode from SECTOR and returns a `struct inode' that contains it. Returns a null pointer if memory allocation fails. */ struct inode * inode_open (block_sector_t sector) { if(INODE_DEBUG || FILE_DEBUG) printf("INODE: opening inode %u\n", sector); struct list_elem *e; struct inode *inode; /* Check whether this inode is already open. */ for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { inode = list_entry (e, struct inode, elem); if (inode->sector == sector) { inode_reopen (inode); return inode; } } /* Allocate memory. */ inode = malloc (sizeof *inode); if (inode == NULL) return NULL; /* Initialize. */ list_push_front (&open_inodes, &inode->elem); inode->sector = sector; inode->open_cnt = 1; inode->deny_write_cnt = 0; inode->removed = false; lock_init(&inode->lock); return inode; }
/* Reads an inode from SECTOR and returns a `struct inode' that contains it. Returns a null pointer if memory allocation fails. */ struct inode * inode_open (block_sector_t sector) { struct list_elem *e; struct inode *inode; /* Check whether this inode is already open. */ for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { inode = list_entry (e, struct inode, elem); if (inode->sector == sector) { //printf("sector : %d has same sector\n",sector); inode_reopen (inode); return inode; } } /* Allocate memory. */ inode = malloc (sizeof *inode); if (inode == NULL) return NULL; /* Initialize. */ list_push_front (&open_inodes, &inode->elem); inode->sector = sector; inode->open_cnt = 1; inode->deny_write_cnt = 0; inode->removed = false; inode->extension = false; block_read (fs_device, inode->sector, &inode->data); return inode; }
struct inode * filesys_open_inode (const char *path, bool *is_directory) { struct dir *dir = NULL; struct inode *inode = 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; if (dir == NULL) goto done; /* open directory in this case */ if (*path != '\0' && strlen (name) == 0) { inode = inode_reopen (dir_get_inode (dir)); if (inode == NULL) goto done; *is_directory = true; } else if (!dir_lookup (dir, name, &inode, is_directory)) goto done; success = true; done: dir_close (dir); free (name); return success ? inode : NULL; }
/* Opens a directory */ struct dir *dir_open (size_t count, struct inode *inode, struct dir *directory_) { struct dir *dir = calloc (1, sizeof *dir); //open root directory if (count == 0) inode = inode_open (ROOT_DIR_SECTOR); //reopen a directory if (count == 1) inode = inode_reopen (directory_->inode); if (dir == NULL && inode == NULL) { inode_close (inode); free (dir); return NULL; } else { dir->pos = 0; dir->inode = inode; return dir; } }
void chdir (struct intr_frame *f) { const char * dirname = *(char **)value_stack(f->esp,4); //if empty or root return if(strlen(dirname) == 0 || strcmp( dirname, "/")) f->eax = 0; /* CLOSE FILE ? */ struct file * file = filesys_open(dirname); if ( file == NULL ) { f->eax = 0; return; } struct inode * myinode = file_get_inode (file); enum file_type type = inode_type (myinode); //if the file is a dir open it and set pwd to it if(type == FILE_DIR) { f->eax = 1; dir_close(thread_current()->pwd); thread_current()->pwd = dir_open(inode_reopen(myinode)); } else f->eax = 0; file_close(file); }
/* Opens the file with the given NAME. Returns the new file if successful or a null pointer otherwise. Fails if no file named NAME exists, or if an internal memory allocation fails. */ struct file * filesys_open (const char *name) { if (strnlen (name, FULLPATH_MAX_LEN) == 0) return NULL; if (strcmp (".", name) == 0) { block_sector_t cwd = thread_current ()->cwd_sector; struct inode *curr = NULL; curr = inode_open (cwd); struct dir *p; p = dir_open (inode_open (curr->data.parent_dir_sector)); struct dir_entry e; size_t ofs; ASSERT (p != NULL); for (ofs = 0; inode_read_at (p->inode, &e, sizeof e, ofs) == sizeof e; ofs += sizeof e) { if (e.inode_sector == cwd && e.in_use) { return filesys_open (e.name); } } return NULL; } struct inode *crr = NULL; crr = inode_open (thread_current ()->cwd_sector); struct dir *parent_dir = dir_reopen(dir_get_parent_dir (name)); //if (crr->data.is_dir) //parent_dir = dir_open (inode_open (crr->data.parent_dir_sector)); //else if (parent_dir == NULL) return NULL; struct inode *inode = NULL; char leaf_name[NAME_MAX + 1]; if (!dir_get_leaf_name (name, leaf_name) && strnlen(leaf_name, NAME_MAX) == 0) { inode = inode_reopen (dir_get_inode (parent_dir)); dir_close (parent_dir); return file_open (inode); } if (parent_dir != NULL) dir_lookup (parent_dir, leaf_name, &inode); dir_close (parent_dir); return file_open (inode); }
/* Opens the file with the given NAME. Returns the new file if successful or a null pointer otherwise. Fails if no file named NAME exists, or if an internal memory allocation fails. */ struct inode * filesys_open (const char *name) { struct dir *search_dir = get_cwd(name); if (search_dir == NULL) { return NULL; } struct inode *inode = NULL; if (name[0] == '/') { inode = dir_get_inode(search_dir); } 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 && inode_is_dir(inode) && get_next_part(part, &name) == 0) { inode = inode_reopen(inode); } dir_close(search_dir); if (inode != NULL && get_next_part(part, &name) != 0) { inode_close(inode); inode = NULL; } free(part); return inode; }
/* Reads an inode from SECTOR and returns a `struct inode' that contains it. Returns a null pointer if memory allocation fails. */ struct inode * inode_open (disk_sector_t sector) { struct list_elem *e; struct inode *inode; //Lock anyone else out of the inode list lock_acquire(&inode_list_lock); /* Check whether this inode is already open. */ for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { inode = list_entry (e, struct inode, elem); if (inode->sector == sector) { inode_reopen (inode); lock_release(&inode_list_lock); return inode; } } /* Allocate memory. */ inode = malloc (sizeof *inode); if (inode == NULL) { lock_release(&inode_list_lock); return NULL; } /* Initialize. */ inode->sector = sector; inode->open_cnt = 1; inode->deny_write_cnt = 0; inode->removed = false; disk_read (filesys_disk, inode->sector, &inode->data); lock_init(&inode->reader_writer_lock); lock_init(&inode->internal_lock); //Push the node into the list and unlock the list for other modifications list_push_front (&open_inodes, &inode->elem); lock_release(&inode_list_lock); return inode; }
/* Reads an inode from SECTOR and returns a `struct inode' that contains it. Returns a null pointer if memory allocation fails. */ struct inode * inode_open (disk_sector_t sector) { struct list_elem *e; struct inode *inode; /* Check whether this inode is already open. */ lock_acquire(&inode_list_lock); for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { inode = list_entry (e, struct inode, elem); if (inode->sector == sector) { inode_reopen (inode); lock_release(&inode_list_lock); return inode; } } /* Allocate memory. */ inode = malloc (sizeof *inode); if (inode == NULL) { return NULL; } list_push_front (&open_inodes, &inode->elem); /* Initialize. */ inode->sector = sector; inode->open_cnt = 1; inode->removed = false; inode->read_cnt = 0; lock_init(&inode->inode_lock); lock_init(&inode->read_lock); sema_init(&inode->semaphore,1); disk_read (filesys_disk, inode->sector, &inode->data); lock_release(&inode_list_lock); return inode; }
/* Removes any entry for NAME in DIR. Returns true if successful, false on failure, which occurs only if there is no file with the given NAME. */ bool dir_remove (struct dir *dir, const char *name) { struct dir_entry e; struct inode *inode = NULL; bool success = false; off_t ofs; ASSERT (dir != NULL); ASSERT (name != NULL); /* Find directory entry. */ if (!lookup (dir, name, &e, &ofs)) goto done; /* Open inode. */ inode = inode_open (e.inode_sector); if (inode == NULL) goto done; if(inode_is_dir(inode)){ struct dir *temp_dir = dir_open(inode_reopen(inode)); if(temp_dir == NULL){ inode_close(inode); goto done; } if(!dir_is_empty(temp_dir)){ dir_close(temp_dir); goto done; } dir_close(temp_dir); } /* Erase directory entry. */ e.in_use = false; if (inode_write_at (dir->inode, &e, sizeof e, ofs) != sizeof e) goto done; /* Remove inode. */ inode_remove (inode); success = true; done: inode_close (inode); return success; }
/* Reads an inode from SECTOR and returns a `struct inode' that contains it. Returns a null pointer if memory allocation fails. */ struct inode * inode_open (block_sector_t sector) { struct list_elem *e; struct inode *inode; /* Check whether this inode is already open. */ lock_acquire(&open_inodes_lock); for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { inode = list_entry (e, struct inode, elem); if (inode->sector == sector) { inode_reopen (inode); lock_release(&open_inodes_lock); return inode; } } lock_release(&open_inodes_lock); /* Allocate memory. */ inode = malloc (sizeof *inode); if (inode == NULL) return NULL; /* Initialize. */ ASSERT(!lock_held_by_current_thread (&open_inodes_lock)); lock_acquire(&open_inodes_lock); list_push_front (&open_inodes, &inode->elem); lock_release(&open_inodes_lock); inode->sector = sector; inode->open_cnt = 1; inode->deny_write_cnt = 0; inode->removed = false; lock_init(&inode->dir_lock); lock_init(&inode->inode_lock); /* retrieve inode_disk from sector */ struct inode_disk id; cache_read(inode->sector, INVALID_SECTOR_ID, &id, 0, BLOCK_SECTOR_SIZE); inode->readable_length = id.length; inode->is_dir = id.is_dir; return inode; }
/* 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); ASSERT (name != NULL); if (strcmp(name, ".") == 0) *inode = inode_reopen(dir->inode); else if(strcmp(name, "..") == 0) *inode = inode_open(inode_parent_number(dir->inode)); else if (lookup (dir, name, &e, NULL)) *inode = inode_open (e.inode_sector); else *inode = NULL; return *inode != NULL; }
int sys_open(const char* file) { // memory validation check_user((const uint8_t*) file); struct file* file_opened; struct file_desc* fd = palloc_get_page(0); if (!fd) { return -1; } lock_acquire (&filesys_lock); file_opened = filesys_open(file); if (!file_opened) { palloc_free_page (fd); lock_release (&filesys_lock); return -1; } fd->file = file_opened; //file save // directory handling struct inode *inode = file_get_inode(fd->file); if(inode != NULL && inode_is_directory(inode)) { fd->dir = dir_open( inode_reopen(inode) ); } else fd->dir = NULL; struct list* fd_list = &thread_current()->file_descriptors; if (list_empty(fd_list)) { // 0, 1, 2 are reserved for stdin, stdout, stderr fd->id = 3; } else { fd->id = (list_entry(list_back(fd_list), struct file_desc, elem)->id) + 1; } list_push_back(fd_list, &(fd->elem)); lock_release (&filesys_lock); return fd->id; }
/* Reads an inode from SECTOR and returns a `struct inode' that contains it. Returns a null pointer if memory allocation fails. */ struct inode * inode_open (block_sector_t sector) { printf("inode_open(%u)\n", sector); struct list_elem *e; struct inode *inode; /* Check whether this inode is already open. */ for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { printf("in inode_open()\n"); inode = list_entry (e, struct inode, elem); if (inode->sector == sector) { printf("inode_open(): inode found in open_inodes list\n"); inode_reopen (inode); return inode; } } /* Allocate memory. */ inode = malloc (sizeof *inode); if (inode == NULL){ printf("Could not create new inode\n"); return NULL; } /* Initialize. */ list_push_front (&open_inodes, &inode->elem); inode->sector = sector; inode->open_cnt = 1; inode->deny_write_cnt = 0; inode->removed = false; //inode->type=... cached_read (inode, inode->sector, &inode->data); //Assignment 4 printf("inode_open(): Successfully created new inode\n"); return inode; }
/* Reads an inode from SECTOR and returns a `struct inode' that contains it. Returns a null pointer if memory allocation fails. */ struct inode * inode_open (block_sector_t sector) { struct list_elem *e; struct inode *inode; /* Check whether this inode is already open. */ for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { inode = list_entry (e, struct inode, elem); if (inode->sector == sector) { inode_reopen (inode); return inode; } } /* Allocate memory. */ inode = malloc (sizeof *inode); if (inode == NULL) return NULL; /* Initialize. */ list_push_front (&open_inodes, &inode->elem); inode->sector = sector; inode->open_cnt = 1; inode->deny_write_cnt = 0; inode->removed = false; struct inode_disk inode_data; lock_init(&inode->inode_lock); block_read (fs_device, inode->sector, &inode_data); memcpy(inode-> indirect_table, data.indirect_table, BLOCK_SECTOR_SIZE); inode -> length = inode_data.length; inode -> first_level_index = inode_data.first_level_index; inode -> second_level_index = inode_data.second_level_index; return inode; }
/* Opens and returns a new file for the same inode as FILE. Returns a null pointer if unsuccessful. */ struct file * file_reopen (struct file *file) { return file_open (inode_reopen (file->inode)); }
/* Opens and returns a new directory for the same inode as DIR. Returns a null pointer on failure. */ struct dir * dir_reopen (struct dir *dir) { return dir_open (inode_reopen (dir->inode)); }
/*! Opens and returns a new file for the same inode as FILE. Returns a null pointer if unsuccessful. */ struct file * file_reopen(struct file *file) { ASSERT(file != NULL); return file_open(inode_reopen(file->inode)); }
/* Reads an inode from SECTOR and returns a `struct inode' that contains it. Returns a null pointer if memory allocation fails. */ struct inode * inode_open (block_sector_t sector) { struct list_elem *e; struct inode *inode; uint8_t buf[BLOCK_SECTOR_SIZE]; /* Check whether this inode is already open. */ lock_acquire (&inode_list_lock); for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { inode = list_entry (e, struct inode, elem); if (inode->sector == sector) { inode_reopen (inode); lock_release (&inode_list_lock); return inode; } } lock_release (&inode_list_lock); /* Allocate memory. */ inode = malloc (sizeof *inode); if (inode == NULL) return NULL; /* Initialize. */ block_read (fs_device, sector, buf); memcpy (inode, buf, sizeof (*inode)); if ( (inode->sector != sector) || (inode->magic) != INODE_MAGIC) { free (inode); return NULL; } lock_acquire (&inode_list_lock); //double check the inode hasn't been added by someone else struct inode *other_inode; for (e = list_begin (&open_inodes); e != list_end (&open_inodes); e = list_next (e)) { other_inode = list_entry (e, struct inode, elem); if (other_inode->sector == sector) { inode_reopen (other_inode); free (inode); lock_release (&inode_list_lock); return other_inode; } } // it hasn't been added by someone else. push onto list. list_push_front (&open_inodes, &inode->elem); lock_release (&inode_list_lock); inode->open_cnt = 1; inode->deny_write_cnt = 0; lock_init (&inode->extend_lock); lock_init (&inode->dir_lock); return inode; }