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

📄 rootfs.c

📁 be文件系统实现的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    l = strlen(node->symlink);    if (l > *bufsize)        memcpy(buf, node->symlink, *bufsize);    else        memcpy(buf, node->symlink, l);    *bufsize = l;    return 0;error1:    return err;}static introotfs_opendir(void *_ns, void *_node, void **cookie){    nspace      *ns;    vnode       *node;    int         err;    dirpos      *pos;    ns = (nspace *) _ns;    node = (vnode *) _node;    if (!MY_S_ISDIR(node->mode)) {        err = ENOTDIR;        goto error1;    }    pos = (dirpos *) malloc(sizeof(dirpos));    if (!pos) {        err = ENOMEM;        goto error1;    }    if (new_lock(&pos->lock, "rootdirlock") < 0) {        err = EINVAL;        goto error2;    }    pos->pos = 0;    pos->name[0] = '\0';    *cookie = pos;    return 0;error2:    free(pos);error1:    return err;}static introotfs_closedir(void *_ns, void *_node, void *_cookie){    return 0;}static introotfs_free_dircookie(void *_ns, void *_node, void *_cookie){    nspace      *ns;    vnode       *node;    dirpos      *cookie;    ns = (nspace *) _ns;    node = (vnode *) _node;    cookie = (dirpos *) _cookie;    free_lock(&cookie->lock);    free(cookie);    return 0;}static introotfs_rewinddir(void *_ns, void *_node, void *_cookie){    nspace      *ns;    vnode       *node;    dirpos      *cookie;    ns = (nspace *) _ns;    node = (vnode *) _node;    cookie = (dirpos *) _cookie;    LOCK(cookie->lock);    cookie->pos = 0;    cookie->name[0] = '\0';    UNLOCK(cookie->lock);    return 0;}static introotfs_readdir(void *_ns, void *_node, void *_cookie, long *num,                    struct my_dirent *buf, size_t bufsize){    nspace              *ns;    vnode               *node;    dirpos              *cookie;    char                *e, *q;    struct my_dirent    *p;    long                 i;    vnode               *vn;    vnode_id             vnid;    char                *name, *last;    int                  sl, rl;    ns = (nspace *) _ns;    node = (vnode *) _node;    cookie = (dirpos *) _cookie;    LOCK(ns->lock);    LOCK(cookie->lock);    vn = node->head;    p = (struct my_dirent *) buf;    e = (char *) buf + bufsize;    if (cookie->pos > 2)        while (vn && (strcmp(cookie->name, vn->name) >= 0))            vn = vn->next;    for(i=0; (i < *num) && ((cookie->pos < 2) || vn); i++, cookie->pos++) {        switch(cookie->pos) {        case 0:            name = ".";            vnid = node->vnid;            break;        case 1:            name = "..";            vnid = node->parent->vnid;            break;        default:            name = vn->name;            vnid = vn->vnid;            vn = vn->next;            break;        }        sl = strlen(name) + 1;        rl = sizeof(struct my_dirent) + sl - 1;        if ((char *)p + rl > e)            break;        last = name;        p->d_reclen = (rl + 7) & ~7;        p->d_ino = vnid;        memcpy(p->d_name, name, sl);        p = (struct my_dirent *)((char *)p + p->d_reclen);    }    if ((cookie->pos > 2) && (i > 0))        strcpy(cookie->name, last);    *num = i;exit:    UNLOCK(cookie->lock);    UNLOCK(ns->lock);    return 0;}static introotfs_rstat(void *_ns, void *_node, struct my_stat *st){    nspace      *ns;    vnode       *node;    ns = (nspace *) _ns;    node = (vnode *) _node;    LOCK(ns->lock);    st->dev = ns->nsid;    st->ino = node->vnid;    st->mode = node->mode;    st->nlink = 1;    st->uid = node->uid;    st->gid = node->gid;    st->size = 0;    st->blksize = 0;    st->atime = st->ctime = st->mtime = node->mtime;    UNLOCK(ns->lock);    return 0;}static introotfs_wstat(void *_ns, void *_node, struct my_stat *st, long mask){    nspace      *ns;    vnode       *node;    ns = (nspace *) _ns;    node = (vnode *) _node;    if (mask & WSTAT_SIZE)        return EINVAL;    LOCK(ns->lock);    if (mask & WSTAT_MODE)        node->mode = (node->mode & MY_S_IFMT) | (st->mode & ~MY_S_IFMT);    if (mask & WSTAT_UID)        node->uid = st->uid;    if (mask & WSTAT_GID)        node->gid = st->gid;    if (mask & WSTAT_MTIME)        node->mtime = st->mtime;    if (mask & WSTAT_ATIME)        node->mtime = st->atime;    UNLOCK(ns->lock);    return 0;}static introotfs_mount(nspace_id nsid, const char *device, ulong flags, void *parms,        size_t len, void **data, vnode_id *vnid){    int             err;    nspace          *ns;    vnode           *root;    vnode_id        rvnid;    if (device || parms || (len != 0)) {        err = EINVAL;        goto error1;    }    ns = (nspace *) malloc(sizeof(nspace));    if (!ns) {        err = ENOMEM;        goto error1;    }    root = (vnode *) malloc(sizeof(vnode));    if (!root) {        err = ENOMEM;        goto error2;    }    rvnid = 1;    ns->nsid = nsid;    ns->vnnum = 0;    ns->nxvnid = rvnid;    ns->root = root;    if (new_lock(&ns->lock, "rootfs") < 0) {        err = -1;        goto error3;    }    ns->skiplist = NewSL(&compare_vnode, NULL, NO_DUPLICATES);    if (!ns->skiplist) {        err = -1;        goto error4;    }    root->vnid = rvnid;    root->parent = root;    root->ns = ns;    root->removed = FALSE;    root->name = NULL;    root->next = root->prev = NULL;    root->head = NULL;    root->symlink = NULL;    /* ### do it for real */    root->uid = 0;    root->gid = 0;    root->mode = MY_S_IFDIR | 0777;    root->mtime = time(NULL);    err = new_vnode(nsid, rvnid, root);    if (err)        goto error5;    *data = ns;    *vnid = rvnid;    return 0;error5:    FreeSL(ns->skiplist);error4:    free_lock(&ns->lock);error3:    free(root);error2:    free(ns);error1:    return err;}static introotfs_unmount(void *_ns){    nspace      *ns;    vnode       *vn, *avn;    ns = (nspace *) _ns;    vn = ns->root;    while (TRUE) {        while(vn->head)            vn = vn->head;        vn = vn->parent;        if (vn == ns->root)            break;        avn = vn->head;        if (avn->prev)            avn->prev->next = avn->next;        else            vn->head = avn->next;        if (avn->next)            avn->next->prev = avn->prev;        rootfs_remove_vnode(ns, avn, TRUE);    }    free(ns->root);    free_lock(&ns->lock);    FreeSL(ns->skiplist);    free(ns);    return 0;}/* ### should do real permission check */static introotfs_access(void *_ns, void *_node, int mode){    return 0;}static intcompare_vnode(vnode *vna, vnode *vnb){    if (vna->vnid > vnb->vnid)        return 1;    else        if (vna->vnid < vnb->vnid)            return -1;        else            return 0;}static intdo_create(nspace *ns, vnode *dir, const char *name, mode_t mode, vnode **vnp){    int         err;    int         c;    vnode       *vn, *pvn, *nvn;    char        *buf;    vnode_id    vnid;    if (!MY_S_ISDIR(dir->mode)) {        err = ENOTDIR;        goto error1;    }        /*    make sure we are not trying to create something in a directory    that has been removed.    */    if (dir->removed) {        err = ENOENT;        goto error1;    }    /*    filter the name:    can't be '.', or '..'    */    if (!strcmp(name, ".") || !strcmp(name, "..")) {        err = EEXIST;        goto error1;    }            /*    lookup the name in the directory            */    vn = dir->head;    while (vn) {        c = strcmp(name, vn->name);        if (c < 0)            vn = NULL;        if (c <= 0)            break;        vn = vn->next;    }        /*    if it was found, report an error.    */    if (vn) {        err = EEXIST;        goto error1;    }    /*    allocate a vnode and fill it    */    vn = NULL;    buf = NULL;    vn = (vnode *) malloc(sizeof(vnode));    buf = (char *) malloc(strlen(name)+1);    if (!vn || !buf) {        err = ENOMEM;        goto error2;    }    strcpy(buf, name);    vnid = ++ns->nxvnid;    vn->vnid = vnid;    vn->parent = dir;    vn->ns = ns;    vn->removed = FALSE;    vn->name = buf;    vn->mode = mode;    vn->uid = 0;    vn->gid = 0;    dir->mtime = vn->mtime = time(NULL);    pvn = NULL;    nvn = dir->head;    while (nvn && (strcmp(name, nvn->name) > 0)) {        pvn = nvn;        nvn = nvn->next;    }    vn->next = nvn;    if (nvn)        nvn->prev = vn;    vn->prev = pvn;    if (pvn)        pvn->next = vn;    else        dir->head = vn;    vn->head = NULL;    vn->symlink = NULL;    atomic_add(&ns->vnnum, 1);    InsertSL(ns->skiplist, vn);    *vnp = vn;    return 0;error2:    if (vn)        free(vn);    if (buf)        free(buf);error1:    return err;}static intdo_unlink(nspace *ns, vnode *dir, const char *name, bool isdir){    int         err;    vnode       *vn;    LOCK(ns->lock);    if (!MY_S_ISDIR(dir->mode)) {        err = ENOTDIR;        goto error1;    }        /*    can't delete '..' and '.'    */    if (!strcmp(name, "..") || !strcmp(name, ".")) {        err = EINVAL;        goto error1;    }            /*    lookup the name in the directory            */    vn = dir->head;    while (vn) {        if (!strcmp(vn->name, name))            break;        vn = vn->next;    }        /*    if it was not found, report an error.    */    if (!vn) {        err = ENOENT;        goto error1;    }    /*    ensure it is of the appropriate type.    */    if (isdir && !(vn->mode & MY_S_IFDIR)) {        err = ENOTDIR;        goto error1;    }    if (!isdir && (vn->mode & MY_S_IFDIR)) {        err = EISDIR;        goto error1;    }            /*    make sure it is not the root    */    if (vn == vn->ns->root) {        err = EBUSY;        goto error1;    }    /*    if it is a directory, make sure it is empty    */    if (MY_S_ISDIR(vn->mode) && vn->head) {        err = ENOTEMPTY;        goto error1;    }    err = get_vnode(ns->nsid, vn->vnid, (void *)&vn);    if (err)        goto error1;    err = remove_vnode(ns->nsid, vn->vnid);    if (err)        goto error1;    if (vn->prev)        vn->prev->next = vn->next;    else        vn->parent->head = vn->next;    if (vn->next)        vn->next->prev = vn->prev;    vn->prev = vn->next = NULL;    vn->removed = TRUE;    dir->mtime = time(NULL);    put_vnode(ns->nsid, vn->vnid);    UNLOCK(ns->lock);    return 0;error1:    UNLOCK(ns->lock);    return err;}

⌨️ 快捷键说明

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