缓存后端 API¶
FS-Cache 系统提供了一个 API,实际的缓存可以通过该 API 提供给 FS-Cache,然后由 FS-Cache 提供给网络文件系统和其他感兴趣的各方。 此 API 被以下系统使用
#include <linux/fscache-cache.h>.
概述¶
与 API 的交互在三个级别上处理:缓存、卷和数据存储,每个级别都有自己的 cookie 对象类型
COOKIE
C 类型
缓存 cookie
struct fscache_cache
卷 cookie
struct fscache_volume
数据存储 cookie
struct fscache_cookie
Cookie 用于向缓存提供一些文件系统数据,管理状态并在访问期间固定缓存,此外还可以作为 API 函数的参考点。 每个 cookie 都有一个调试 ID,该 ID 包含在跟踪点中,以便更容易关联跟踪。 但是请注意,调试 ID 只是从递增的计数器中分配的,最终会回绕。
缓存后端和网络文件系统都可以请求缓存 cookie - 如果它们请求具有相同名称的 cookie,它们将获得相同的 cookie。 但是,卷 cookie 和数据 cookie 仅应文件系统的请求而创建。
注册缓存¶
当缓存后端想要使缓存上线时,它应该首先注册缓存名称,这将使其获得缓存 cookie。 这是通过以下方式完成的
struct fscache_cache *fscache_acquire_cache(const char *name);
这将查找并可能创建一个缓存 cookie。 缓存 cookie 可能已被寻找它的网络文件系统创建,在这种情况下,将使用该缓存 cookie。 如果缓存 cookie 未被另一个缓存使用,它将被移动到准备状态,否则它将返回繁忙。
如果成功,缓存后端可以开始设置缓存。 如果初始化失败,缓存后端应调用
void fscache_relinquish_cache(struct fscache_cache *cache);
重置并丢弃 cookie。
使缓存上线¶
设置好缓存后,可以通过调用以下命令使其上线
int fscache_add_cache(struct fscache_cache *cache,
const struct fscache_cache_ops *ops,
void *cache_priv);
这会将缓存操作表指针和缓存私有数据存储到缓存 cookie 中,并将缓存移动到活动状态,从而允许进行访问。
从服务中撤回缓存¶
缓存后端可以通过调用此函数从服务中撤回缓存
void fscache_withdraw_cache(struct fscache_cache *cache);
这会将缓存移动到撤回状态,以防止新的缓存级和卷级访问开始,然后等待未完成的缓存级访问完成。
然后,缓存必须遍历其拥有的数据存储对象,并告知 fscache 撤回它们,调用
void fscache_withdraw_cookie(struct fscache_cookie *cookie);
在每个对象所属的 cookie 上。 这会安排指定的 cookie 进行撤回。 这将被卸载到工作队列。 缓存后端可以通过调用以下命令等待完成
void fscache_wait_for_objects(struct fscache_cache *cache);
一旦所有 cookie 都被撤回,缓存后端可以撤回所有卷,调用
void fscache_withdraw_volume(struct fscache_volume *volume);
告知 fscache 卷已被撤回。 这将等待卷上的所有未完成访问完成后再返回。
当缓存完全撤回后,应通过调用以下命令通知 fscache
void fscache_relinquish_cache(struct fscache_cache *cache);
清除 cookie 中的字段并丢弃调用者的引用。
缓存管理 API¶
缓存后端通过提供 fscache 可以用来管理缓存各个方面的操作表来实现缓存管理 API。 这些保存在类型的结构中
struct fscache_cache_ops {
const char *name;
...
};
这包含缓存后端驱动程序的可打印名称,以及指向允许 fscache 请求管理缓存的方法的许多指针
设置卷 cookie [可选]
void (*acquire_volume)(struct fscache_volume *volume);当创建卷 cookie 时会调用此方法。 调用者持有缓存级别的访问锁,以防止缓存在整个过程中消失。 此方法应设置访问缓存中卷的资源,并且在完成之前不应返回。
如果成功,它可以将
cache_priv
设置为其自己的数据。清理卷 cookie [可选]
void (*free_volume)(struct fscache_volume *volume);如果在设置了
cache_priv
的情况下释放卷 cookie,则会调用此方法。在缓存中查找 cookie [强制]
bool (*lookup_cookie)(struct fscache_cookie *cookie);调用此方法来查找/创建访问 cookie 的数据存储所需的资源。 它从工作线程中调用,其中缓存中具有卷级别的访问锁,以防止其被撤回。
如果成功,则应返回 true,否则返回 false。 如果返回 false,则将调用 withdraw_cookie op(参见下文)。
如果查找失败,但仍然可以创建对象(例如,之前没有缓存),则
void fscache_cookie_lookup_negative( struct fscache_cookie *cookie);可以调用以允许网络文件系统继续并开始下载内容,同时缓存后端继续创建内容。
如果成功,可以设置
cookie->cache_priv
。撤回没有任何 cookie 访问计数的对象 [强制]
void (*withdraw_cookie)(struct fscache_cookie *cookie);调用此方法以从服务中撤回 cookie。 当 cookie 被 netfs 放弃、被缓存后端撤回或剔除,或者在 fscache 长时间未使用后关闭时,将调用此方法。
调用者不持有任何访问锁,但它是从不可重入的工作项中调用的,以管理各种撤回方式之间的竞争。
如果应从缓存中删除关联的数据,则 cookie 将设置
FSCACHE_COOKIE_RETIRED
标志。更改数据存储对象的大小 [强制]
void (*resize_cookie)(struct netfs_cache_resources *cres, loff_t new_size);调用此方法以通知缓存后端由于本地截断导致 netfs 文件的大小发生更改。 缓存后端应在返回之前进行所有需要进行的更改,因为这是在 netfs inode 互斥锁下完成的。
调用者持有 cookie 级别的访问锁,以防止与撤回发生竞争,并且 netfs 必须将 cookie 标记为正在使用,以防止垃圾回收或剔除删除任何资源。
使数据存储对象失效 [强制]
bool (*invalidate_cookie)(struct fscache_cookie *cookie);当网络文件系统检测到第三方修改或在本地进行 O_DIRECT 写入时,将调用此方法。 这会请求缓存后端丢弃缓存中此对象的所有数据并重新开始。 如果成功,则应返回 true,否则返回 false。
在进入时,新的 I O/操作被阻止。 一旦缓存能够再次接受 I/O,后端应通过调用以下命令释放该块
void fscache_resume_after_invalidation(struct fscache_cookie *cookie);如果该方法返回 false,则将为此 cookie 撤回缓存。
准备对缓存进行本地修改 [强制]
void (*prepare_to_write)(struct fscache_cookie *cookie);当网络文件系统发现它需要修改缓存的内容(由于本地写入或截断)时,将调用此方法。 这使缓存有机会注意到缓存对象可能与服务器不一致,并且可能需要在以后写回。 如果未正确提交,这也可能导致缓存的数据在以后的重新绑定时被丢弃。
开始 netfs lib 的操作 [强制]
bool (*begin_operation)(struct netfs_cache_resources *cres, enum fscache_want_state want_state);在设置 I/O 操作(读取、写入或调整大小)时会调用此方法。 调用者持有 cookie 上的访问锁,并且必须将 cookie 标记为正在使用。
如果可以,后端应将其需要保留的所有资源附加到 netfs_cache_resources 对象并返回 true。
如果无法完成设置,则应返回 false。
want_state 参数指示调用者需要缓存对象处于的状态以及它希望在操作期间执行的操作
FSCACHE_WANT_PARAMS
- 调用者只想访问缓存对象参数;它不需要进行数据 I/O。
FSCACHE_WANT_READ
- 调用者想要读取数据。
FSCACHE_WANT_WRITE
- 调用者想要写入或调整缓存对象的大小。请注意,如果 cookie 仍在创建中,则不一定有任何内容附加到 cookie 的 cache_priv。
数据 I/O API¶
缓存后端通过 netfs 库的 struct netfs_cache_ops
(通过上面描述的 begin_operation
方法附加到 struct netfs_cache_resources
)提供数据 I/O API。
有关说明,请参见网络文件系统服务库。
其他函数¶
FS-Cache 提供了一些缓存后端可能会使用的实用程序
注意缓存中发生的 I/O 错误
void fscache_io_error(struct fscache_cache *cache);这告诉 FS-Cache 缓存中发生了 I/O 错误。 这可以防止在缓存上启动任何新的 I/O。
这实际上不会撤回缓存。 必须单独完成。
注意由于故障而停止在 cookie 上进行缓存
void fscache_caching_failed(struct fscache_cookie *cookie);这说明在 cookie 上进行的缓存以某种方式失败,例如,后备存储无法创建或失效失败,并且在重置缓存之前不应在其上进行进一步的 I/O 操作。
计数 I/O 请求
void fscache_count_read(void); void fscache_count_write(void);这些记录从缓存读取和写入缓存。 这些数字显示在 /proc/fs/fscache/stats 中。
计数空间不足错误
void fscache_count_no_write_space(void); void fscache_count_no_create_space(void);这些记录缓存中的 ENOSPC 错误,分为数据写入失败和文件系统对象创建失败(例如,mkdir)。
计数剔除的对象
void fscache_count_culled(void);这记录了对象的剔除。
从一组缓存资源中获取 cookie
struct fscache_cookie *fscache_cres_cookie(struct netfs_cache_resources *cres)从缓存资源中提取指向 cookie 的指针。 如果未设置 cookie,则这可能会返回 NULL cookie。
API 函数参考¶
-
enum fscache_cookie_state fscache_cookie_state(struct fscache_cookie *cookie)¶
读取 cookie 的状态
参数
struct fscache_cookie *cookie
要查询的 cookie
说明
获取 cookie 的状态,在 cookie 内容和状态值之间强制执行排序。 与 fscache_set_cookie_state() 配对使用。
-
void *fscache_get_key(struct fscache_cookie *cookie)¶
获取指向 cookie 键的指针
参数
struct fscache_cookie *cookie
要查询的 cookie
说明
返回一个指针,指向存储 cookie 键的位置。
-
void fscache_count_object(struct fscache_cache *cache)¶
告知 fscache 已添加对象
参数
struct fscache_cache *cache
要记帐的缓存
说明
告知 fscache 已将对象添加到缓存中。 这可以防止缓存在对象被取消计数之前拆除缓存结构。
-
void fscache_uncount_object(struct fscache_cache *cache)¶
告知 fscache 已删除对象
参数
struct fscache_cache *cache
要记帐的缓存
说明
告知 fscache 已从缓存中删除对象,并且将不再访问该对象。 在此之后,可能会销毁缓存 cookie。
-
void fscache_wait_for_objects(struct fscache_cache *cache)¶
等待撤回所有对象
参数
struct fscache_cache *cache
要查询的缓存
说明
等待缓存中所有现存对象完成撤回并消失。