通用文件系统缓存

概述

此功能是用于网络文件系统的通用缓存,但也可用于缓存其他内容,例如 ISO9660 文件系统。

FS-Cache 在缓存后端(例如 CacheFiles)和网络文件系统之间进行协调。

+---------+
|         |                                    +--------------+
|   NFS   |--+                                 |              |
|         |  |                             +-->|   CacheFS    |
+---------+  |               +----------+  |   |  /dev/hda5   |
             |               |          |  |   +--------------+
+---------+  +-------------->|          |  |
|         |      +-------+   |          |--+
|   AFS   |----->|       |   | FS-Cache |
|         |      | netfs |-->|          |--+
+---------+  +-->|  lib  |   |          |  |
             |   |       |   |          |  |   +--------------+
+---------+  |   +-------+   +----------+  |   |              |
|         |  |                             +-->|  CacheFiles  |
|   9P    |--+                                 |  /var/cache  |
|         |                                    +--------------+
+---------+

换句话说,FS-Cache 是一个模块,它为网络文件系统提供缓存功能,使缓存对用户透明。

+---------+
|         |
| Server  |
|         |
+---------+
     |                  NETWORK
~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     |
     |           +----------+
     V           |          |
+---------+      |          |
|         |      |          |
|   NFS   |----->| FS-Cache |
|         |      |          |--+
+---------+      |          |  |   +--------------+   +--------------+
     |           |          |  |   |              |   |              |
     V           +----------+  +-->|  CacheFiles  |-->|  Ext3        |
+---------+                        |  /var/cache  |   |  /dev/sda6   |
|         |                        +--------------+   +--------------+
|   VFS   |                                ^                     ^
|         |                                |                     |
+---------+                                +--------------+      |
     |                  KERNEL SPACE                      |      |
~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~|~~~~
     |                  USER SPACE                        |      |
     V                                                    |      |
+---------+                                           +--------------+
|         |                                           |              |
| Process |                                           | cachefilesd  |
|         |                                           |              |
+---------+                                           +--------------+

FS-Cache 不遵循在允许访问之前将每个打开的网络文件(netfs 文件)完全加载到缓存中,然后从该缓存而不是从网络文件系统 inode 提供页面的理念,因为:

  1. 必须能够实际地在没有缓存的情况下运行。

  2. 任何可访问文件的大小不得受限于缓存大小。

  3. 所有打开文件(包括映射库)的总大小不得受限于缓存大小。

  4. 用户不应被迫下载整个文件,只为一次性访问其中一小部分(例如通过“file”程序进行的操作)。

它而是根据使用它的网络文件系统的请求,以块为单位提供缓存。

FS-Cache 提供以下功能:

  • 可以同时使用多个缓存。缓存可以通过使用标签明确选择。

  • 缓存可以随时添加/移除,即使在访问过程中也行。

  • 网络文件系统提供了一个接口,允许任何一方从文件中撤销缓存功能((2) 所需)。

  • 网络文件系统的接口尽可能少地返回错误,宁愿让网络文件系统保持不知情。

  • 有三种类型的 cookie:缓存 cookie、卷 cookie 和数据文件 cookie。缓存 cookie 代表整个缓存,通常对网络文件系统不可见;网络文件系统获得一个卷 cookie 来表示文件集合(通常是网络文件系统为超级块获取的内容);数据文件 cookie 用于缓存数据(通常是为 inode 获取的内容)。

  • 卷通过一个键进行匹配。这是一个可打印字符串,用于编码可能需要区分一个超级块与另一个超级块的所有信息。这可能是一个组合,例如单元名称或服务器地址、卷名称或共享路径。它必须是一个有效的路径名。

  • Cookie 通过一个键进行匹配。这是一个二进制块(blob),用于表示卷中的对象(因此卷键无需构成 blob 的一部分)。这可能包括 inode 号和唯一标识符或文件句柄等。

  • 通过将 cookie 标记为“使用中”,可以设置并固定 cookie 资源。这可以防止后台资源被清除。采用定时垃圾回收机制来清除短期内未使用的 cookie,从而减少资源过载。这旨在用于文件打开或关闭时。

    一个 cookie 可以同时被多次标记为“使用中”;每次标记都必须被取消使用。

  • 提供了开始/结束访问函数,以在操作期间延迟缓存撤回,并防止在我们查看结构体时其被释放。

  • 数据 I/O 通过异步 DIO 完成,数据在网络文件系统使用 iov_iter 描述的缓冲区之间传输。

  • 提供了一个失效机制,用于从缓存中丢弃数据,并处理正在进行中访问旧数据的 I/O 操作。

  • Cookie 在释放时可以被“退役”,从而导致对象从缓存中移除。

