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

📄 file.c

📁 be文件系统实现的源码
💻 C
字号:
/*  This file contains the bulk of the file system interface routines  and all the routines that operate on files directly.      THIS CODE COPYRIGHT DOMINIC GIAMPAOLO.  NO WARRANTY IS EXPRESSED   OR IMPLIED.  YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR  NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.  FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).  Dominic Giampaolo  dbg@be.com*/#include "myfs.h"intmyfs_read_vnode(void *ns, vnode_id vnid, char r, void **node){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi;    int         bsize = myfs->dsb.block_size, offset;    char       *block;    char        tmp[IDENT_NAME_LENGTH];    fs_off_t    addr;     my_ino_t    ia = (my_ino_t)vnid;    myfs_inode_etc *metc;        mi = (myfs_inode *)malloc(sizeof(myfs_inode));    if (mi == NULL)        return ENOMEM;    metc = (myfs_inode_etc *)calloc(1, sizeof(myfs_inode_etc));    if (metc == NULL) {        free(mi);        return ENOMEM;    }       addr = myfs->dsb.inodes_start + ((ia * sizeof(myfs_inode)) / bsize);    offset = (ia % (bsize / sizeof(myfs_inode))) * sizeof(myfs_inode);    block = get_block(myfs->fd, addr, bsize);    if (block == NULL) {        printf("couldn't read inode block at block #%ld", addr);        return EINVAL;    }        memcpy(mi, &block[offset], sizeof(myfs_inode));    release_block(myfs->fd, addr);    mi->etc = metc;    CHECK_INODE(mi);    /* make sure it's not corrupt */    sprintf(tmp, "ino#%ld", ia);    new_lock(&mi->etc->lock, tmp);    /* only directories use this. it is read on demmand so clear it for now */    mi->etc->contents = NULL;        *node = mi;    return 0;}intmyfs_release_vnode(void *ns, void *node, char r){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    free_lock(&mi->etc->lock);        if (mi->etc->contents) {        free(mi->etc->contents);        mi->etc->contents = NULL;    }    free(mi->etc);    mi->etc = NULL;        free(mi);    return 0;}intmyfs_remove_vnode(void *ns, void *node, char r){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    myfs_free_data_stream(myfs, mi);        myfs_free_inode(myfs, mi->inode_num);    if (mi->etc->contents)        free(mi->etc->contents);    mi->etc->contents = NULL;      /* paranoia, it'll destroy ya */        free(mi->etc);    mi->etc = NULL;        free(mi);    return 0;}intmyfs_access(void *ns, void *node, int mode){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    /* no permission checking yet... */    return 0;}static intmake_file(myfs_info *myfs, myfs_inode *parent, int mode, myfs_inode **newfile){    int         ret;    size_t      len;    myfs_inode *mi;    mi = myfs_allocate_inode(myfs, parent, mode);    if (mi == NULL)        return ENOSPC;    mi->mode |= MY_S_IFREG;            /* mark it as a regular file */    update_inode(myfs, mi);    *newfile = mi;    return 0;}intmyfs_create(void *ns, void *dir, const char *name,            int omode, int mode, vnode_id *vnid, void **cookie){    int         ret, err;    myfs_info  *myfs   = (myfs_info *)ns;    myfs_inode *parent = (myfs_inode *)dir;    myfs_inode *mi;    CHECK_INODE(parent);    if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)        return EINVAL;    if (strlen(name) >= FILE_NAME_LENGTH-1)        return ENAMETOOLONG;    if (dir_lookup(myfs, dir, name, vnid) == 0)        return EEXIST;    ret = make_file(myfs, parent, mode, &mi);    if (ret < 0)        return ret;        ret = dir_insert(myfs, parent, name, mi->inode_num);    if (ret != 0) {        printf("create: failed to insert the new guy %s\n", name);        myfs_free_inode(myfs, mi->inode_num);        free(mi);                return ret;    }    *vnid   = (vnode_id)mi->inode_num;    *cookie = NULL;    if ((err = new_vnode(myfs->nsid, *vnid, mi)) != 0)        myfs_die("new_vnode failed for vnid %ld: %s\n", *vnid, strerror(err));    return 0;    }intmyfs_symlink(void *ns, void *dir, const char *name, const char *path){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi;    return EINVAL;}intmyfs_readlink(void *ns, void *node, char *buf, size_t *bufsize){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    return EINVAL;}intmyfs_link(void *ns, void *dir, const char *name, void *node){    return EINVAL;}intmyfs_rename(void *ns, void *olddir, const char *oldname,            void *newdir, const char *newname){    return EINVAL;}intmyfs_unlink(void *ns, void *_dir, const char *name){    int         ret;    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *dir  = (myfs_inode *)_dir;    myfs_inode *mi;    vnode_id    vnid;        CHECK_INODE(dir);    ret = dir_lookup(myfs, dir, name, &vnid);    if (ret != 0)        return ret;    ret = get_vnode(myfs->nsid, vnid, (void *)&mi);    if (ret != 0)        return ret;        if (MY_S_ISDIR(mi->mode)) {        put_vnode(myfs->nsid, vnid);        return EISDIR;    }    ret = dir_delete(myfs, dir, name);    if (ret != 0)        return ret;    remove_vnode(myfs->nsid, vnid);    put_vnode(myfs->nsid, vnid);    return 0;}intmyfs_open(void *ns, void *node, int omode, void **cookie){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    return 0;}intmyfs_close(void *ns, void *node, void *cookie){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    return 0;}intmyfs_free_cookie(void *ns, void *node, void *cookie){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    return 0;}intmyfs_read(void *ns, void *node, void *cookie, fs_off_t pos, void *buf,          size_t *len){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    return myfs_read_data_stream(myfs, mi, pos, buf, len);}intmyfs_write(void *ns, void *node, void *cookie, fs_off_t pos,           const void *buf, size_t *len){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    return myfs_write_data_stream(myfs, mi, pos, buf, len);}intmyfs_ioctl(void *ns, void *node, void *cookie, int cmd, void *buf, size_t len){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    return EINVAL;}intmyfs_rstat(void *ns, void *node, struct my_stat *st){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    st->dev      = myfs->fd;    st->ino      = mi->inode_num;    st->mode     = mi->mode;    st->nlink    = 1;    st->uid      = mi->uid;    st->gid      = mi->gid;    st->size     = mi->data.size;    st->blksize  = 1024;    st->atime    = time(NULL);    st->mtime    = mi->last_modified_time;    st->ctime    = mi->last_modified_time;    st->crtime   = mi->create_time;    return 0;}intmyfs_wstat(void *ns, void *node, struct my_stat *st, long mask){    int         err  = 0;    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    if (mask == 0)                /* check this first */        return 0;        if (mask & WSTAT_MODE) {        mi->mode = (mi->mode & MY_S_IFMT) | (st->mode & MY_S_IUMSK);    }    if (mask & WSTAT_UID) {        mi->uid = st->uid;    }    if (mask & WSTAT_GID) {        mi->gid = st->gid;    }    if (mask & WSTAT_SIZE) {        if (MY_S_ISDIR(mi->mode)) {            err = EISDIR;        } else {            err = myfs_set_file_size(myfs, mi, st->size);            mi->last_modified_time = time(NULL);        }        if (err)            return err;    }    if (mask & WSTAT_CRTIME) {        mi->create_time = st->crtime;    }    if (mask & WSTAT_MTIME) {        mi->last_modified_time = st->mtime;    }    if (mask & WSTAT_ATIME) {        /* hah! nothing to do because we're wanky and don't maintain atime */    }    update_inode(myfs, mi);    return 0;}intmyfs_fsync(void *ns, void *node){    myfs_info  *myfs = (myfs_info *)ns;    myfs_inode *mi   = (myfs_inode *)node;    CHECK_INODE(mi);    return 0;}

⌨️ 快捷键说明

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