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

📄 fuse_lowlevel.c

📁 UNIX/LINUX下面的用户文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
static void do_flush(fuse_req_t req, fuse_ino_t nodeid,                     struct fuse_flush_in *arg){    struct fuse_file_info fi;    memset(&fi, 0, sizeof(fi));    fi.fh = arg->fh;    fi.fh_old = fi.fh;    if (req->f->op.flush)        req->f->op.flush(req, nodeid, &fi);    else        fuse_reply_err(req, ENOSYS);}static void do_release(fuse_req_t req, fuse_ino_t nodeid,                       struct fuse_release_in *arg){    struct fuse_file_info fi;    memset(&fi, 0, sizeof(fi));    fi.flags = arg->flags;    fi.fh = arg->fh;    fi.fh_old = fi.fh;    if (req->f->op.release)        req->f->op.release(req, nodeid, &fi);    else        fuse_reply_err(req, 0);}static void do_fsync(fuse_req_t req, fuse_ino_t nodeid,                     struct fuse_fsync_in *inarg){    struct fuse_file_info fi;    memset(&fi, 0, sizeof(fi));    fi.fh = inarg->fh;    fi.fh_old = fi.fh;    if (req->f->op.fsync)        req->f->op.fsync(req, nodeid, inarg->fsync_flags & 1, &fi);    else        fuse_reply_err(req, ENOSYS);}static void do_opendir(fuse_req_t req, fuse_ino_t nodeid,                       struct fuse_open_in *arg){    struct fuse_file_info fi;    memset(&fi, 0, sizeof(fi));    fi.flags = arg->flags;    if (req->f->op.opendir)        req->f->op.opendir(req, nodeid, &fi);    else        fuse_reply_open(req, &fi);}static void do_readdir(fuse_req_t req, fuse_ino_t nodeid,                       struct fuse_read_in *arg){    struct fuse_file_info fi;    memset(&fi, 0, sizeof(fi));    fi.fh = arg->fh;    fi.fh_old = fi.fh;    if (req->f->op.readdir)        req->f->op.readdir(req, nodeid, arg->size, arg->offset, &fi);    else        fuse_reply_err(req, ENOSYS);}static void do_releasedir(fuse_req_t req, fuse_ino_t nodeid,                          struct fuse_release_in *arg){    struct fuse_file_info fi;    memset(&fi, 0, sizeof(fi));    fi.flags = arg->flags;    fi.fh = arg->fh;    fi.fh_old = fi.fh;    if (req->f->op.releasedir)        req->f->op.releasedir(req, nodeid, &fi);    else        fuse_reply_err(req, 0);}static void do_fsyncdir(fuse_req_t req, fuse_ino_t nodeid,                        struct fuse_fsync_in *inarg){    struct fuse_file_info fi;    memset(&fi, 0, sizeof(fi));    fi.fh = inarg->fh;    fi.fh_old = fi.fh;    if (req->f->op.fsyncdir)        req->f->op.fsyncdir(req, nodeid, inarg->fsync_flags & 1, &fi);    else        fuse_reply_err(req, ENOSYS);}static void do_statfs(fuse_req_t req){    if (req->f->op.statfs)        req->f->op.statfs(req);    else        fuse_reply_err(req, ENOSYS);}static void do_setxattr(fuse_req_t req, fuse_ino_t nodeid,                        struct fuse_setxattr_in *arg){    char *name = PARAM(arg);    char *value = name + strlen(name) + 1;    if (req->f->op.setxattr)            req->f->op.setxattr(req, nodeid, name, value, arg->size,                                       arg->flags);    else        fuse_reply_err(req, ENOSYS);}static void do_getxattr(fuse_req_t req, fuse_ino_t nodeid,                        struct fuse_getxattr_in *arg){    if (req->f->op.getxattr)        req->f->op.getxattr(req, nodeid, PARAM(arg), arg->size);    else        fuse_reply_err(req, ENOSYS);}static void do_listxattr(fuse_req_t req, fuse_ino_t nodeid,                         struct fuse_getxattr_in *arg){    if (req->f->op.listxattr)        req->f->op.listxattr(req, nodeid, arg->size);    else        fuse_reply_err(req, ENOSYS);}static void do_removexattr(fuse_req_t req, fuse_ino_t nodeid, char *name){    if (req->f->op.removexattr)        req->f->op.removexattr(req, nodeid, name);    else        fuse_reply_err(req, ENOSYS);}static void do_init(fuse_req_t req, struct fuse_init_in *arg){    struct fuse_init_out outarg;    struct fuse_ll *f = req->f;    size_t bufsize = fuse_chan_bufsize(req->ch);    if (f->debug) {        printf("INIT: %u.%u\n", arg->major, arg->minor);        fflush(stdout);    }    f->got_init = 1;    if (f->op.init)        f->op.init(f->userdata);    f->major = FUSE_KERNEL_VERSION;    f->minor = arg->minor;    if (bufsize < FUSE_MIN_READ_BUFFER) {        fprintf(stderr, "fuse: warning: buffer size too small: %i\n", bufsize);        bufsize = FUSE_MIN_READ_BUFFER;    }    memset(&outarg, 0, sizeof(outarg));    outarg.major = f->major;    outarg.minor = FUSE_KERNEL_MINOR_VERSION;    outarg.max_write = bufsize - 4096;    if (f->debug) {        printf("   INIT: %u.%u\n", outarg.major, outarg.minor);        fflush(stdout);    }    send_reply_ok(req, &outarg, arg->minor < 5 ? 8 : sizeof(outarg));}void *fuse_req_userdata(fuse_req_t req){    return req->f->userdata;}const struct fuse_ctx *fuse_req_ctx(fuse_req_t req){    return &req->ctx;}static void fuse_ll_process(void *data, const char *buf, size_t len,                     struct fuse_chan *ch){    struct fuse_ll *f = (struct fuse_ll *) data;    struct fuse_in_header *in = (struct fuse_in_header *) buf;    const void *inarg = buf + sizeof(struct fuse_in_header);    struct fuse_req *req;    if (f->debug) {        printf("unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %i\n",               in->unique, opname((enum fuse_opcode) in->opcode), in->opcode,               (unsigned long) in->nodeid, len);        fflush(stdout);    }    req = (struct fuse_req *) malloc(sizeof(struct fuse_req));    if (req == NULL) {        fprintf(stderr, "fuse: failed to allocate request\n");        return;    }    req->f = f;    req->unique = in->unique;    req->ctx.uid = in->uid;    req->ctx.gid = in->gid;    req->ctx.pid = in->pid;    req->ch = ch;    if (!f->got_init && in->opcode != FUSE_INIT)        fuse_reply_err(req, EIO);    else if (f->allow_root && in->uid != f->owner && in->uid != 0 &&             in->opcode != FUSE_INIT && in->opcode != FUSE_READ &&             in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC &&             in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&             in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR) {        fuse_reply_err(req, EACCES);    } else switch (in->opcode) {    case FUSE_INIT:        do_init(req, (struct fuse_init_in *) inarg);        break;    case FUSE_LOOKUP:        do_lookup(req, in->nodeid, (char *) inarg);        break;    case FUSE_FORGET:        do_forget(req, in->nodeid, (struct fuse_forget_in *) inarg);        break;    case FUSE_GETATTR:        do_getattr(req, in->nodeid);        break;    case FUSE_SETATTR:        do_setattr(req, in->nodeid, (struct fuse_setattr_in *) inarg);        break;    case FUSE_READLINK:        do_readlink(req, in->nodeid);        break;    case FUSE_MKNOD:        do_mknod(req, in->nodeid, (struct fuse_mknod_in *) inarg);        break;    case FUSE_MKDIR:        do_mkdir(req, in->nodeid, (struct fuse_mkdir_in *) inarg);        break;    case FUSE_UNLINK:        do_unlink(req, in->nodeid, (char *) inarg);        break;    case FUSE_RMDIR:        do_rmdir(req, in->nodeid, (char *) inarg);        break;    case FUSE_SYMLINK:        do_symlink(req, in->nodeid, (char *) inarg,                   ((char *) inarg) + strlen((char *) inarg) + 1);        break;    case FUSE_RENAME:        do_rename(req, in->nodeid, (struct fuse_rename_in *) inarg);        break;    case FUSE_LINK:        do_link(req, in->nodeid, (struct fuse_link_in *) inarg);        break;    case FUSE_OPEN:        do_open(req, in->nodeid, (struct fuse_open_in *) inarg);        break;    case FUSE_FLUSH:        do_flush(req, in->nodeid, (struct fuse_flush_in *) inarg);        break;    case FUSE_RELEASE:        do_release(req, in->nodeid, (struct fuse_release_in *) inarg);        break;    case FUSE_READ:        do_read(req, in->nodeid, (struct fuse_read_in *) inarg);        break;    case FUSE_WRITE:        do_write(req, in->nodeid, (struct fuse_write_in *) inarg);        break;    case FUSE_STATFS:        do_statfs(req);        break;    case FUSE_FSYNC:        do_fsync(req, in->nodeid, (struct fuse_fsync_in *) inarg);        break;    case FUSE_SETXATTR:        do_setxattr(req, in->nodeid, (struct fuse_setxattr_in *) inarg);        break;    case FUSE_GETXATTR:        do_getxattr(req, in->nodeid, (struct fuse_getxattr_in *) inarg);        break;    case FUSE_LISTXATTR:        do_listxattr(req, in->nodeid, (struct fuse_getxattr_in *) inarg);        break;    case FUSE_REMOVEXATTR:        do_removexattr(req, in->nodeid, (char *) inarg);        break;    case FUSE_OPENDIR:        do_opendir(req, in->nodeid, (struct fuse_open_in *) inarg);        break;    case FUSE_READDIR:        do_readdir(req, in->nodeid, (struct fuse_read_in *) inarg);        break;    case FUSE_RELEASEDIR:        do_releasedir(req, in->nodeid, (struct fuse_release_in *) inarg);        break;    case FUSE_FSYNCDIR:        do_fsyncdir(req, in->nodeid, (struct fuse_fsync_in *) inarg);        break;    case FUSE_ACCESS:        do_access(req, in->nodeid, (struct fuse_access_in *) inarg);        break;    case FUSE_CREATE:        do_create(req, in->nodeid, (struct fuse_open_in *) inarg);        break;    default:        fuse_reply_err(req, ENOSYS);    }}enum {    KEY_HELP,    KEY_VERSION,};static struct fuse_opt fuse_ll_opts[] = {    { "debug", offsetof(struct fuse_ll, debug), 1 },    { "-d", offsetof(struct fuse_ll, debug), 1 },    { "allow_root", offsetof(struct fuse_ll, allow_root), 1 },    FUSE_OPT_KEY("-h", KEY_HELP),    FUSE_OPT_KEY("--help", KEY_HELP),    FUSE_OPT_KEY("-V", KEY_VERSION),    FUSE_OPT_KEY("--version", KEY_VERSION),    FUSE_OPT_END};static void fuse_ll_version(void){    fprintf(stderr, "using FUSE kernel interface version %i.%i\n",            FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);}static int fuse_ll_opt_proc(void *data, const char *arg, int key,                            struct fuse_args *outargs){    (void) data; (void) outargs;    switch (key) {    case KEY_HELP:        break;    case KEY_VERSION:        fuse_ll_version();        break;    default:        fprintf(stderr, "fuse: unknown option `%s'\n", arg);    }    return -1;}int fuse_lowlevel_is_lib_option(const char *opt){    return fuse_opt_match(fuse_ll_opts, opt);}static void fuse_ll_destroy(void *data){    struct fuse_ll *f = (struct fuse_ll *) data;    if (f->op.destroy)        f->op.destroy(f->userdata);    free(f);}struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,                                       const struct fuse_lowlevel_ops *op,                                       size_t op_size, void *userdata){    struct fuse_ll *f;    struct fuse_session *se;    struct fuse_session_ops sop = {        .process = fuse_ll_process,        .destroy = fuse_ll_destroy,    };    if (sizeof(struct fuse_lowlevel_ops) < op_size) {        fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");        op_size = sizeof(struct fuse_lowlevel_ops);    }    f = (struct fuse_ll *) calloc(1, sizeof(struct fuse_ll));    if (f == NULL) {        fprintf(stderr, "fuse: failed to allocate fuse object\n");        goto out;    }    if (fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)        goto out_free;    memcpy(&f->op, op, op_size);    f->owner = getuid();    f->userdata = userdata;    se = fuse_session_new(&sop, f);    if (!se)        goto out_free;    return se; out_free:    free(f); out:    return NULL;}#ifndef __FreeBSD__#include "fuse_lowlevel_compat.h"static void fill_open_compat(struct fuse_open_out *arg,                      const struct fuse_file_info_compat *f){    arg->fh = f->fh;    if (f->direct_io)        arg->open_flags |= FOPEN_DIRECT_IO;    if (f->keep_cache)        arg->open_flags |= FOPEN_KEEP_CACHE;}static void convert_statfs_compat(const struct statfs *compatbuf,                                  struct statvfs *buf){    buf->f_bsize	= compatbuf->f_bsize;    buf->f_blocks	= compatbuf->f_blocks;    buf->f_bfree	= compatbuf->f_bfree;    buf->f_bavail	= compatbuf->f_bavail;    buf->f_files	= compatbuf->f_files;    buf->f_ffree	= compatbuf->f_ffree;    buf->f_namemax	= compatbuf->f_namelen;}int fuse_reply_open_compat(fuse_req_t req,                           const struct fuse_file_info_compat *f){    struct fuse_open_out arg;    memset(&arg, 0, sizeof(arg));    fill_open_compat(&arg, f);    return send_reply_ok(req, &arg, sizeof(arg));}int fuse_reply_statfs_compat(fuse_req_t req, const struct statfs *stbuf){    struct statvfs newbuf;    memset(&newbuf, 0, sizeof(newbuf));    convert_statfs_compat(stbuf, &newbuf);    return fuse_reply_statfs(req, &newbuf);}struct fuse_session *fuse_lowlevel_new_compat(const char *opts,                                              const struct fuse_lowlevel_ops *op,                                              size_t op_size, void *userdata){    struct fuse_session *se;    struct fuse_args args = FUSE_ARGS_INIT(0, NULL);    if (opts &&        (fuse_opt_add_arg(&args, "") == -1 ||         fuse_opt_add_arg(&args, "-o") == -1 ||         fuse_opt_add_arg(&args, opts) == -1)) {        fuse_opt_free_args(&args);        return NULL;    }    se = fuse_lowlevel_new(&args, op, op_size, userdata);    fuse_opt_free_args(&args);    return se;}__asm__(".symver fuse_reply_statfs_compat,fuse_reply_statfs@FUSE_2.4");__asm__(".symver fuse_reply_open_compat,fuse_reply_open@FUSE_2.4");__asm__(".symver fuse_lowlevel_new_compat,fuse_lowlevel_new@FUSE_2.4");#endif /* __FreeBSD__ */

⌨️ 快捷键说明

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