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

📄 fuse.c

📁 linux下的用户文件系统fuse-2.5.2
💻 C
📖 第 1 页 / 共 4 页
字号:
                        int err){    if (!err) {        if (fuse_reply_entry(req, e) == -ENOENT)            forget_node(req_fuse(req), e->ino, 1);    } else        reply_err(req, err);}static void fuse_data_init(void *data){    struct fuse *f = (struct fuse *) data;    struct fuse_context *c = fuse_get_context();    memset(c, 0, sizeof(*c));    c->fuse = f;    if (f->op.init)        f->user_data = f->op.init();}static void fuse_data_destroy(void *data){    struct fuse *f = (struct fuse *) data;    struct fuse_context *c = fuse_get_context();    memset(c, 0, sizeof(*c));    c->fuse = f;    c->private_data = f->user_data;    if (f->op.destroy)        f->op.destroy(f->user_data);}static void fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char *name){    struct fuse *f = req_fuse_prepare(req);    struct fuse_entry_param e;    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path_name(f, parent, name);    if (path != NULL) {        if (f->conf.debug) {            printf("LOOKUP %s\n", path);            fflush(stdout);        }        err = -ENOSYS;        if (f->op.getattr) {            err = lookup_path(f, parent, name, path, &e, NULL);            if (err == -ENOENT && f->conf.negative_timeout != 0.0) {                e.ino = 0;                e.entry_timeout = f->conf.negative_timeout;                err = 0;            }        }        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_entry(req, &e, err);}static void fuse_forget(fuse_req_t req, fuse_ino_t ino, unsigned long nlookup){    struct fuse *f = req_fuse(req);    if (f->conf.debug) {        printf("FORGET %llu/%lu\n", (unsigned long long) ino, nlookup);        fflush(stdout);    }    forget_node(f, ino, nlookup);    fuse_reply_none(req);}static void fuse_getattr(fuse_req_t req, fuse_ino_t ino,                         struct fuse_file_info *fi){    struct fuse *f = req_fuse_prepare(req);    struct stat buf;    char *path;    int err;    (void) fi;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        err = -ENOSYS;        if (f->op.getattr)            err = f->op.getattr(path, &buf);        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    if (!err) {        set_stat(f, ino, &buf);        fuse_reply_attr(req, &buf, f->conf.attr_timeout);    } else        reply_err(req, err);}static int do_chmod(struct fuse *f, const char *path, struct stat *attr){    int err;    err = -ENOSYS;    if (f->op.chmod)        err = f->op.chmod(path, attr->st_mode);    return err;}static int do_chown(struct fuse *f, const char *path, struct stat *attr,                    int valid){    int err;    uid_t uid = (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1;    gid_t gid = (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1;    err = -ENOSYS;    if (f->op.chown)        err = f->op.chown(path, uid, gid);    return err;}static int do_truncate(struct fuse *f, const char *path, struct stat *attr,                       struct fuse_file_info *fi){    int err;    err = -ENOSYS;    if (fi && f->op.ftruncate)        err = f->op.ftruncate(path, attr->st_size, fi);    else if (f->op.truncate)        err = f->op.truncate(path, attr->st_size);    return err;}static int do_utime(struct fuse *f, const char *path, struct stat *attr){    int err;    struct utimbuf buf;    buf.actime = attr->st_atime;    buf.modtime = attr->st_mtime;    err = -ENOSYS;    if (f->op.utime)        err = f->op.utime(path, &buf);    return err;}static void fuse_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,                         int valid, struct fuse_file_info *fi){    struct fuse *f = req_fuse_prepare(req);    struct stat buf;    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        err = -ENOSYS;        if (f->op.getattr) {            err = 0;            if (!err && (valid & FUSE_SET_ATTR_MODE))                err = do_chmod(f, path, attr);            if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID)))                err = do_chown(f, path, attr, valid);            if (!err && (valid & FUSE_SET_ATTR_SIZE))                err = do_truncate(f, path, attr, fi);            if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) == (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))                err = do_utime(f, path, attr);            if (!err)                err = f->op.getattr(path, &buf);        }        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    if (!err) {        set_stat(f, ino, &buf);        fuse_reply_attr(req, &buf, f->conf.attr_timeout);    } else        reply_err(req, err);}static void fuse_access(fuse_req_t req, fuse_ino_t ino, int mask){    struct fuse *f = req_fuse_prepare(req);    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        if (f->conf.debug) {            printf("ACCESS %s 0%o\n", path, mask);            fflush(stdout);        }        err = -ENOSYS;        if (f->op.access)            err = f->op.access(path, mask);        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_err(req, err);}static void fuse_readlink(fuse_req_t req, fuse_ino_t ino){    struct fuse *f = req_fuse_prepare(req);    char linkname[PATH_MAX + 1];    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        err = -ENOSYS;        if (f->op.readlink)            err = f->op.readlink(path, linkname, sizeof(linkname));        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    if (!err) {        linkname[PATH_MAX] = '\0';        fuse_reply_readlink(req, linkname);    } else        reply_err(req, err);}static void fuse_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,                       mode_t mode, dev_t rdev){    struct fuse *f = req_fuse_prepare(req);    struct fuse_entry_param e;    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path_name(f, parent, name);    if (path != NULL) {        if (f->conf.debug) {            printf("MKNOD %s\n", path);            fflush(stdout);        }        err = -ENOSYS;        if (S_ISREG(mode) && f->op.create && f->op.getattr) {            struct fuse_file_info fi;            memset(&fi, 0, sizeof(fi));            fi.flags = O_CREAT | O_EXCL | O_WRONLY;            err = f->op.create(path, mode, &fi);            if (!err) {                err = lookup_path(f, parent, name, path, &e, &fi);                if (f->op.release)                    f->op.release(path, &fi);            }        } else if (f->op.mknod && f->op.getattr) {            err = f->op.mknod(path, mode, rdev);            if (!err)                err = lookup_path(f, parent, name, path, &e, NULL);        }        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_entry(req, &e, err);}static void fuse_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,                       mode_t mode){    struct fuse *f = req_fuse_prepare(req);    struct fuse_entry_param e;    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path_name(f, parent, name);    if (path != NULL) {        if (f->conf.debug) {            printf("MKDIR %s\n", path);            fflush(stdout);        }        err = -ENOSYS;        if (f->op.mkdir && f->op.getattr) {            err = f->op.mkdir(path, mode);            if (!err)                err = lookup_path(f, parent, name, path, &e, NULL);        }        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_entry(req, &e, err);}static void fuse_unlink(fuse_req_t req, fuse_ino_t parent, const char *name){    struct fuse *f = req_fuse_prepare(req);    char *path;    int err;    err = -ENOENT;    pthread_rwlock_wrlock(&f->tree_lock);    path = get_path_name(f, parent, name);    if (path != NULL) {        if (f->conf.debug) {            printf("UNLINK %s\n", path);            fflush(stdout);        }        err = -ENOSYS;        if (f->op.unlink) {            if (!f->conf.hard_remove && is_open(f, parent, name))                err = hide_node(f, path, parent, name);            else {                err = f->op.unlink(path);                if (!err)                    remove_node(f, parent, name);            }        }        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_err(req, err);}static void fuse_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name){    struct fuse *f = req_fuse_prepare(req);    char *path;    int err;    err = -ENOENT;    pthread_rwlock_wrlock(&f->tree_lock);    path = get_path_name(f, parent, name);    if (path != NULL) {        if (f->conf.debug) {            printf("RMDIR %s\n", path);            fflush(stdout);        }        err = -ENOSYS;        if (f->op.rmdir) {            err = f->op.rmdir(path);            if (!err)                remove_node(f, parent, name);        }        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_err(req, err);}static void fuse_symlink(fuse_req_t req, const char *linkname,                         fuse_ino_t parent, const char *name){    struct fuse *f = req_fuse_prepare(req);    struct fuse_entry_param e;    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path_name(f, parent, name);    if (path != NULL) {        if (f->conf.debug) {            printf("SYMLINK %s\n", path);            fflush(stdout);        }        err = -ENOSYS;        if (f->op.symlink && f->op.getattr) {            err = f->op.symlink(linkname, path);            if (!err)                err = lookup_path(f, parent, name, path, &e, NULL);        }        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_entry(req, &e, err);}static void fuse_rename(fuse_req_t req, fuse_ino_t olddir, const char *oldname,                        fuse_ino_t newdir, const char *newname){    struct fuse *f = req_fuse_prepare(req);    char *oldpath;    char *newpath;    int err;    err = -ENOENT;    pthread_rwlock_wrlock(&f->tree_lock);    oldpath = get_path_name(f, olddir, oldname);    if (oldpath != NULL) {        newpath = get_path_name(f, newdir, newname);        if (newpath != NULL) {            if (f->conf.debug) {                printf("RENAME %s -> %s\n", oldpath, newpath);                fflush(stdout);            }            err = -ENOSYS;            if (f->op.rename) {                err = 0;                if (!f->conf.hard_remove &&                    is_open(f, newdir, newname))                    err = hide_node(f, newpath, newdir, newname);                if (!err) {                    err = f->op.rename(oldpath, newpath);                    if (!err)                        err = rename_node(f, olddir, oldname, newdir, newname, 0);                }            }            free(newpath);        }        free(oldpath);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_err(req, err);}static void fuse_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,                      const char *newname){    struct fuse *f = req_fuse_prepare(req);    struct fuse_entry_param e;    char *oldpath;    char *newpath;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    oldpath = get_path(f, ino);    if (oldpath != NULL) {        newpath =  get_path_name(f, newparent, newname);        if (newpath != NULL) {            if (f->conf.debug) {                printf("LINK %s\n", newpath);                fflush(stdout);            }            err = -ENOSYS;            if (f->op.link && f->op.getattr) {                err = f->op.link(oldpath, newpath);                if (!err)                    err = lookup_path(f, newparent, newname, newpath, &e, NULL);            }            free(newpath);        }        free(oldpath);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_entry(req, &e, err);}static void fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,                        mode_t mode, struct fuse_file_info *fi){    struct fuse *f = req_fuse_prepare(req);    struct fuse_entry_param e;    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path_name(f, parent, name);    if (path != NULL) {        err = -ENOSYS;        if (f->op.create && f->op.getattr) {            err = f->op.create(path, mode, fi);            if (!err) {                if (f->conf.debug) {                    printf("CREATE[%llu] flags: 0x%x %s\n",                           (unsigned long long) fi->fh, fi->flags, path);                    fflush(stdout);                }                err = lookup_path(f, parent, name, path, &e, fi);                if (err) {                    if (f->op.release)                        f->op.release(path, fi);                } else if (!S_ISREG(e.attr.st_mode)) {                    err = -EIO;                    if (f->op.release)                        f->op.release(path, fi);                    forget_node(f, e.ino, 1);                }            }        }    }    if (!err) {        if (f->conf.direct_io)            fi->direct_io = 1;        if (f->conf.kernel_cache)            fi->keep_cache = 1;        pthread_mutex_lock(&f->lock);        if (fuse_reply_create(req, &e, fi) == -ENOENT) {            /* The open syscall was interrupted, so it must be cancelled */            if(f->op.release)                f->op.release(path, fi);            forget_node(f, e.ino, 1);        } else {            struct node *node = get_node(f, e.ino);            node->open_count ++;        }        pthread_mutex_unlock(&f->lock);    } else        reply_err(req, err);    if (path)        free(path);    pthread_rwlock_unlock(&f->tree_lock);}static void fuse_open(fuse_req_t req, fuse_ino_t ino,                      struct fuse_file_info *fi){    struct fuse *f = req_fuse_prepare(req);    char *path = NULL;    int err = 0;    pthread_rwlock_rdlock(&f->tree_lock);    if (f->op.open) {        err = -ENOENT;        path = get_path(f, ino);        if (path != NULL)            err = fuse_do_open(f, path, fi);    }    if (!err) {        if (f->conf.debug) {            printf("OPEN[%llu] flags: 0x%x\n", (unsigned long long) fi->fh,                   fi->flags);            fflush(stdout);        }        if (f->conf.direct_io)            fi->direct_io = 1;        if (f->conf.kernel_cache)            fi->keep_cache = 1;        pthread_mutex_lock(&f->lock);

⌨️ 快捷键说明

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