JuiceFS:用户态fuse接口

这篇具有很好参考价值的文章主要介绍了JuiceFS:用户态fuse接口。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

FUSE简介

FUSE(Filesystem in Userspace,用户空间文件系统)作为类UNIX系统平台上可加载的内核模块,允许非特权用户创建功能完备的文件系统,而不需要重新编译内核。FUSE模块仅仅提供kernel模块的接入口,而本身的主要实现代码位于用户空间中。对于读写虚拟文件系统来说,FUSE是个很好的选择。

FUSE IO流程

内核文件系统

juicefs fuse,JuiceFS,分布式,linux,数据库,大数据,云计算,Powered by 金山文档

FUSE

内核 FUSE 模块在内核态中间做协议封装和协议解析的工作,它接收从VFS下来的请求并按照 FUSE 协议转发到用户态,然后接收用户态的响应,并随后回复给用户。

juicefs fuse,JuiceFS,分布式,linux,数据库,大数据,云计算,Powered by 金山文档
juicefs fuse,JuiceFS,分布式,linux,数据库,大数据,云计算,Powered by 金山文档

内核到用户态穿越

juicefs fuse,JuiceFS,分布式,linux,数据库,大数据,云计算,Powered by 金山文档

FUSE总结

  • FUSE框架就是内核开发者为了能在用户态进行文件系统开发的需求开发出来的;

  • FUSE 框架的3大组件分别是:内核 fuse 模块,用户态 libfuse 库,fusermount 挂载工具;

  • 内核FUSE模块用于接收VFS的请求,并且通过 /dev/fuse 建立的管道,把封装后的请求发往用户态;

  • libfuse 则是用户态封装用来解析 FUSE 数据包协议的库代码,服务于所有的用户态文件系统;

  • /dev/fuse 就是连接内核 fuse 和用户态文件系统的纽带;

  • fusermount 则是用户态文件系统用来挂载的工具

用户态FUSE接口及功能

接口

可以参考linux内核struct fuse_operations操作

struct fuse_operations {
    int (*getattr) (const char *, struct stat *);
    int (*readlink) (const char *, char *, size_t);
    int (*mknod) (const char *, mode_t, dev_t);
    int (*mkdir) (const char *, mode_t);
    int (*unlink) (const char *);
    int (*rmdir) (const char *);
    int (*symlink) (const char *, const char *);
    int (*rename) (const char *, const char *);
    int (*link) (const char *, const char *);
    int (*chmod) (const char *, mode_t);
    int (*chown) (const char *, uid_t, gid_t);
    int (*truncate) (const char *, off_t);
    int (*utime) (const char *, struct utimbuf *);
    int (*open) (const char *, struct fuse_file_info *);
    int (*read) (const char *, char *, size_t, off_t, structfuse_file_info *);
    int (*write) (const char *, const char *, size_t, off_t, structfuse_file_info *);
    int (*statfs) (const char *, struct statvfs *);
    int (*flush) (const char *, struct fuse_file_info *);
    int (*release) (const char *, struct fuse_file_info *);
    int (*fsync) (const char *, int, struct fuse_file_info *);
    int (*setxattr) (const char *, const char *, const char *, size_t,int);
    int (*getxattr) (const char *, const char *, char *, size_t);
    int (*listxattr) (const char *, char *, size_t);
    int (*removexattr) (const char *, const char *);
    int (*opendir) (const char *, struct fuse_file_info *);
    int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,struct fuse_file_info *);
    int (*releasedir) (const char *, struct fuse_file_info *);
    int (*fsyncdir) (const char *, int, struct fuse_file_info *);
    void *(*init) (struct fuse_conn_info *conn);
    void (*destroy) (void *);
    int (*access) (const char *, int);
    int (*create) (const char *, mode_t, struct fuse_file_info*);
    int (*ftruncate) (const char *, off_t, struct fuse_file_info*);
    int (*fgetattr) (const char *, struct stat *, struct fuse_file_info*);
    int (*lock) (const char *, struct fuse_file_info *, int cmd, structflock *);
    int (*utimens) (const char *, const struct timespec tv[2]);
    int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
};

