文件系统(十二)—图解如何使用fuse文件系统

本文深入探讨了FUSE(Filesystem in Userspace)的工作原理,包括libfuse库的编译和使用,以及如何实现一个简单的用户空间文件系统。文章详细介绍了libfuse的高、低级别API,以及挂载和卸载过程。此外,还解析了FUSE内核队列的运作机制,请求和响应包的格式,以及通过/dev/fuse的调用流程。最后,总结了FUSE涉及的三个主要模块:内核模块、LibFUSE模块和用户程序模块。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习完了fuse的内核实现,我们真实的来看怎么实现一个简单的fuse文件系统,我们还是以之前的例子,对于用户空间需要实现基于libfuse实现的应用程序hello,例子可以参考http://fuse.sourceforge.net/helloworld.html

在这里插入图片描述

首先,我们需要编译libfuse,其可以参考下面的github,里面有编译的相关方法

1 libfuse库测试

libfuse的仓库地址为:https://github.com/libfuse/libfuse

使用其方法编译安装完成如下图所示,表示libfuse库已经安装到我们的系统中

在这里插入图片描述

libfuse提供了两个APIs:

  • 一个“high-level”同步API
  • 一个“low-level” 异步API

这两种API 都从内核接收请求传递到主程序(fuse_main函数),主程序使用相应的回调函数进行处理。

  • 当使用high-level API时,回调函数使用文件名(file names)和路径(paths)工作,而不是索引节点inodes,回调函数返回时也就是一个请求处理的完成。
  • 使用low-level API 时,回调函数必须使用索引节点inode工作,响应发送必须显示的使用一套单独的API函数

在这里插入图片描述

low-level api 相对于 high-level api 来说,有更好的自由度;high-level相对于 low-level api 则有更简单的api使用,如果阅读过fuse源码过后,使用low-level api将使得可控性更强。

  • 一种是high-level模式,此模式下fuse的入口函数为fuse_main,它封装了一系列初始化操作,使用简单,但是不灵活。
  • 另一种是low-level模式,用户可以利用fuse提供的底层函数灵活开发应用程序。

libfuse的简单示例

刚才上面提到了两个API,一个high-level API,一个是low-level API,libfuse 提供了两个示例程序:

这里学习了解一下High-Level ,接下来进行一个简单的测试:

gcc -Wall hello.c `pkg-config fuse3 --cflags --libs` -o hello

然后进行挂载

cd /mnt
mkdir hello_test  //建立挂载目录
cd libfuse/example
./hello /mnt/hello_test/ 		//挂载

若显示:

在这里插入图片描述

是因为没有配置ldconfig:

vim /etc/ld.so.conf.d/fuse.conf

输入:

/usr/local/lib

执行:

ldconfig

重新挂载:

./hello /mnt/hello_test/

/home/book/fuse/libfuse/example/hello on /home/book/fuse/hello_test type fuse.hello (rw,nosuid,nodev,relatime,user_id=1001,group_id=1001)

现在挂载成功啦!!!其挂载的属性为fuse.hello,这个在VFS分发中将会使用到,那么进入hello_test目录,可以看到hello文件:

cat hello hello 
Hello World!

2. fuse用户空间工作原理

首先来看看hello.c中是如何启动fuse deman的,其入口为,重点是fuse_main接口

int main(int argc, char *argv[])
{
   
	int ret;
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);

	/* Set defaults -- we have to use strdup so that
	   fuse_opt_parse can free the defaults if other
	   values are specified */
	options.filename = strdup("hello");
	options.contents = strdup("Hello World!\n");

	/* Parse options */
	if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1)
		return 1;

	/* When --help is specified, first print our own file-system
	   specific help text, then signal fuse_main to show
	   additional help (by adding `--help` to the options again)
	   without usage: line (by setting argv[0] to the empty
	   string) */
	if (options.show_help) {
   
		show_help(argv[0]);
		assert(fuse_opt_add_arg(&args, "--help") == 0);
		args.argv[0][0] = '\0';
	}

	ret = fuse_main(args.argc, args.argv, &hello_oper, NULL);
	fuse_opt_free_args(&args);
	return ret;
}

fuse为开发者提供了两组接口,分别是fuse_lowlevel_ops以及fuse_operations,开发者只需要实现
这两组接口的一种即可实现一个用户空间文件系统。

static struct fuse_lowlevel_ops fuse_path_ops = {
   
.init    = fuse_lib_init,
.destroy = fuse_lib_destroy,
.lookup  = fuse_lib_lookup,
.forget  = fuse_lib_forget,
.forget_multi = fuse_lib_forget_multi,
...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值