Designing a True Direct-Access File System with DevFS


Designing a True Direct-Access File System with DevFS

0x00 引言

这篇Paper主要讲的是新的硬件下面的文件系统的优化的问题。下面的这幅图比较的表示了DevFS的主要内容,主要就是如果将文件系统的实现完全绕开Kernel,与硬件集成,应用可以直接操作,

 Evaluation of an emulated DevFS prototype shows more than 2x higher I/O throughput with direct access and up to a 5x reduction in device RAM utilization.

devfs-serval

0x01 基本思路

上面的图中表示了几种文件系统类型的设计:

  • 传统的FS,所有的工作都交给Kernel来完成,应用只是使用syscall来调用Kernel提供的功能。这个也是最常见的实现方式;
  • 混合类型的user-level的FS,Control-Plane运行在内核,但是读写数据的时候应用可以直接和硬件交互;
  • 带Server的混合类型的user-level的FS,与上一种类似,区别在于未来减少Control-Plane给Kernel带来的Overhead,这些工作交给一个可信的另外一个应用完成;
  • 基于FUSE的user-level的FS,使用Linux上面的FUSE。处理的路径更加长,和这篇Paper内容关系不大;
  • 真直接访问的user-level的FS,就是这篇Paper提出的FS,基本思路就是Control-Plane和Data-Plane都不需要Kernel处理

由于Control-Plane和Data-Plane都不需要Kernel,这样的话需要处理下面几个问题,也基本是就是原来由内核处理的几个问题需要处理:

  • 文件系统完整性,这里主要就是处理一些情况下更新的问题和并发的问题;
  • 权限,实现POSIX的文件权限的功能;
  • Crash一致性,这个是一个文件系统要处理的一个问题;

DevFS这样做的主要的优点就是:1. 能获得更高的并发性;2. 可以使用一些特殊的但是不是一般的存储设备都有的特性来获取更高的性能,比如防止突然掉电丢失数据的电容;3. 将文件系统和一些原来是现在存储设备中的一些控制逻辑集成,可以获取更好的性能,比如将FS的设计和FTL的结合考虑。

0x02 设计

设计原则

  1. 解耦FS的数据结构,获取更加好的并发度,DevFS将每个基本的数据结构映射到不同的硬件资源(单元)上面,减少操作的相互的影响;
  2. 保证文件完整性的同时保持user-lelvel的直接访问能力;
  3. 使用硬件的防掉电的电容来简化Crash一致性;
  4. 减少FS的内存使用,因为设备的内存一般都不如主机,比较有限;
  5. DevFS可以共享一些OS-level的状态信息(最小化的信息);

一个基本的示意图:

devfs-design

几个设计要点:

  • 文件系统结构,文件系统结构范围全局结构和单个文件的结构两个部分,全局的结构主要包括了FS整体的一些信息,主要就是一些元数据的信息,比如superblock, inodes, and bitmaps。而DevFS为每个文件提供单独的IO队列和日志。一个内存中的filemap树提供了文件系统层次结构的一个抽象,

     the DevFS superblock contains global information of a file system, each inode contains per-file metadata and a reference to per-file memory and disk journal, and finally, directory entries (dentries) are maintained in a radix-tree indexed by hash values of file path names.
    

    DevFS提供的还是POSIX的文件系统的接口,提供了良好的兼容性。对于一个文件操作的IO请求会提交给这个文件对应的IO队列来处理。

  • 保证文件系统完整性; 在保证文件系统完整性的基本方式上,DevFS使用的是常见的log的方式。这里一个值得注意的地方是一些日志是保存在内存中的。为了处理并发访问的问题,DevFS为每一个文件使用了一个per-file filemap lock,更新的操作会被赋予一个时间戳,用于给操作排序,

    DevFS tags each command with a time-stamp counter (TSC). Applications requiring strict data ordering for shared files could implement custom user-level synchronization at application-level.
    
  • 简化Crash一致性设计;这里使用的基本的方式前面已经提到的就是使用硬件提供的特性。掉电之后,存储设备自己的电容还可以提供可以使用一段时间的电力。由于能提供的电力是有限的,和下面的一个设计点对应,这里也是想办法减少内存中没有持久化的数据的量。这里在掉电之后需要持久化的就是内存中的日志和提交IO队列。

  • 减少内存占用;在DevFS中,主要消耗内存的就是in-memory inodes, dentries, file pointers, 和per-file filemaptree几种结构。为了减少内存的占用,这里住著压迫使用量一下几种方式:1. 相关的数据结构只有在需要的时候再会分配;2. 对于被Cache的inode和sentries等信息在文件被关闭的时候保存到主机的内存中,而不是设备的内存中。3. inode中包含了非常多的信息。DevFS将其分为device-inode 和 host-inode两个部分,

    The device-inode contains fields that are accessed even after a file is closed, and therefore only the host-inode structure is moved to host memory. Each host inode is approximately 593 bytes of the overall 840 bytes. Therefore, this decomposition along with reverse caching significantly reduces inode memory use.
    
  • 为权限检查的共享状态;文件的权限也是很重要的一个部分,但是DevFS绕开了Kernel直接和应用交互。为了仍然坚持权限,DevFS和Kernel之间使用一个 credential table,保存在设备的内存中,只由Kernel更新。如下面的图所示,使用的是CPU ID标记的方式,使用要求在进程切换的时候,OS需要更新这个table。

devfs-permission

0x03 评估

具体信息可以参看[1],

devfs-perf

参考

  1. Designing a True Direct-Access File System with DevFS, FAST’18.