功能

  • getattr: int (*getattr) (const char *, struct stat *); 这个函数与 stat() 类似。st_dev 和 st_blksize 域都可以忽略。st_ino 域也会被忽略,除非在执行mount 时指定了 use_ino 选项。

  • readlink: int (*readlink) (const char *, char *, size_t); 这个函数会读取一个符号链接的目标。缓冲区应该是一个以 null 结束的字符串。缓冲区的大小参数包括这个 null结束字符的空间。如果链接名太长,不能保存到缓冲区中,就应该被截断。成功时的返回值应该是“0”。

  • getdir: int (*getdir) (const char *, fuse_dirh_t,fuse_dirfil_t); 这个函数会读取一个目录中的内容。这个操作实际上是在一次调用中执行 opendir()、readdir()、...、closedir()序列。对于每个目录项来说,都应该调用 filldir() 函数。

  • mknod: int (*mknod) (const char *, mode_t, dev_t); 这个函数会创建一个文件节点。此处没有 create() 操作;mknod()会在创建非目录、非符号链接的节点时调用。

  • mkdir: int (*mkdir) (const char *, mode_t); 分别用来创建一个目录。

  • rmdir: int (*rmdir) (const char *); 分别用来删除一个目录。

  • unlink: int (*unlink) (const char *); 删除名一个文件

  • rename: int (*rename) (const char *, const char *); 重命名一个文件。

  • symlink: int (*symlink) (const char *, const char *); 这个函数用来创建一个符号链接。

  • link: int (*link) (const char *, const char *); 这个函数创建一个到文件的硬链接。

  • chmod: int (*chmod) (const char *, mode_t); 修改权限位

  • chown: int (*chown) (const char *, uid_t, gid_t); 修改属主和用户

  • truncate: int (*truncate) (const char *, off_t); 截断文件

  • utime: int (*utime) (const char *, struct utimbuf *); 修改文件的访问/修改时间

  • open: int (*open) (const char *, struct fuse_file_info *); 这是文件的打开操作。对 open()函数不能传递创建或截断标记(O_CREAT、O_EXCL、O_TRUNC)。这个函数应该检查是否允许执行给定的标记的操作。另外,open()也可能在 fuse_file_info结构中返回任意的文件句柄,这会传递给所有的文件操作。

  • read: int (*read) (const char *, char *, size_t, off_t, structfuse_file_info *); 这个函数从一个打开文件中读取数据。除非碰到 EOF 或出现错误,否则 read()应该返回所请求的字节数的数据;否则,其余数据都会被替换成 0。一个例外是在执行 mount 命令时指定了 direct_io选项,在这种情况中 read() 系统调用的返回值会影响这个操作的返回值。

  • write: int (*write) (const char *, const char *, size_t, off_t,struct fuse_file_info *); 这个函数将数据写入一个打开的文件中。除非碰到 EOF 或出现错误,否则 write() 应该返回所请求的字节数的数据。一个例外是在执行mount 命令时指定了 direct_io 选项(这于 read()操作的情况类似)。

  • statfs: int (*statfs) (const char *, struct statfs *); 这个函数获取文件系统的统计信息。f_type 和 f_fsid 域都会被忽略。

  • flush: int (*flush) (const char *, struct fuse_file_info*); 这表示要刷新缓存数据。它并不等于 fsync() 函数 —— 也不是请求同步脏数据。每次对一个文件描述符执行 close()函数时,都会调用 flush();因此如果文件系统希望在 close()中返回写错误,并且这个文件已经缓存了脏数据,那么此处就是回写数据并返回错误的好地方。由于很多应用程序都会忽略 close()错误,因此这通常用处不大。 注意:我们也可以对一个 open() 多次调用 flush() 方法。如果由于调用了 dup()、dup2() 或 fork()而产生多个文件描述符指向一个打开文件的情况,就可能会需要这种用法。我们无法确定哪个 flush 操作是最后一次操作,因此每个flush 都应该同等地对待。多个写刷新序列相当罕见,因此这并不是什么问题。

  • release: int (*release) (const char *, struct fuse_file_info*); 这个函数释放一个打开文件。release() 是在对一个打开文件没有其他引用时调用的 ——此时所有的文件描述符都会被关闭,所有的内存映射都会被取消。对于每个 open() 调用来说,都必须有一个使用完全相同标记和文件描述符的release() 调用。对一个文件打开多次是可能的,在这种情况中只会考虑最后一次release,然后就不能再对这个文件执行更多的读/写操作了。release的返回值会被忽略。

  • fsync: int (*fsync) (const char *, int, struct fuse_file_info*); 这个函数用来同步文件内容。如果 datasync 参数为非0,那么就只会刷新用户数据,而不会刷新元数据。

  • setxattr: int (*setxattr) (const char *, const char *, const char*, size_t, int); 设置扩展属性

  • getxattr: int (*getxattr) (const char *, const char *, char *,size_t); 获取扩展属性

  • listxattr: int (*listxattr) (const char *, char *, size_t); 列出扩展属性

  • removexattr: int (*removexattr) (const char *, const char*); 删除扩展属性

