fuse的direct_io

direct_io:

      启用该选项后,fuse的kernel模块将不在内核的页缓存中为读写的文件保存缓存。文件的数据将从用户态的缓冲区和fuse daemon的缓冲区之间直接拷贝。fuse的direct_io选项fcntl里的O_DIRECT选项区别。两者本来是一个目的,都是要取消kernel里的页缓存。但是fuse实现的时候把这个功能的控制权交个了fuse文件系统的实现者,而不是访问fuse的用户进程。如果open一个fuse里的文件时采用了O_DRECT,那么fuse的内核模块会返回错误EINVAL。
       fuse的direct_io选项是在每次文件打开时由fuse的用户态daemon进程设置。daemon进程返回open的结果消息时会告诉kernel本次文件open之后是否采用direct_io方式。
fuse的daemon在实现时可以动态选择是否对本次文件读写采用direct_io(当时实际这样做的fuse系统估计没有,太复杂了)。
       direct_io既有优点也有缺点,看具体场景。对于大文件的顺序i/o,direct_io可以有效减少大量的内存拷贝。但是对于小文件的随机访问,不采用direct_io而保留kernel的page cache,在cache命令率较高的情况下可以有效的减少i/o的路径,减少用户进程跟fuse daemon的交互次数。
       fuse的direct_io技术实现细节很有意思。既然绕过了page cache,那么意味着文件的数据是从文件访问者的用户空间跟fuse daemon的用户空间直接做内存拷贝。实际这个拷贝的动作时fuse daemon做的。理论上说,现代OS不会允许一个进程直接访问另外一个进程的用户空间数据,除非共享内存之类的特殊情况。实际上fuse的daemon进程正式这样做的,当然fuse daemon只是是在内核态做的这件事情,安全性还是有保证的,从fuse daemon用户态代码并不能做任何违法的事情。direct_io的大致流程如下:
         用户进程调用sys_write一个fuse文件。
         用户进程陷入内核调用fuse_direct_write,进一步调用fuse_direct_io。
         fuse_direct_io获取用户进程buf的物理页的page指针和offset,并写入fuse的request消息。
         fuse daemon 读取/dev/fuse文件,陷入内核后调用fuse_dev_read,收到前面的request消息。最好在函数fuse_copy_fill,将请求消息中用户进程的物理页映射到fuse daemon。注意,这里做物理页映射的时候调用的是kmap_atomic。kmap_atomic是好处是不会导致整个tlb无效,是快速页映射。这样fuse daemon就可以直接访问另外一个进程的用户空间,做内存拷贝了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值