通用文件系统缓存

概述

此功能是网络文件系统的通用缓存,但它也可以用于缓存其他内容,例如 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 文件全部加载到缓存中,然后再允许访问,然后从该缓存而不是 netfs inode 中提供页面的想法,因为

  1. 在没有缓存的情况下操作必须是可行的。

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

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

  4. 用户不应被迫下载整个文件,而只是为了对文件的一小部分进行一次性访问(例如使用“file”程序)。

相反,它会在 netfs 使用它时按块提供缓存。

FS-Cache 提供以下功能

  • 可以一次使用多个缓存。可以通过使用标签显式选择缓存。

  • 可以随时添加/删除缓存,即使在访问时也是如此。

  • 向 netfs 提供了一个接口,允许任何一方从文件中撤回缓存功能(第 (2) 点要求)。

  • 到 netfs 的接口返回的错误尽可能少,宁愿让 netfs 不知情。

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

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

  • Cookie 使用键进行匹配。这是一个二进制 blob,用于表示卷中的对象(因此卷键不需要构成 blob 的一部分)。这可能包括诸如 inode 编号和唯一标识符或文件句柄之类的内容。

  • Cookie 资源通过标记 cookie 为使用中来设置和固定。这可以防止支持资源被删除。采用定时垃圾回收来消除短时间内未使用的 cookie,从而减少资源过载。这旨在在打开或关闭文件时使用。

    一个 cookie 可以同时多次标记为使用中;每个标记都必须是未使用的。

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

  • 数据 I/O 通过异步 DIO 从/向 netfs 使用 iov_iter 描述的缓冲区完成。

  • 提供无效机制以从缓存中丢弃数据,并处理正在进行的访问旧数据的 I/O。

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

FS-Cache 的 netfs API 可以在以下位置找到

FS-Cache 的缓存后端 API 可以在以下位置找到

统计信息

如果 FS-Cache 在启用以下选项的情况下编译

CONFIG_FSCACHE_STATS=y

那么它将收集某些统计信息并通过以下方式显示它们

/proc/fs/fscache/stats

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

类别

事件

含义

Cookies

n=N

分配的数据存储 cookie 的数量

v=N

分配的卷索引 cookie 的数量

vcol=N

卷索引键冲突的数量

voom=N

分配卷 cookie 时 OOM 事件的数量

Acquire

n=N

看到的获取 cookie 请求的数量

ok=N

成功的 acq 请求的数量

oom=N

由于 ENOMEM 而失败的 acq 请求的数量

LRU

n=N

当前在 LRU 上的 cookie 数量

exp=N

从 LRU 过期的 cookie 数量

rmv=N

从 LRU 中删除的 cookie 数量

drp=N

放弃/撤回的 LRU cookie 数量

at=N

下次 LRU 删除的时间(jiffies)

Invals

n=N

无效的数量

Updates

n=N

看到的更新 cookie 请求的数量

rsz=N

调整大小请求的数量

rsn=N

跳过的调整大小请求的数量

Relinqs

n=N

看到的放弃 cookie 请求的数量

rtr=N

带有 retire=true 的 rlq 请求的数量

drop=N

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

NoSpace

nwr=N

由于空间不足而拒绝的写入请求数量

ncr=N

由于空间不足而拒绝的创建请求数量

cull=N

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

IO

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

其中列是

描述

CACHE

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

REF

缓存 cookie 上的引用次数

VOLS

此缓存中的卷 cookie 的数量

OBJS

正在使用的缓存对象的数量

ACCES

固定缓存的访问次数

S

状态

NAME

缓存的名称。

状态可以是 (-) 不活动、(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

其中列是

描述

VOLUME

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

REF

卷 cookie 上的引用次数

nCOOK

卷中的 cookie 数量

ACC

固定缓存的访问次数

FL

卷 cookie 上的标志

CACHE

缓存的名称或“-”

KEY

卷的索引键

调试

如果启用了 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

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