参考文献

https://www.a-programmer.top/2021/10/05/FUSE%E4%BB%8B%E7%BB%8D/

https://blog.csdn.net/sourthstar/article/details/8551993文章来源地址https://www.toymoban.com/news/detail-785904.html

到了这里,关于JuiceFS:用户态fuse接口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • juicefs使用glusterfs卷

    前提:搭建后redis,并配置无密码和远程访问。并且juicefs要使用1.1.0以上版本。 参考juicefs官网: 使用glusterfs作为后端存储 https://juicefs.com/docs/zh/community/how_to_setup_object_storage#gluster 编译安装juicefs https://juicefs.com/docs/zh/community/installation 编译安装juicefs步骤整理如下,要求系统为

    2024年02月17日
    浏览(39)
  • juicefs源码format命令阅读

    之前博文中介绍过在windows下安装GO和vscode windows下安装go环境 和vscode中go扩展+调试 首先观察代码架构 上图是我已经编译过得代码,可能和刚git下来的有些出入。 我是在windows上进行调试,首先需要对juicefs进行编译。编译过程看文档即可。 文档地址:安装 | JuiceFS Document Cent

    2024年02月10日
    浏览(22)
  • JuiceFS 元数据引擎选型指南

    文件系统是我们常见的存储形式,内部主要由数据和元数据两部分组成。其中数据是文件的具体内容,通常会直接展现给用户;而元数据是描述数据的数据,用来记录文件属性、目录结构、数据存储位置等。一般来说,元数据有非常鲜明的特点,即占用空间较小,但访问非常

    2024年02月02日
    浏览(27)
  • 分布式接口幂等性设计实现

    面对分布式架构和微服务复杂的系统架构和网络超时服务器异常等带来的系统稳定性问题,分布式接口的幂等性设计显得尤为重要。本文简要介绍了几种分布式接口幂等性设计实现,包括Token去重机制、乐观锁机制、数据库主键和状态机实现等,以加深理解。 1、分布式接口幂

    2024年02月05日
    浏览(29)
  • cookie和session的区别,分布式环境怎么保存用户状态

    1、cookie数据存放在客户的浏览器上,session数据放在服务器上。 2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。 3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方

    2024年02月13日
    浏览(42)
  • Navicat 技术指引 | 适用于 GaussDB 分布式的用户/权限功能

     Navicat Premium(16.3.3 Windows 版或以上)正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能,还提供强大的高阶功能(如模型、结构同步、协同合作、数据迁移等)。这使得Nav

    2024年02月05日
    浏览(30)
  • 使用 redis 实现分布式接口限流注解 RedisLimit

    前言 很多时候,由于种种不可描述的原因,我们需要针对单个接口实现接口限流,防止访问次数过于频繁。这里就用 redis+aop 实现一个限流接口注解 @RedisLimit 代码 点击查看RedisLimit注解代码 AOP代码 点击查看aop代码 lua脚本代码 注意:脚本代码是放在 resources 文件下的,它的类型是

    2024年02月08日
    浏览(46)
  • redis+token+分布式锁确保接口的幂等性

    目录 1.幂等性是什么? 2.如何实现幂等性呢? 1.新增管理员,出弹窗的同时,请求后台。 2.后端根据雪花算法生成唯一标识key,以雪花数为key存到redis。并返回key给前端。 3.前端保存后端传过来的key。 4.前端输入完成信息,点击【保存】,携带key请求后端。 5.请求到达后端,

    2024年02月14日
    浏览(36)
  • Ceph分布式文件系统——文件系统MDS接口 块存储RDB接口 对象存储RGW接口

    服务端操作 1)在管理节点创建 mds 服务 2)查看各个节点的 mds 服务 3)创建存储池,启用 ceph 文件系统 ceph 文件系统至少需要两个 rados 池,一个用于存储数据,一个用于存储元数据。此时数据池就类似于文件系统的共享目录。 创建 cephfs,命令格式:ceph fs new FS_NAME CEPHFS_ME

    2024年02月16日
    浏览(30)
  • 金山云:基于 JuiceFS 的 Elasticsearch 温冷热数据管理实践

    Elasticsearch(下文简称“ES”)是一个分布式的搜索引擎,还可作为分布式数据库来使用,常用于日志处理、分析和搜索等场景;在运维排障层面,ES 组成的 ELK(Elasticsearch+ Logstash+ Kibana)解决方案,简单易用、响应速度快,并且提供了丰富的报表;高可用方面, ES 提供了分布

    2023年04月15日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包