FS-Cache 的网络文件系统 API 可以在此处找到:

FS-Cache 的缓存后端 API 可以在此处找到:

统计信息

如果 FS-Cache 编译时启用了以下选项:

CONFIG_FSCACHE_STATS=y

它将收集特定统计信息并通过以下路径显示:

/proc/fs/fscache/stats

这显示了 FS-Cache 中可能发生的多个事件的计数。

类别

事件

含义

Cookie

n=N

已分配的数据存储 cookie 数量

v=N

已分配的卷索引 cookie 数量

vcol=N

卷索引键冲突次数

voom=N

分配卷 cookie 时发生 OOM 事件的次数

获取

n=N

已接收的获取 cookie 请求数量

ok=N

成功获取请求的数量

oom=N

因 ENOMEM 失败的获取请求数量

LRU

n=N

当前在 LRU 上的 cookie 数量

exp=N

从 LRU 过期移除的 cookie 数量

rmv=N

从 LRU 移除的 cookie 数量

drp=N

已释放/撤回的 LRU cookie 数量

at=N

下次 LRU 清除的时间(jiffies)

失效

n=N

失效次数

更新

n=N

已接收的更新 cookie 请求数量

rsz=N

调整大小请求数量

rsn=N

跳过的调整大小请求数量

释放

n=N

已接收的释放 cookie 请求数量

rtr=N

具有 retire=true 的释放请求数量

drop=N

不再阻止重新获取的 cookie 数量

无空间

nwr=N

因空间不足而被拒绝的写入请求数量

ncr=N

因空间不足而被拒绝的创建请求数量

cull=N

为腾出空间而清除的对象数量

I/O

rd=N

缓存中的读取操作数量

wr=N

缓存中的写入操作数量

Netfslib 也会添加一些自己的统计计数器。

缓存列表

FS-Cache 提供缓存 cookie 列表:

/proc/fs/fscache/cookies

其显示内容大致如下:

# cat /proc/fs/fscache/caches
CACHE    REF   VOLS  OBJS  ACCES S NAME
======== ===== ===== ===== ===== = ===============
00000001     2     1  2123     1 A default

其中各列的含义是:

描述

缓存

缓存 cookie 调试 ID(也出现在跟踪中)

引用计数

缓存 cookie 上的引用计数

卷数

此缓存中的卷 cookie 数量

对象数

正在使用的缓存对象数量

访问次数

固定缓存的访问次数

状态

状态

名称

缓存的名称。

状态可以是 (-) 非活跃、(P) 准备中、(A) 活跃、(E) 错误或 (W) 撤回中。

卷列表

FS-Cache 提供卷 cookie 列表:

/proc/fs/fscache/volumes

其显示内容大致如下:

VOLUME   REF   nCOOK ACC FL CACHE           KEY
======== ===== ===== === == =============== ================
00000001    55    54   1 00 default         afs,example.com,100058

其中各列的含义是:

描述

卷 cookie 调试 ID(也出现在跟踪中)

引用计数

卷 cookie 上的引用计数

cookie 数

卷中的 cookie 数量

访问计数

固定缓存的访问次数

标志

卷 cookie 上的标志

缓存

缓存名称或“ - ”

卷的索引键

调试

如果启用了 CONFIG_NETFS_DEBUG,FS-Cache 功能和 NETFS 支持可以通过调整以下位置的值来启用运行时调试:

/sys/module/netfs/parameters/debug

这是一个用于启用调试流的位掩码:

0

1

缓存管理

函数入口跟踪

1

2

函数出口跟踪

2

4

通用

3

8

Cookie 管理

函数入口跟踪

4

16

函数出口跟踪

5

32

通用

6-8

(未使用)

9

512

I/O 操作管理

函数入口跟踪

10

1024

函数出口跟踪

11

2048

通用

应将相应的值进行或运算,并将结果写入控制文件。例如:

echo $((1|8|512)) >/sys/module/netfs/parameters/debug

将开启所有函数入口调试。