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

📄 fuse.c

📁 UNIX/LINUX下面的用户文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup){    struct node *node;    if (nodeid == FUSE_ROOT_ID)        return;    pthread_mutex_lock(&f->lock);    node = get_node(f, nodeid);    assert(node->nlookup >= nlookup);    node->nlookup -= nlookup;    if (!node->nlookup) {        unhash_name(f, node);        unref_node(f, node);    }    pthread_mutex_unlock(&f->lock);}static void remove_node(struct fuse *f, fuse_ino_t dir, const char *name){    struct node *node;    pthread_mutex_lock(&f->lock);    node = lookup_node(f, dir, name);    if (node != NULL)        unhash_name(f, node);    pthread_mutex_unlock(&f->lock);}static int rename_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,                        fuse_ino_t newdir, const char *newname, int hide){    struct node *node;    struct node *newnode;    int err = 0;    pthread_mutex_lock(&f->lock);    node  = lookup_node(f, olddir, oldname);    newnode  = lookup_node(f, newdir, newname);    if (node == NULL)        goto out;    if (newnode != NULL) {        if (hide) {            fprintf(stderr, "fuse: hidden file got created during hiding\n");            err = -EBUSY;            goto out;        }        unhash_name(f, newnode);    }    unhash_name(f, node);    if (hash_name(f, node, newdir, newname) == -1) {        err = -ENOMEM;        goto out;    }    if (hide)        node->is_hidden = 1; out:    pthread_mutex_unlock(&f->lock);    return err;}static void set_stat(struct fuse *f, fuse_ino_t nodeid, struct stat *stbuf){    if (!f->conf.use_ino)        stbuf->st_ino = nodeid;    if (f->conf.set_mode)        stbuf->st_mode = (stbuf->st_mode & S_IFMT) | (0777 & ~f->conf.umask);    if (f->conf.set_uid)        stbuf->st_uid = f->conf.uid;    if (f->conf.set_gid)        stbuf->st_gid = f->conf.gid;}static struct fuse *req_fuse(fuse_req_t req){    return (struct fuse *) fuse_req_userdata(req);}static void fuse_intr_sighandler(int sig){    (void) sig;    /* Nothing to do */}struct fuse_intr_data {    pthread_t id;    pthread_cond_t cond;    int finished;};static void fuse_interrupt(fuse_req_t req, void *d_){    struct fuse_intr_data *d = d_;    struct fuse *f = req_fuse(req);    if (d->id == pthread_self())        return;    pthread_mutex_lock(&f->lock);    while (!d->finished) {        struct timeval now;        struct timespec timeout;        pthread_kill(d->id, f->conf.intr_signal);        gettimeofday(&now, NULL);        timeout.tv_sec = now.tv_sec + 1;        timeout.tv_nsec = now.tv_usec * 1000;        pthread_cond_timedwait(&d->cond, &f->lock, &timeout);    }    pthread_mutex_unlock(&f->lock);}static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,                                     struct fuse_intr_data *d){    pthread_mutex_lock(&f->lock);    d->finished = 1;    pthread_cond_broadcast(&d->cond);    pthread_mutex_unlock(&f->lock);    fuse_req_interrupt_func(req, NULL, NULL);    pthread_cond_destroy(&d->cond);}static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d){    d->id = pthread_self();    pthread_cond_init(&d->cond, NULL);    d->finished = 0;    fuse_req_interrupt_func(req, fuse_interrupt, d);}static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req,                                         struct fuse_intr_data *d){    if (f->conf.intr)        fuse_do_finish_interrupt(f, req, d);}static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,                                          struct fuse_intr_data *d){    if (f->conf.intr)        fuse_do_prepare_interrupt(req, d);}#ifndef __FreeBSD__static int fuse_compat_open(struct fuse_fs *fs, const char *path,                            struct fuse_file_info *fi){    int err;    if (!fs->compat || fs->compat >= 25)        err = fs->op.open(path, fi);    else if (fs->compat == 22) {        struct fuse_file_info_compat tmp;        memcpy(&tmp, fi, sizeof(tmp));        err = ((struct fuse_operations_compat22 *) &fs->op)->open(path, &tmp);        memcpy(fi, &tmp, sizeof(tmp));        fi->fh = tmp.fh;    } else        err = ((struct fuse_operations_compat2 *) &fs->op)            ->open(path, fi->flags);    return err;}static int fuse_compat_release(struct fuse_fs *fs, const char *path,                               struct fuse_file_info *fi){    if (!fs->compat || fs->compat >= 22)        return fs->op.release(path, fi);    else        return ((struct fuse_operations_compat2 *) &fs->op)            ->release(path, fi->flags);}static int fuse_compat_opendir(struct fuse_fs *fs, const char *path,                               struct fuse_file_info *fi){    if (!fs->compat || fs->compat >= 25)        return fs->op.opendir(path, fi);    else {        int err;        struct fuse_file_info_compat tmp;        memcpy(&tmp, fi, sizeof(tmp));        err = ((struct fuse_operations_compat22 *) &fs->op)            ->opendir(path, &tmp);        memcpy(fi, &tmp, sizeof(tmp));        fi->fh = tmp.fh;        return err;    }}static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf,                                  struct statvfs *stbuf){    stbuf->f_bsize   = compatbuf->block_size;    stbuf->f_blocks  = compatbuf->blocks;    stbuf->f_bfree   = compatbuf->blocks_free;    stbuf->f_bavail  = compatbuf->blocks_free;    stbuf->f_files   = compatbuf->files;    stbuf->f_ffree   = compatbuf->files_free;    stbuf->f_namemax = compatbuf->namelen;}static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf){    stbuf->f_bsize   = oldbuf->f_bsize;    stbuf->f_blocks  = oldbuf->f_blocks;    stbuf->f_bfree   = oldbuf->f_bfree;    stbuf->f_bavail  = oldbuf->f_bavail;    stbuf->f_files   = oldbuf->f_files;    stbuf->f_ffree   = oldbuf->f_ffree;    stbuf->f_namemax = oldbuf->f_namelen;}static int fuse_compat_statfs(struct fuse_fs *fs, const char *path,                              struct statvfs *buf){    int err;    if (!fs->compat || fs->compat >= 25) {        err = fs->op.statfs(fs->compat == 25 ? "/" : path, buf);    } else if (fs->compat > 11) {        struct statfs oldbuf;        err = ((struct fuse_operations_compat22 *) &fs->op)            ->statfs("/", &oldbuf);        if (!err)            convert_statfs_old(&oldbuf, buf);    } else {        struct fuse_statfs_compat1 compatbuf;        memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1));        err = ((struct fuse_operations_compat1 *) &fs->op)->statfs(&compatbuf);        if (!err)            convert_statfs_compat(&compatbuf, buf);    }    return err;}#else /* __FreeBSD__ */static inline int fuse_compat_open(struct fuse_fs *fs, char *path,                                   struct fuse_file_info *fi){    return fs->op.open(path, fi);}static inline int fuse_compat_release(struct fuse_fs *fs, const char *path,                                      struct fuse_file_info *fi){    return fs->op.release(path, fi);}static inline int fuse_compat_opendir(struct fuse_fs *fs, const char *path,                                      struct fuse_file_info *fi){    return fs->op.opendir(path, fi);}static inline int fuse_compat_statfs(struct fuse_fs *fs, const char *path,                                     struct statvfs *buf){    return fs->op.statfs(fs->compat == 25 ? "/" : path, buf);}#endif /* __FreeBSD__ */int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.getattr)        return fs->op.getattr(path, buf);    else        return -ENOSYS;}int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,                     struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.fgetattr)        return fs->op.fgetattr(path, buf, fi);    else if (fs->op.getattr)        return fs->op.getattr(path, buf);    else        return -ENOSYS;}int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,                   const char *newpath){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.rename)        return fs->op.rename(oldpath, newpath);    else        return -ENOSYS;}int fuse_fs_unlink(struct fuse_fs *fs, const char *path){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.unlink)        return fs->op.unlink(path);    else        return -ENOSYS;}int fuse_fs_rmdir(struct fuse_fs *fs, const char *path){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.rmdir)        return fs->op.rmdir(path);    else        return -ENOSYS;}int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.symlink)        return fs->op.symlink(linkname, path);    else        return -ENOSYS;}int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.link)        return fs->op.link(oldpath, newpath);    else        return -ENOSYS;}int fuse_fs_release(struct fuse_fs *fs,  const char *path,                    struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.release)        return fuse_compat_release(fs, path, fi);    else        return 0;}int fuse_fs_opendir(struct fuse_fs *fs, const char *path,                    struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.opendir)        return fuse_compat_opendir(fs, path, fi);    else        return 0;}int fuse_fs_open(struct fuse_fs *fs, const char *path,                 struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.open)        return fuse_compat_open(fs, path, fi);    else        return 0;}int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size,                 off_t off, struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.read)        return fs->op.read(path, buf, size, off, fi);    else        return -ENOSYS;}int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf,                  size_t size, off_t off, struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.write)        return fs->op.write(path, buf, size, off, fi);    else        return -ENOSYS;}int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,                  struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.fsync)        return fs->op.fsync(path, datasync, fi);    else        return -ENOSYS;}int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,                     struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.fsyncdir)        return fs->op.fsyncdir(path, datasync, fi);    else        return -ENOSYS;}int fuse_fs_flush(struct fuse_fs *fs, const char *path,                  struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.flush)        return fs->op.flush(path, fi);    else        return -ENOSYS;}int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.statfs)        return fuse_compat_statfs(fs, path, buf);    else {        buf->f_namemax = 255;        buf->f_bsize = 512;        return 0;    }}int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,                       struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.releasedir)        return fs->op.releasedir(path, fi);    else        return 0;}static int fill_dir_old(struct fuse_dirhandle *dh, const char *name, int type,                        ino_t ino){    int res;    struct stat stbuf;    memset(&stbuf, 0, sizeof(stbuf));    stbuf.st_mode = type << 12;    stbuf.st_ino = ino;    res = dh->filler(dh->buf, name, &stbuf, 0);    return res ? -ENOMEM : 0;}int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,                    fuse_fill_dir_t filler, off_t off,                    struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.readdir)        return fs->op.readdir(path, buf, filler, off, fi);    else if (fs->op.getdir) {        struct fuse_dirhandle dh;        dh.filler = filler;        dh.buf = buf;        return fs->op.getdir(path, &dh, fill_dir_old);    } else        return -ENOSYS;}int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,                   struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.create)        return fs->op.create(path, mode, fi);    else

⌨️ 快捷键说明

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