⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernel.c

📁 be文件系统实现的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -