int vfs_open(char *path, uint32_t open_flags, struct inode **node_store) { bool can_write = 0; switch (open_flags & O_ACCMODE) { case O_RDONLY: break; case O_WRONLY: case O_RDWR: can_write = 1; break; default: return -E_INVAL; } if (open_flags & O_TRUNC) { if (!can_write) { return -E_INVAL; } } int ret; struct inode *dir, *node; if (open_flags & O_CREAT) { char *name; bool excl = (open_flags & O_EXCL) != 0; if ((ret = vfs_lookup_parent(path, &dir, &name)) != 0) { return ret; } ret = vop_create(dir, name, excl, &node); vop_ref_dec(dir); } else { ret = vfs_lookup(path, &node); } if (ret != 0) { return ret; } assert(node != NULL); if ((ret = vop_open(node, open_flags)) != 0) { vop_ref_dec(node); return ret; } vop_open_inc(node); if (open_flags & O_TRUNC) { if ((ret = vop_truncate(node, 0)) != 0) { vop_open_dec(node); vop_ref_dec(node); return ret; } } *node_store = node; return 0; }
int vfs_unlink(char *path) { int ret; char *name; struct inode *dir; if ((ret = vfs_lookup_parent(path, &dir, &name)) != 0) { return ret; } ret = vop_unlink(dir, name); vop_ref_dec(dir); return ret; }
int vfs_symlink(char *old_path, char *new_path) { int ret; char *new_name; struct inode *new_dir; if ((ret = vfs_lookup_parent(new_path, &new_dir, &new_name)) != 0) { return ret; } ret = vop_symlink(new_dir, new_name, old_path); vop_ref_dec(new_dir); return ret; }
int vfs_rename(char *old_path, char *new_path) { int ret; char *old_name, *new_name; struct inode *old_dir, *new_dir; if ((ret = vfs_lookup_parent(old_path, &old_dir, &old_name)) != 0) { return ret; } if ((ret = vfs_lookup_parent(new_path, &new_dir, &new_name)) != 0) { vop_ref_dec(old_dir); return ret; } if (old_dir->in_fs == NULL || old_dir->in_fs != new_dir->in_fs) { ret = -E_XDEV; } else { ret = vop_rename(old_dir, old_name, new_dir, new_name); } vop_ref_dec(old_dir); vop_ref_dec(new_dir); return ret; }
error_t vfs_lookup_elem(struct vfs_lookup_s *lkp, struct vfs_lookup_response_s *lkr, char* name) { char isDot; char isRoot; char isDotDot; struct task_s *task; vfs_dmsg(1, "%s : lookup element = %s\n", __FUNCTION__, name); task = current_task; isRoot = ((name[0] == '/') && (name[1] == '\0')); isDot = ((name[0] == '.') && (name[1] == '\0')); isDotDot = ((name[0] == '.') && (name[1] == '.')) ? 1 : 0; lkr->err = 0; if(isRoot) { lkr->inode = task->vfs_root.f_inode; return 0; } /* if the requested element is a dot path or the parent of root * return the current parent */ if(isDot || (isDotDot && VFS_INODE_REF_COMPARE(lkp->current, task->vfs_root.f_inode))) { lkr->inode = lkp->current; return 0; } if(isDotDot) vfs_lookup_parent(lkr, lkp); else vfs_lookup_child(lkr, lkp, name); return 0; }
void dev_init(void) { init_device(null); init_device(stdin); init_device(stdout); init_device(disk0); /* for Nand flash */ init_device(disk1); init_device(tty); //init_device(ashmem); // link such as stdout int ret; char *new_name; struct inode *old_node, *new_dir; if ((ret = vfs_lookup("stdout:", &old_node)) != 0) { kprintf("erho"); return;// ret; } if ((ret = vfs_lookup_parent("/dev", &new_dir, &new_name)) != 0) { vop_ref_dec(old_node); return;// ret; } // if (old_node->in_fs == NULL || old_node->in_fs != new_dir->in_fs) { // ret = -E_XDEV; // } // else { ret = vop_link(new_dir, new_name, old_node); kprintf("odife%d\n", ret); // } vop_ref_dec(old_node); vop_ref_dec(new_dir); }
errno_t sc_open(thread_t *p, syscall_result_t *r, sc_open_args *arg) { int fd; int flags = arg->flags; int error = 0; vnode_t *node; proc_t *proc = p->thr_proc; char fname[PATH_MAX+1]; if((error = copyinstr(fname, arg->fname, PATH_MAX))) return error; KASSERT(proc->p_rootdir!=NULL); error = vfs_lookup(proc->p_curdir, &node, fname, p, LKP_NORMAL); if(error) { if(!(flags & O_CREAT)) return error; vnode_t *parent; error = vfs_lookup_parent(proc->p_curdir, &parent, fname, p); if(error) return error; if((error = VOP_ACCESS(parent, W_OK, proc->p_cred))) { vrele(parent); return error; } vattr_t attr; attr.va_mode = arg->mode & ~(proc->p_umask) & 0777; attr.va_type = VNODE_TYPE_REG; attr.va_uid = proc->p_cred->p_uid; attr.va_gid = proc->p_cred->p_gid; attr.va_size = 0; attr.va_dev = NULL; error = VOP_CREATE(parent, &node, _get_last_cmpt(fname), &attr); VOP_UNLOCK(parent); if(error) return error; VOP_LOCK(node); } else { //plik istnieje if((flags & O_CREAT) && (flags & O_EXCL)) { vrele(node); return -EEXIST; } if((node->v_type == VNODE_TYPE_DIR) && (flags & (O_RDWR | O_WRONLY))) { vrele(node); return -EISDIR; } } int wmode = (flags & O_RDWR) ? (W_OK | R_OK) : (flags & O_RDONLY) ? (R_OK) : (W_OK); if((error = VOP_ACCESS(node, wmode, proc->p_cred))) { vrele(node); return error; } if((error = VOP_OPEN(node, flags, arg->mode))) { vrele(node); return error; } if(ISSET(flags, O_RDWR | O_WRONLY) && ISSET(flags, O_TRUNC) && node->v_type == VNODE_TYPE_REG) VOP_TRUNCATE(node, 0); if((error = f_alloc(proc, node, flags, &fd))) { vrele(node); // <- powinno to tutaj być, dopisałem bo nie było. return error; } VOP_UNLOCK(node); r->result = fd; return 0; }