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

📄 kernel.c

📁 be文件系统实现的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    vn->ns->vnodes.head = vn;    return 0;}static voidmove_vnode(vnode *vn, int list){    if (vn->list.prev)        vn->list.prev->list.next = vn->list.next;    else        lists[vn->inlist].head = vn->list.next;    if (vn->list.next)        vn->list.next->list.prev = vn->list.prev;    else        lists[vn->inlist].tail = vn->list.prev;    lists[vn->inlist].num--;    vn->inlist = list;    vn->list.next = NULL;    vn->list.prev = lists[list].tail;    if (vn->list.prev)        vn->list.prev->list.next = vn;    else        lists[list].head = vn;    lists[list].tail = vn;    lists[list].num++;}static vnode *steal_vnode(int list){    vnode       *vn;    vn = lists[list].head;    if (!vn)        return NULL;    move_vnode(vn, LOCKED_LIST);    return vn;}static voidflush_vnode(vnode *vn, char r){    int     err;    vn->busy = TRUE;    UNLOCK(vnlock);    err = (*vn->ns->fs->ops.release_vnode)(vn->ns->data, vn->data, r);    if (err)        PANIC("ERROR WRITING VNODE!!!\n");    LOCK(vnlock);    vn->busy = FALSE;    clear_vnode(vn);}static vnode *lookup_vnode(nspace_id nsid, vnode_id vnid){    vnode       fakevn;    nspace      fakens;    fakens.nsid = nsid;    fakevn.ns = &fakens;    fakevn.vnid = vnid;    return SearchSL(skiplist, &fakevn);}static intload_vnode(nspace_id nsid, vnode_id vnid, char r, vnode **vnp){    int             err;    vnode           *vn;    LOCK(vnlock);    while (TRUE) {        vn = lookup_vnode(nsid, vnid);        if (vn)            if (vn->busy) {                UNLOCK(vnlock);                snooze(SLEEP_TIME);                LOCK(vnlock);                continue;            } else                break;        vn = steal_vnode(FREE_LIST);        if (!vn) {            vn = steal_vnode(USED_LIST);            if (!vn)                PANIC("OUT OF VNODE!!!\n");        } else            break;        flush_vnode(vn, r);        move_vnode(vn, FREE_LIST);    }    if (vn->ns == NULL) {        vn->ns = nsidtons(nsid);        if (!vn->ns) {            err = ENOENT;            goto error1;        }        vn->vnid = vnid;        vn->busy = TRUE;        err = sort_vnode(vn);        if (err)            goto error2;        move_vnode(vn, LOCKED_LIST);        UNLOCK(vnlock);        err = (*vn->ns->fs->ops.read_vnode)(vn->ns->data, vnid, r, &vn->data);        LOCK(vnlock);        vn->busy = FALSE;        if (err)            goto error2;        vn->rcnt = 1;    } else {        vn->rcnt++;        if (vn->rcnt == 1)            move_vnode(vn, LOCKED_LIST);    }    *vnp = vn;    UNLOCK(vnlock);    return 0;error2:    clear_vnode(vn);error1:    move_vnode(vn, FREE_LIST);    UNLOCK(vnlock);    return err;}static intcompare_vnode(vnode *vna, vnode *vnb){    if (vna->vnid > vnb->vnid)        return 1;    else        if (vna->vnid < vnb->vnid)            return -1;        else            if (vna->ns->nsid > vnb->ns->nsid)                return 1;            else                if (vna->ns->nsid < vnb->ns->nsid)                    return -1;                else                    return 0;}/* * path management functions */intnew_path(const char *path, char **copy){    const char  *q, *r;    char        *p;    int         l, s;    if (!path) {        *copy = NULL;        return 0;    }    l = strlen(path);    if (l == 0)        return ENOENT;    s = l;    if (path[l-1] == '/')        s++;    if (l >= MAXPATHLEN)        return ENAMETOOLONG;    q = path;    while(*q != '\0') {        while (*q == '/')            q++;        r = q;        while ((*q != '/') && (*q != '\0'))            q++;        if (q - r >= FILE_NAME_LENGTH)            return ENAMETOOLONG;            }    p = (char *) malloc(s+1);    if (!p)        return ENOMEM;    /* ### do real checking: MAXPATHLEN, max file name len, buffer address... */    strcpy(p, path);        if (p[l-1] == '/') {        p[l] = '.';        p[l+1] = '\0';    }    *copy = p;    return 0;}voidfree_path(char *p){    if (p) {        free(p);    }}static char *cat_paths(char *a, char *b){    char        *p;    p = (char *) realloc(a, strlen(a) + strlen(b) + 2);    if (!p)        return NULL;    strcat(p, "/");    strcat(p, b);    return p;}/*  * mount point management functions */static intis_mount_vnode(vnode *mount, vnode **root){    nspace      *ns;    LOCK(vnlock);    ns = mount->mounted;    if (ns) {        *root = ns->root;        ns->root->rcnt++;    }    UNLOCK(vnlock);    return (ns != NULL);        }static intis_mount_vnid(nspace_id nsid, vnode_id vnid, vnode_id *mount){    nspace      *ns;    for(ns = nshead; ns; ns = ns->next) {        if (!ns->mount)            continue;        if (ns->mount->ns->nsid != nsid)            continue;        if (ns->mount->vnid != vnid)            continue;        *mount = ns->root->vnid;        return TRUE;    }    return FALSE;}static intis_root(vnode *root, vnode **mount){    if ((root->ns->root == root) && root->ns->mount) {        *mount = root->ns->mount;        inc_vnode(*mount);        return TRUE;    } else        return FALSE;}/* * file descriptor management functions */ static ofile *get_fd(bool kernel, int fd, int type){    ofile       *f;    fdarray     *fds;    f = NULL;    if (kernel)        fds = global_fds;    else        fds = get_cur_ioctx()->fds;    LOCK(fds->lock);    if ((fd >= 0) && (fd < fds->num) && fds->fds[fd]) {        f = fds->fds[fd];        if (f->type & type)            atomic_add(&f->rcnt, 1);        else            f = NULL;    }    UNLOCK(fds->lock);    return f;}static intput_fd(ofile *f){    long            cnt;    cnt = atomic_add(&f->rcnt, -1);    if (cnt == 1)        invoke_free(f);    return 0;}static intnew_fd(bool kernel, int nfd, ofile *f, int fd, bool coe){    int         i, j, num, end;    fdarray     *fds;    ofile       *of;    int         err;    long        cnt;    if (kernel)        fds = global_fds;    else        fds = get_cur_ioctx()->fds;    LOCK(fds->lock);    num = fds->num;    if (!f) {        if ((fd < 0) || (fd >= num)) {            err = EBADF;            goto error1;        }        f = fds->fds[fd];        if (!f) {            err = EBADF;            goto error1;        }    }    atomic_add(&f->rcnt, 1);    atomic_add(&f->ocnt, 1);    if (nfd >= 0) {        if (nfd >= num) {            err = EBADF;            goto error2;        }        of = fds->fds[nfd];        fds->fds[nfd] = f;        SETBIT(fds->alloc, nfd, TRUE);        SETBIT(fds->coes, nfd, coe);        UNLOCK(fds->lock);        if (of) {            cnt = atomic_add(&of->ocnt, -1);            if (cnt == 1)                invoke_close(of);            cnt = atomic_add(&of->rcnt, -1);            if (cnt == 1)                invoke_free(of);        }        return nfd;    }    end = num & ~31;    for(j=0; j<end; j+=32)        if (fds->alloc[j/32] != 0xffffffff)            for(i=j; i<j+32; i++)                if (!GETBIT(fds->alloc, i))                    goto found;    for(i=end; i<num; i++)        if (!GETBIT(fds->alloc, i))            goto found;    err = EMFILE;    goto error2;found:    SETBIT(fds->alloc, i, 1);    fds->fds[i] = f;    SETBIT(fds->coes, i, coe);    UNLOCK(fds->lock);    return i;error2:    atomic_add(&f->rcnt, -1);    atomic_add(&f->ocnt, -1);error1:    UNLOCK(fds->lock);    return err;}static intremove_fd(bool kernel, int fd, int type){    ofile       *f;    fdarray     *fds;    long        cnt;    int         err;    f = NULL;    if (kernel)        fds = global_fds;    else        fds = get_cur_ioctx()->fds;    LOCK(fds->lock);    if ((fd >= 0) && (fd < fds->num) && fds->fds[fd]) {        f = fds->fds[fd];        if (f->type == type) {            SETBIT(fds->alloc, fd, 0);            fds->fds[fd] = NULL;        } else            f = NULL;    }    UNLOCK(fds->lock);    if (f == NULL)        return EBADF;    err = 0;    cnt = atomic_add(&f->ocnt, -1);    if (cnt == 1)        err = invoke_close(f);    cnt = atomic_add(&f->rcnt, -1);    if (cnt == 1)        invoke_free(f);    return err;}static intget_coe(bool kernel, int fd, int type, bool *coe){    ofile       *f;    fdarray     *fds;    f = NULL;    if (kernel)        fds = global_fds;    else        fds = get_cur_ioctx()->fds;    LOCK(fds->lock);    if ((fd >= 0) && (fd < fds->num) && fds->fds[fd]) {        f = fds->fds[fd];        if (f->type == type) {            *coe = GETBIT(fds->coes, fd);            UNLOCK(fds->lock);            return 0;        }    }    UNLOCK(fds->lock);    return EBADF;}static intset_coe(bool kernel, int fd, int type, bool coe){    ofile       *f;    fdarray     *fds;    f = NULL;    if (kernel)        fds = global_fds;    else        fds = get_cur_ioctx()->fds;    LOCK(fds->lock);    if ((fd >= 0) && (fd < fds->num) && fds->fds[fd]) {        f = fds->fds[fd];        if (f->type == type) {            SETBIT(fds->coes, fd, coe);            UNLOCK(fds->lock);            return 0;        }    }    UNLOCK(fds->lock);    return EBADF;}static intget_omode(bool kernel, int fd, int type, int *omode){    ofile       *f;    fdarray     *fds;    f = NULL;    if (kernel)        fds = global_fds;    else        fds = get_cur_ioctx()->fds;    LOCK(fds->lock);    if ((fd >= 0) && (fd < fds->num) && fds->fds[fd]) {        f = fds->fds[fd];        if (f->type == type) {            *omode = f->omode;            UNLOCK(fds->lock);            return 0;        }    }    UNLOCK(fds->lock);    return EBADF;}static intinvoke_close(ofile *f){    int     err;    vnode   *vn;    vn = f->vn;    switch (f->type) {    case FD_FILE:        err = (*vn->ns->fs->ops.close)(vn->ns->data, vn->data, f->cookie);        break;    case FD_DIR:        err = (*vn->ns->fs->ops.closedir)(vn->ns->data, vn->data, f->cookie);        break;    case FD_WD:    default:        err = 0;        break;    }    return err;}static intinvoke_free(ofile *f){    vnode           *vn;    op_free_cookie  *op = NULL;    vn = f->vn;    switch(f->type) {    case FD_FILE:        op = vn->ns->fs->ops.free_cookie;        break;    case FD_DIR:        op = vn->ns->fs->ops.free_dircookie;        break;    case FD_WD:        op = NULL;        break;    }    if (op)        (*op)(vn->ns->data, vn->data, f->cookie);    dec_vnode(vn, FALSE);    free(f);    return 0;}/* * other routines */static nspace *nsidtons(nspace_id nsid){    nspace      *ns;    ns = nstab[nsid % nns];    if (!ns || (ns->nsid != nsid) || ns->shutdown)        return NULL;    return ns;}static intalloc_wd_fd(bool kernel, vnode *vn, bool coe, int *fdp){    int             err;    ofile           *f;    int             nfd;    /*    find a file descriptor    */    f = (ofile *) calloc(sizeof(ofile), 1);    if (!f) {        err = ENOMEM;        goto error1;    }    f->type = FD_WD;    f->vn = vn;    f->rcnt = 0;    f->ocnt = 0;    nfd = new_fd(kernel, -1, f, -1, coe);    if (nfd < 0) {        err = EMFILE;        goto error2;    }    *fdp = nfd;    return 0;error2:    free(f);error1:    return err;}/* * file system operations */void *install_file_system(vnode_ops *ops, const char *name, bool fixed, image_id aid){    fsystem     *fs;    int         i;    fs = (fsystem *) malloc(sizeof(fsystem));    if (!fs)        return NULL;    memcpy(&fs->ops, ops, sizeof(vnode_ops));    strcpy(fs->name, name);    fs->rcnt = 1;    fs->fixed = fixed;    fs->aid = aid;    for(i=0; i<nfs; i++, nxfsid++)        if (!fstab[nxfsid % nfs]) {            fstab[nxfsid % nfs] = fs;            fs->fsid = nxfsid;            nxfsid++;            break;        }    if (i == nfs) {        free(fs);        return NULL;    }    return (void *)fs;}static fsystem *load_file_system(const char *name){    return NULL;}static intunload_file_system(fsystem *fs){    fstab[fs->fsid % nfs] = NULL;    free(fs);    return 0;}static fsystem *inc_file_system(const char *name){    fsystem         *fs;    int             i;    fs = NULL;    LOCK(fstablock);    for(i=0; i<nfs; i++)        if (fstab[i] && !strcmp(fstab[i]->name, name)) {            fs = fstab[i];            fs->rcnt++;            break;        }    if (!fs)        fs = load_file_system(name);    UNLOCK(fstablock);    return fs;}static intdec_file_system(fsystem *fs){    LOCK(fstablock);    fs->rcnt--;    if (!fs->fixed && (fs->rcnt == 0))        unload_file_system(fs);    UNLOCK(fstablock);    return 0;}static fdarray *new_fds(int num){    fdarray *fds;    size_t      sz;    sz = sizeof(fdarray) + (num-1) * sizeof(void *) + 2*BITSZ(num);    fds = (fdarray *) malloc(sz);    if (!fds)        return NULL;    memset(fds, 0, sz);    fds->rcnt = 1;    if (new_lock(&fds->lock, "fdlock") < 0) {        free(fds);        return NULL;    }    fds->num = num;    fds->alloc = (ulong *) &fds->fds[num];    fds->coes = &fds->alloc[BITSZ(num) / sizeof(ulong)];    return fds;}static intfree_fds(fdarray *fds){    long    cnt;    int     i;    ofile   *f;    for(i=0; i<fds->num; i++)        if (fds->fds[i]) {            f = fds->fds[i];            cnt = atomic_add(&f->ocnt, -1);            if (cnt == 1)                invoke_close(f);            cnt = atomic_add(&f->rcnt, -1);            if (cnt == 1)                invoke_free(f);        }    delete_sem(fds->lock.s);    free(fds);    return 0;}

⌨️ 快捷键说明

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