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

📄 fuse.c

📁 Linux下fuse用户文件系统的的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    memset(&buf, 0, sizeof(buf));    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        err = -ENOSYS;        if (f->op.getattr)            err = fuse_do_getattr(f, req, path, &buf);        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    if (!err) {        if (f->conf.auto_cache) {            pthread_mutex_lock(&f->lock);            update_stat(get_node(f, ino), &buf);            pthread_mutex_unlock(&f->lock);        }        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, fuse_req_t req, const char *path,                    struct stat *attr){    int err;    err = -ENOSYS;    if (f->op.chmod) {        struct fuse_intr_data d;        fuse_prepare_interrupt(f, req, &d);        err = f->op.chmod(path, attr->st_mode);        fuse_finish_interrupt(f, req, &d);    }    return err;}static int do_chown(struct fuse *f, fuse_req_t req, 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) {        struct fuse_intr_data d;        fuse_prepare_interrupt(f, req, &d);        err = f->op.chown(path, uid, gid);        fuse_finish_interrupt(f, req, &d);    }    return err;}static int do_truncate(struct fuse *f, fuse_req_t req,  const char *path,                       struct stat *attr, struct fuse_file_info *fi){    int err;    struct fuse_intr_data d;    err = -ENOSYS;    if (fi && f->op.ftruncate) {        fuse_prepare_interrupt(f, req, &d);        err = f->op.ftruncate(path, attr->st_size, fi);        fuse_finish_interrupt(f, req, &d);    } else if (f->op.truncate) {        fuse_prepare_interrupt(f, req, &d);        err = f->op.truncate(path, attr->st_size);        fuse_finish_interrupt(f, req, &d);    }    return err;}static int do_utimens(struct fuse *f, fuse_req_t req, const char *path,                      struct stat *attr){    int err;    struct fuse_intr_data d;    err = -ENOSYS;    if (f->op.utimens) {        struct timespec tv[2];#ifdef FUSE_STAT_HAS_NANOSEC        tv[0] = ST_ATIM(attr);        tv[1] = ST_MTIM(attr);#else        tv[0].tv_sec = attr->st_atime;        tv[0].tv_nsec = 0;        tv[1].tv_sec = attr->st_mtime;        tv[1].tv_nsec = 0;#endif        fuse_prepare_interrupt(f, req, &d);        err = f->op.utimens(path, tv);        fuse_finish_interrupt(f, req, &d);    } else if (f->op.utime) {        struct utimbuf buf;        buf.actime = attr->st_atime;        buf.modtime = attr->st_mtime;        fuse_prepare_interrupt(f, req, &d);        err = f->op.utime(path, &buf);        fuse_finish_interrupt(f, req, &d);    }    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, req, path, attr);            if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID)))                err = do_chown(f, req, path, attr, valid);            if (!err && (valid & FUSE_SET_ATTR_SIZE))                err = do_truncate(f, req, path, attr, fi);            if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) == (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))                err = do_utimens(f, req, path, attr);            if (!err)                err = fuse_do_getattr(f, req, path, &buf);        }        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    if (!err) {        if (f->conf.auto_cache) {            pthread_mutex_lock(&f->lock);            update_stat(get_node(f, ino), &buf);            pthread_mutex_unlock(&f->lock);        }        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) {            struct fuse_intr_data d;            fuse_prepare_interrupt(f, req, &d);            err = f->op.access(path, mask);            fuse_finish_interrupt(f, req, &d);        }        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) {            struct fuse_intr_data d;            fuse_prepare_interrupt(f, req, &d);            err = f->op.readlink(path, linkname, sizeof(linkname));            fuse_finish_interrupt(f, req, &d);        }        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 = fuse_do_create(f, req, path, mode, &fi);            if (!err) {                err = lookup_path(f, req, parent, name, path, &e, &fi);                if (f->op.release)                    fuse_do_release(f, req, path, &fi);            }        } else if (f->op.mknod && f->op.getattr) {            struct fuse_intr_data d;            fuse_prepare_interrupt(f, req, &d);            err = f->op.mknod(path, mode, rdev);            fuse_finish_interrupt(f, req, &d);            if (!err)                err = lookup_path(f, req, 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) {            struct fuse_intr_data d;            fuse_prepare_interrupt(f, req, &d);            err = f->op.mkdir(path, mode);            fuse_finish_interrupt(f, req, &d);            if (!err)                err = lookup_path(f, req, 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, req, path, parent, name);            else {                err = fuse_do_unlink(f, req, 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) {            struct fuse_intr_data d;            fuse_prepare_interrupt(f, req, &d);            err = f->op.rmdir(path);            fuse_finish_interrupt(f, req, &d);            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) {            struct fuse_intr_data d;            fuse_prepare_interrupt(f, req, &d);            err = f->op.symlink(linkname, path);            fuse_finish_interrupt(f, req, &d);            if (!err)                err = lookup_path(f, req, 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, req, newpath, newdir, newname);                if (!err) {                    err = fuse_do_rename(f, req, 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) {                struct fuse_intr_data d;                fuse_prepare_interrupt(f, req, &d);                err = f->op.link(oldpath, newpath);                fuse_finish_interrupt(f, req, &d);                if (!err)                    err = lookup_path(f, req, 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 = fuse_do_create(f, req, 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, req, parent, name, path, &e, fi);                if (err) {                    if (f->op.release)                        fuse_do_release(f, req, path, fi);                } else if (!S_ISREG(e.attr.st_mode)) {                    err = -EIO;                    if (f->op.release)                        fuse_do_release(f, req, path, fi);                    forget_node(f, e.ino, 1);                }            }        }

⌨️ 快捷键说明

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