?? kernel.c
字號:
sz = bufsize; err = (*op)(vn->ns->data, vn->data, buf, &sz); if (err) goto error2; dec_vnode(vn, FALSE); return sz;error2: dec_vnode(vn, FALSE);error1: return err;}/* * sys_mkdir */intsys_mkdir(bool kernel, int fd, const char *path, int perms){ int err; char filename[FILE_NAME_LENGTH]; vnode *dvn; op_mkdir *op; err = get_dir_fd(kernel, fd, path, filename, &dvn); if (err) goto error1; op = dvn->ns->fs->ops.mkdir; if (!op) { err = EINVAL; goto error2; } err = (*op)(dvn->ns->data, dvn->data, filename, perms); if (err) goto error2; dec_vnode(dvn, FALSE); return 0;error2: dec_vnode(dvn, FALSE);error1: return err;}/* * opendir. */intsys_opendir(bool kernel, int fd, const char *path, bool coe){ int err; op_opendir *op; op_free_cookie *opf; ofile *f; int nfd; vnode *vn; void *cookie; err = get_file_fd(kernel, fd, path, TRUE, &vn); if (err) goto error1; op = vn->ns->fs->ops.opendir; if (!op) { err = EINVAL; goto error2; } err = (*op)(vn->ns->data, vn->data, &cookie); if (err) goto error2; /* find a file descriptor */ f = (ofile *) calloc(sizeof(ofile), 1); if (!f) { err = ENOMEM; goto error3; } f->type = FD_DIR; f->vn = vn; f->cookie = cookie; f->rcnt = 0; f->ocnt = 0; nfd = new_fd(kernel, -1, f, -1, coe); if (nfd < 0) { err = EMFILE; goto error4; } return nfd;error4: free(f);error3: (*vn->ns->fs->ops.closedir)(vn->ns->data, vn->data, cookie); opf = vn->ns->fs->ops.free_dircookie; if (opf) (*opf)(vn->ns->data, vn->data, cookie);error2: dec_vnode(vn, FALSE);error1: if (err > 0) /* XXXdbg -- a hack for linux */ err = -err; return err;}/* * closedir */intsys_closedir(bool kernel, int fd){ return remove_fd(kernel, fd, FD_DIR);}/* * readdir. */intsys_readdir(bool kernel, int fd, struct my_dirent *buf, size_t bufsize, long count){ ofile *f; int err; vnode *vn; struct my_dirent *p; struct my_stat st; long i; nspace_id nsid; vnode_id vnid; long nm; f = get_fd(kernel, fd, FD_DIR); if (!f) { err = EBADF; goto error1; } vn = f->vn; nm = count; err = (*vn->ns->fs->ops.readdir)(vn->ns->data, vn->data, f->cookie, &nm, buf, bufsize); if (err) goto error1; /* patch the mount points and the root. */ LOCK(vnlock); nsid = vn->ns->nsid; p = buf; for(i=0; i<nm; i++) { if (is_mount_vnid(nsid, p->d_ino, &vnid)) p->d_ino = vnid; if (vn->ns->mount && !strcmp(p->d_name, "..")) { UNLOCK(vnlock); err = sys_rstat(kernel, fd, "..", &st, FALSE); if (err) goto error2; LOCK(vnlock); p->d_ino = st.ino; } p = (struct my_dirent *) ((char *) p + p->d_reclen); } UNLOCK(vnlock); put_fd(f); return nm;error2: put_fd(f);error1: return err;}/* * rewinddir */intsys_rewinddir(bool kernel, int fd){ ofile *f; int err; vnode *vn; f = get_fd(kernel, fd, FD_DIR); if (!f) return EBADF; vn = f->vn; err = (*vn->ns->fs->ops.rewinddir)(vn->ns->data, vn->data, f->cookie); put_fd(f); return err;}/* * open/create files. */intsys_open(bool kernel, int fd, const char *path, int omode, int perms, bool coe){ int err; char filename[FILE_NAME_LENGTH]; vnode *vn, *dvn; vnode_id vnid; void *cookie; ofile *f; int nfd; fdarray *fds; op_create *opc; op_open *opo; op_free_cookie *opf; if (omode & O_CREAT) { err = get_dir_fd(kernel, fd, path, filename, &dvn); if (err) goto errorA; opc = dvn->ns->fs->ops.create; if (!opc) { err = EINVAL; goto errorB; } err = (*opc)(dvn->ns->data, dvn->data, filename, omode, perms, &vnid, &cookie); if (err) goto errorB; LOCK(vnlock); vn = lookup_vnode(dvn->ns->nsid, vnid); UNLOCK(vnlock); dec_vnode(dvn, FALSE); } else { err = get_file_fd(kernel, fd, path, TRUE, &vn); if (err) goto error1; opo = vn->ns->fs->ops.open; if (!opo) { err = EINVAL; goto error2; } err = (*opo)(vn->ns->data, vn->data, omode, &cookie); if (err) goto error2; } /* find a file descriptor */ f = (ofile *) calloc(sizeof(ofile), 1); if (!f) { err = ENOMEM; goto error3; } f->type = FD_FILE; f->vn = vn; f->cookie = cookie; f->ocnt = 0; f->rcnt = 0; f->pos = 0; f->omode = omode; nfd = new_fd(kernel, -1, f, -1, coe); if (nfd < 0) { err = EMFILE; goto error4; } return nfd;error4: free(f);error3: (*vn->ns->fs->ops.close)(vn->ns->data, vn->data, cookie); opf = vn->ns->fs->ops.free_cookie; if (opf) (*opf)(vn->ns->data, vn->data, cookie); if (omode & O_CREAT) goto errorC;error2: dec_vnode(vn, FALSE);error1: return err;errorC: (*vn->ns->fs->ops.unlink)(dvn->ns->data, dvn->data, filename); dec_vnode(vn, FALSE);errorB: dec_vnode(dvn, FALSE);errorA: if (err > 0) /* XXXdbg -- a hack for linux */ err = -err; return err;}/* * sys_close */intsys_close(bool kernel, int fd){ return remove_fd(kernel, fd, FD_FILE);}/* * sys_lseek */fs_off_tsys_lseek(bool kernel, int fd, fs_off_t pos, int whence){ ofile *f; int err; struct my_stat st; vnode *vn; op_rstat *op; f = get_fd(kernel, fd, FD_FILE); if (!f) { err = EBADF; goto error1; } switch(whence) { case SEEK_SET: f->pos = pos; break; case SEEK_CUR: if ((f->omode & O_APPEND) == 0) f->pos += pos; else { /* we're in append mode so ask where the EOF is */ vn = f->vn; op = vn->ns->fs->ops.rstat; if (!op) { err = EINVAL; goto error2; } err = (*op)(vn->ns->data, vn->data, &st); if (err) goto error2; pos += st.size; f->pos = pos; break; } break; case SEEK_END: vn = f->vn; op = vn->ns->fs->ops.rstat; if (!op) { err = EINVAL; goto error2; } err = (*op)(vn->ns->data, vn->data, &st); if (err) goto error2; pos += st.size; f->pos = pos; break; default: put_fd(f); return EINVAL; } if (f->pos < 0) { f->pos = 0; err = EINVAL; goto error2; } pos = f->pos; put_fd(f); return pos;error2: put_fd(f);error1: return err;}/* * sys_read */ssize_tsys_read(bool kernel, int fd, void *buf, size_t len){ ofile *f; int err; vnode *vn; size_t sz; f = get_fd(kernel, fd, FD_FILE); if (!f) { err = EBADF; goto error1; } if ((f->omode & OMODE_MASK) == O_WRONLY) { err = EBADF; goto error2; } vn = f->vn; sz = len; err = (*vn->ns->fs->ops.read)(vn->ns->data, vn->data, f->cookie, f->pos, buf, &sz); if (err) goto error2; /* the update of f->pos is not protected. does it matter? simultaneous I/Os on the same file are unpredictable anyway. */ f->pos += sz; put_fd(f); return sz;error2: put_fd(f); error1: return err;}/* * sys_write */ssize_tsys_write(bool kernel, int fd, void *buf, size_t len){ ofile *f; int err; vnode *vn; size_t sz; f = get_fd(kernel, fd, FD_FILE); if (!f) { err = EBADF; goto error1; } if ((f->omode & OMODE_MASK) == O_RDONLY) { err = EBADF; goto error2; } vn = f->vn; sz = len; err = (*vn->ns->fs->ops.write)(vn->ns->data, vn->data, f->cookie, f->pos, buf, &sz); if (err) goto error2; /* the update of f->pos is not protected. does it matter? simultaneous I/Os on the same file are unpredictable anyway. */ f->pos += sz; put_fd(f); return sz;error2: put_fd(f); error1: return err;}/* * sys_ioctl */intsys_ioctl(bool kernel, int fd, int cmd, void *arg, size_t sz){ ofile *f; int err; vnode *vn; op_ioctl *op; f = get_fd(kernel, fd, FD_FILE); if (!f) { err = EBADF; goto error1; } vn = f->vn; op = vn->ns->fs->ops.ioctl; if (op) err = (*op)(vn->ns->data, vn->data, f->cookie, cmd, arg, sz); else err = EINVAL; if (err) goto error2; put_fd(f); return 0;error2: put_fd(f);error1: return err;}/* * sys_link */intsys_link(bool kernel, int ofd, const char *oldpath, int nfd, const char *newpath){ int err; vnode *vn, *dvn; char filename[FILE_NAME_LENGTH]; op_link *op; err = get_file_fd(kernel, ofd, oldpath, TRUE, &vn); if (err) goto error1; err = get_dir_fd(kernel, nfd, newpath, filename, &dvn); if (err) goto error2; if (vn->ns != dvn->ns) { err = EXDEV; goto error3; } op = dvn->ns->fs->ops.link; if (!op) { err = EINVAL; goto error3; } err = (*op)(dvn->ns->data, dvn->data, filename, vn->data); if (err) goto error3; dec_vnode(dvn, FALSE); dec_vnode(vn, FALSE); return 0;error3: dec_vnode(dvn, FALSE);error2: dec_vnode(vn, FALSE);error1: return err;}/* * sys_unlink */intsys_unlink(bool kernel, int fd, const char *path){ int err; vnode *dvn; char filename[FILE_NAME_LENGTH]; op_unlink *op; err = get_dir_fd(kernel, fd, path, filename, &dvn); if (err) goto error1; op = dvn->ns->fs->ops.unlink; if (!op) { err = EINVAL; goto error2; } err = (*op)(dvn->ns->data, dvn->data, filename); if (err) goto error2; dec_vnode(dvn, FALSE); return 0;error2: dec_vnode(dvn, FALSE);error1: return err;}/* * sys_rmdir */intsys_rmdir(bool kernel, int fd, const char *path){ int err; vnode *dvn; char filename[FILE_NAME_LENGTH]; op_unlink *op; err = get_dir_fd(kernel, fd, path, filename, &dvn); if (err) goto error1; op = dvn->ns->fs->ops.rmdir; if (!op) { err = EINVAL; goto error2; } err = (*op)(dvn->ns->data, dvn->data, filename); if (err) goto error2; dec_vnode(dvn, FALSE); return 0;error2: dec_vnode(dvn, FALSE);error1: return err;}/* * sys_rename */intsys_rename(bool kernel, int ofd, const char *oldpath, int nfd, const char *newpath){ int err; char newname[FILE_NAME_LENGTH], oldname[FILE_NAME_LENGTH]; vnode *odvn, *ndvn; op_rename *op; err = get_dir_fd(kernel, ofd, oldpath, oldname, &odvn); if (err) goto error1; err = get_dir_fd(kernel, nfd, newpath, newname, &ndvn); if (err) goto error2; if (odvn->ns != ndvn->ns) { err = EXDEV; goto error2; } op = odvn->ns->fs->ops.rename; if (!op) { err = EINVAL; goto error3; } err = (*op)(odvn->ns->data, odvn->data, oldname, ndvn->data, newname); if (err) goto error3; dec_vnode(odvn, FALSE); dec_vnode(ndvn, FALSE); return 0;error3: dec_vnode(ndvn, FALSE);error2: dec_vnode(odvn, FALSE);error1: return err;}/* * sys_rstat */intsys_rstat(bool kernel, int fd, const char *path, struct my_stat *st, bool eatlink){ int err; vnode *vn; op_rstat *op; err = get_file_fd(kernel, fd, path, eatlink, &vn); if (err) goto error1; op = vn->ns->fs->ops.rstat; if (!op) { err = EINVAL; goto error2; } err = (*op)(vn->ns->data, vn->data, st); if (err) goto error2; dec_vnode(vn, FALSE); return 0;error2: dec_vnode(vn, FALSE);error1: return err;}/* * sys_wstat */intsys_wstat(bool kernel, int fd, const char *path, struct my_stat *st, long mask, bool eatlink){ int err; vnode *vn; op_wstat *op; err = get_file_fd(kernel, fd, path, eatlink, &vn); if (err)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -