요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
=================
Cache Backend API
=================
The FS-Cache system provides an API by which actual caches can be supplied to
FS-Cache for it to then serve out to network filesystems and other interested
parties. This API is used by::
#include <linux/fscache-cache.h>.
Overview
========
Interaction with the API is handled on three levels: cache, volume and data
storage, and each level has its own type of cookie object:
======================= =======================
COOKIE C TYPE
======================= =======================
Cache cookie struct fscache_cache
Volume cookie struct fscache_volume
Data storage cookie struct fscache_cookie
======================= =======================
Cookies are used to provide some filesystem data to the cache, manage state and
pin the cache during access in addition to acting as reference points for the
API functions. Each cookie has a debugging ID that is included in trace points
to make it easier to correlate traces. Note, though, that debugging IDs are
simply allocated from incrementing counters and will eventually wrap.
The cache backend and the network filesystem can both ask for cache cookies -
and if they ask for one of the same name, they'll get the same cookie. Volume
and data cookies, however, are created at the behest of the filesystem only.
Cache Cookies
=============
Caches are represented in the API by cache cookies. These are objects of
type::
struct fscache_cache {
void *cache_priv;
unsigned int debug_id;
char *name;
...
};
There are a few fields that the cache backend might be interested in. The
``debug_id`` can be used in tracing to match lines referring to the same cache
and ``name`` is the name the cache was registered with. The ``cache_priv``
member is private data provided by the cache when it is brought online. The
other fields are for internal use.
Registering a Cache
===================
When a cache backend wants to bring a cache online, it should first register
the cache name and that will get it a cache cookie. This is done with::
struct fscache_cache *fscache_acquire_cache(const char *name);
This will look up and potentially create a cache cookie. The cache cookie may
have already been created by a network filesystem looking for it, in which case
that cache cookie will be used. If the cache cookie is not in use by another
cache, it will be moved into the preparing state, otherwise it will return
busy.
If successful, the cache backend can then start setting up the cache. In the
event that the initialisation fails, the cache backend should call::
void fscache_relinquish_cache(struct fscache_cache *cache);
to reset and discard the cookie.
Bringing a Cache Online
=======================
Once the cache is set up, it can be brought online by calling::
int fscache_add_cache(struct fscache_cache *cache,
const struct fscache_cache_ops *ops,
void *cache_priv);
This stores the cache operations table pointer and cache private data into the
cache cookie and moves the cache to the active state, thereby allowing accesses
to take place.
Withdrawing a Cache From Service
================================
The cache backend can withdraw a cache from service by calling this function::
void fscache_withdraw_cache(struct fscache_cache *cache);
This moves the cache to the withdrawn state to prevent new cache- and
volume-level accesses from starting and then waits for outstanding cache-level
accesses to complete.
The cache must then go through the data storage objects it has and tell fscache
to withdraw them, calling::
void fscache_withdraw_cookie(struct fscache_cookie *cookie);
on the cookie that each object belongs to. This schedules the specified cookie
for withdrawal. This gets offloaded to a workqueue. The cache backend can
wait for completion by calling::
void fscache_wait_for_objects(struct fscache_cache *cache);
Once all the cookies are withdrawn, a cache backend can withdraw all the
volumes, calling::
void fscache_withdraw_volume(struct fscache_volume *volume);
to tell fscache that a volume has been withdrawn. This waits for all
outstanding accesses on the volume to complete before returning.
When the cache is completely withdrawn, fscache should be notified by
calling::
void fscache_relinquish_cache(struct fscache_cache *cache);
to clear fields in the cookie and discard the caller's ref on it.
Volume Cookies
==============
Within a cache, the data storage objects are organised into logical volumes.
These are represented in the API as objects of type::
struct fscache_volume {
struct fscache_cache *cache;
void *cache_priv;
unsigned int debug_id;
char *key;
unsigned int key_hash;
...
u8 coherency_len;
u8 coherency[];
};
There are a number of fields here that are of interest to the caching backend:
* ``cache`` - The parent cache cookie.
* ``cache_priv`` - A place for the cache to stash private data.
* ``debug_id`` - A debugging ID for logging in tracepoints.
* ``key`` - A printable string with no '/' characters in it that represents
the index key for the volume. The key is NUL-terminated and padded out to
a multiple of 4 bytes.
* ``key_hash`` - A hash of the index key. This should work out the same, no
matter the cpu arch and endianness.
* ``coherency`` - A piece of coherency data that should be checked when the
volume is bound to in the cache.
* ``coherency_len`` - The amount of data in the coherency buffer.
Data Storage Cookies
====================
A volume is a logical group of data storage objects, each of which is
represented to the network filesystem by a cookie. Cookies are represented in
the API as objects of type::
struct fscache_cookie {
struct fscache_volume *volume;
void *cache_priv;
unsigned long flags;
unsigned int debug_id;
unsigned int inval_counter;
loff_t object_size;
u8 advice;
u32 key_hash;
u8 key_len;
u8 aux_len;
...
};
The fields in the cookie that are of interest to the cache backend are:
* ``volume`` - The parent volume cookie.
* ``cache_priv`` - A place for the cache to stash private data.
* ``flags`` - A collection of bit flags, including:
* FSCACHE_COOKIE_NO_DATA_TO_READ - There is no data available in the
cache to be read as the cookie has been created or invalidated.
* FSCACHE_COOKIE_NEEDS_UPDATE - The coherency data and/or object size has
been changed and needs committing.
* FSCACHE_COOKIE_LOCAL_WRITE - The netfs's data has been modified
locally, so the cache object may be in an incoherent state with respect
to the server.
* FSCACHE_COOKIE_HAVE_DATA - The backend should set this if it
successfully stores data into the cache.
* FSCACHE_COOKIE_RETIRED - The cookie was invalidated when it was
relinquished and the cached data should be discarded.
* ``debug_id`` - A debugging ID for logging in tracepoints.
* ``inval_counter`` - The number of invalidations done on the cookie.
* ``advice`` - Information about how the cookie is to be used.
* ``key_hash`` - A hash of the index key. This should work out the same, no
matter the cpu arch and endianness.
* ``key_len`` - The length of the index key.
* ``aux_len`` - The length of the coherency data buffer.
Each cookie has an index key, which may be stored inline to the cookie or
elsewhere. A pointer to this can be obtained by calling::
void *fscache_get_key(struct fscache_cookie *cookie);
The index key is a binary blob, the storage for which is padded out to a
multiple of 4 bytes.
Each cookie also has a buffer for coherency data. This may also be inline or
detached from the cookie and a pointer is obtained by calling::
void *fscache_get_aux(struct fscache_cookie *cookie);
Cookie Accounting
=================
Data storage cookies are counted and this is used to block cache withdrawal
completion until all objects have been destroyed. The following functions are
provided to the cache to deal with that::
void fscache_count_object(struct fscache_cache *cache);
void fscache_uncount_object(struct fscache_cache *cache);
void fscache_wait_for_objects(struct fscache_cache *cache);
The count function records the allocation of an object in a cache and the
uncount function records its destruction. Warning: by the time the uncount
function returns, the cache may have been destroyed.
The wait function can be used during the withdrawal procedure to wait for
fscache to finish withdrawing all the objects in the cache. When it completes,
there will be no remaining objects referring to the cache object or any volume
objects.
Cache Management API
====================
The cache backend implements the cache management API by providing a table of
operations that fscache can use to manage various aspects of the cache. These
are held in a structure of type::
struct fscache_cache_ops {
const char *name;
...
};
This contains a printable name for the cache backend driver plus a number of
pointers to methods to allow fscache to request management of the cache:
* Set up a volume cookie [optional]::
void (*acquire_volume)(struct fscache_volume *volume);
This method is called when a volume cookie is being created. The caller
holds a cache-level access pin to prevent the cache from going away for
the duration. This method should set up the resources to access a volume
in the cache and should not return until it has done so.
If successful, it can set ``cache_priv`` to its own data.
* Clean up volume cookie [optional]::
void (*free_volume)(struct fscache_volume *volume);
This method is called when a volume cookie is being released if
``cache_priv`` is set.
* Look up a cookie in the cache [mandatory]::
bool (*lookup_cookie)(struct fscache_cookie *cookie);
This method is called to look up/create the resources needed to access the
data storage for a cookie. It is called from a worker thread with a
volume-level access pin in the cache to prevent it from being withdrawn.
True should be returned if successful and false otherwise. If false is
returned, the withdraw_cookie op (see below) will be called.
If lookup fails, but the object could still be created (e.g. it hasn't
been cached before), then::
void fscache_cookie_lookup_negative(
struct fscache_cookie *cookie);
can be called to let the network filesystem proceed and start downloading
stuff whilst the cache backend gets on with the job of creating things.
If successful, ``cookie->cache_priv`` can be set.
* Withdraw an object without any cookie access counts held [mandatory]::
void (*withdraw_cookie)(struct fscache_cookie *cookie);
This method is called to withdraw a cookie from service. It will be
called when the cookie is relinquished by the netfs, withdrawn or culled
by the cache backend or closed after a period of non-use by fscache.
The caller doesn't hold any access pins, but it is called from a
non-reentrant work item to manage races between the various ways
withdrawal can occur.
The cookie will have the ``FSCACHE_COOKIE_RETIRED`` flag set on it if the
associated data is to be removed from the cache.
* Change the size of a data storage object [mandatory]::
void (*resize_cookie)(struct netfs_cache_resources *cres,
loff_t new_size);
This method is called to inform the cache backend of a change in size of
the netfs file due to local truncation. The cache backend should make all
of the changes it needs to make before returning as this is done under the
netfs inode mutex.
The caller holds a cookie-level access pin to prevent a race with
withdrawal and the netfs must have the cookie marked in-use to prevent
garbage collection or culling from removing any resources.
* Invalidate a data storage object [mandatory]::
bool (*invalidate_cookie)(struct fscache_cookie *cookie);
This is called when the network filesystem detects a third-party
modification or when an O_DIRECT write is made locally. This requests
that the cache backend should throw away all the data in the cache for
this object and start afresh. It should return true if successful and
false otherwise.
On entry, new I O/operations are blocked. Once the cache is in a position
to accept I/O again, the backend should release the block by calling::
void fscache_resume_after_invalidation(struct fscache_cookie *cookie);
If the method returns false, caching will be withdrawn for this cookie.
* Prepare to make local modifications to the cache [mandatory]::
void (*prepare_to_write)(struct fscache_cookie *cookie);
This method is called when the network filesystem finds that it is going
to need to modify the contents of the cache due to local writes or
truncations. This gives the cache a chance to note that a cache object
may be incoherent with respect to the server and may need writing back
later. This may also cause the cached data to be scrapped on later
rebinding if not properly committed.
* Begin an operation for the netfs lib [mandatory]::
bool (*begin_operation)(struct netfs_cache_resources *cres,
enum fscache_want_state want_state);
This method is called when an I/O operation is being set up (read, write
or resize). The caller holds an access pin on the cookie and must have
marked the cookie as in-use.
If it can, the backend should attach any resources it needs to keep around
to the netfs_cache_resources object and return true.
If it can't complete the setup, it should return false.
The want_state parameter indicates the state the caller needs the cache
object to be in and what it wants to do during the operation:
* ``FSCACHE_WANT_PARAMS`` - The caller just wants to access cache
object parameters; it doesn't need to do data I/O yet.
* ``FSCACHE_WANT_READ`` - The caller wants to read data.
* ``FSCACHE_WANT_WRITE`` - The caller wants to write to or resize the
cache object.
Note that there won't necessarily be anything attached to the cookie's
cache_priv yet if the cookie is still being created.
Data I/O API
============
A cache backend provides a data I/O API by through the netfs library's ``struct
netfs_cache_ops`` attached to a ``struct netfs_cache_resources`` by the
``begin_operation`` method described above.
See the Documentation/filesystems/netfs_library.rst for a description.
Miscellaneous Functions
=======================
FS-Cache provides some utilities that a cache backend may make use of:
* Note occurrence of an I/O error in a cache::
void fscache_io_error(struct fscache_cache *cache);
This tells FS-Cache that an I/O error occurred in the cache. This
prevents any new I/O from being started on the cache.
This does not actually withdraw the cache. That must be done separately.
* Note cessation of caching on a cookie due to failure::
void fscache_caching_failed(struct fscache_cookie *cookie);
This notes that a the caching that was being done on a cookie failed in
some way, for instance the backing storage failed to be created or
invalidation failed and that no further I/O operations should take place
on it until the cache is reset.
* Count I/O requests::
void fscache_count_read(void);
void fscache_count_write(void);
These record reads and writes from/to the cache. The numbers are
displayed in /proc/fs/fscache/stats.
* Count out-of-space errors::
void fscache_count_no_write_space(void);
void fscache_count_no_create_space(void);
These record ENOSPC errors in the cache, divided into failures of data
writes and failures of filesystem object creations (e.g. mkdir).
* Count objects culled::
void fscache_count_culled(void);
This records the culling of an object.
* Get the cookie from a set of cache resources::
struct fscache_cookie *fscache_cres_cookie(struct netfs_cache_resources *cres)
Pull a pointer to the cookie from the cache resources. This may return a
NULL cookie if no cookie was set.
API Function Reference
======================
.. kernel-doc:: include/linux/fscache-cache.h
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Cache Backend API 개요
1-38FS-Cache는 실제 캐시 구현을 등록하여 네트워크 파일시스템과 다른 사용자가 이용하게 하는 API를 제공합니다. 캐시 백엔드는 `#include <linux/fscache-cache.h>`를 통해 이 API를 사용합니다.
API 상호작용은 cache, volume, data storage의 세 계층에서 이루어지며 각 계층에는 고유한 cookie 객체 형식이 있습니다. cache cookie는 `struct fscache_cache`, volume cookie는 `struct fscache_volume`, data storage cookie는 `struct fscache_cookie`입니다.
cookie는 파일시스템 데이터를 캐시에 제공하고, 상태를 관리하며, 접근 중 캐시가 사라지지 않게 고정하는 동시에 API 함수의 참조 지점 역할을 합니다. 각 cookie에는 trace point에서 같은 객체의 기록을 연결하기 쉬운 debugging ID가 있습니다. 이 ID는 증가 카운터에서 단순 할당하므로 언젠가는 wrap됩니다.
캐시 백엔드와 네트워크 파일시스템은 둘 다 cache cookie를 요청할 수 있습니다. 같은 이름을 요청하면 같은 cookie를 받습니다. 반면 volume cookie와 data cookie는 파일시스템의 요청으로만 생성됩니다.
캐시 전체에서 개별 데이터 객체까지의 API 객체입니다.
.. SPDX-License-Identifier: GPL-2.0
=================
Cache Backend API
=================
The FS-Cache system provides an API by which actual caches can be supplied to
FS-Cache for it to then serve out to network filesystems and other interested
parties. This API is used by::
#include <linux/fscache-cache.h>.
Overview
========
Interaction with the API is handled on three levels: cache, volume and data
storage, and each level has its own type of cookie object:
======================= =======================
COOKIE C TYPE
======================= =======================
Cache cookie struct fscache_cache
Volume cookie struct fscache_volume
Data storage cookie struct fscache_cookie
======================= =======================
Cookies are used to provide some filesystem data to the cache, manage state and
pin the cache during access in addition to acting as reference points for the
API functions. Each cookie has a debugging ID that is included in trace points
to make it easier to correlate traces. Note, though, that debugging IDs are
simply allocated from incrementing counters and will eventually wrap.
The cache backend and the network filesystem can both ask for cache cookies -
and if they ask for one of the same name, they'll get the same cookie. Volume
and data cookies, however, are created at the behest of the filesystem only.
Cache cookie 구조
39-58API에서 캐시는 `struct fscache_cache` 형식의 cache cookie로 표현됩니다. 이 구조체에는 `cache_priv`, `debug_id`, `name`과 내부 필드가 들어 있습니다.
캐시 백엔드가 관심을 가질 필드는 몇 개뿐입니다. `debug_id`는 같은 캐시를 가리키는 trace 행을 연결하는 데 사용할 수 있고, `name`은 캐시를 등록할 때 사용한 이름입니다.
`cache_priv`는 캐시를 online으로 전환할 때 백엔드가 제공한 private data입니다. 그 밖의 필드는 FS-Cache 내부용입니다.
백엔드가 읽거나 제공하는 cache cookie 정보입니다.
Cache Cookies
=============
Caches are represented in the API by cache cookies. These are objects of
type::
struct fscache_cache {
void *cache_priv;
unsigned int debug_id;
char *name;
...
};
There are a few fields that the cache backend might be interested in. The
``debug_id`` can be used in tracing to match lines referring to the same cache
and ``name`` is the name the cache was registered with. The ``cache_priv``
member is private data provided by the cache when it is brought online. The
other fields are for internal use.
캐시 등록
59-80캐시 백엔드가 캐시를 online으로 전환하려면 먼저 캐시 이름을 등록하여 cache cookie를 얻어야 합니다. `struct fscache_cache *fscache_acquire_cache(const char *name);`을 호출합니다.
이 함수는 cache cookie를 조회하고 필요하면 생성합니다. 네트워크 파일시스템이 같은 이름의 캐시를 찾으면서 cookie를 이미 만들었을 수 있으며, 그 경우 기존 cookie를 사용합니다.
다른 캐시가 해당 cookie를 사용하고 있지 않으면 preparing 상태로 옮깁니다. 이미 사용 중이면 busy를 반환합니다.
성공하면 백엔드는 캐시 설정을 시작할 수 있습니다. 초기화에 실패하면 `void fscache_relinquish_cache(struct fscache_cache *cache);`를 호출해 cookie를 초기 상태로 되돌리고 폐기해야 합니다.
이름 기반 cookie 획득부터 준비 상태까지의 흐름입니다.
Registering a Cache
===================
When a cache backend wants to bring a cache online, it should first register
the cache name and that will get it a cache cookie. This is done with::
struct fscache_cache *fscache_acquire_cache(const char *name);
This will look up and potentially create a cache cookie. The cache cookie may
have already been created by a network filesystem looking for it, in which case
that cache cookie will be used. If the cache cookie is not in use by another
cache, it will be moved into the preparing state, otherwise it will return
busy.
If successful, the cache backend can then start setting up the cache. In the
event that the initialisation fails, the cache backend should call::
void fscache_relinquish_cache(struct fscache_cache *cache);
to reset and discard the cookie.
캐시 online 전환
81-94캐시 설정이 끝나면 `fscache_add_cache(cache, ops, cache_priv)`를 호출해 online으로 전환할 수 있습니다.
이 함수는 cache operation table 포인터와 캐시 private data를 cache cookie에 저장하고 캐시를 active 상태로 옮깁니다. 그 결과 캐시 접근을 시작할 수 있습니다.
preparing 상태의 캐시를 접근 가능한 active 상태로 전환합니다.
Bringing a Cache Online
=======================
Once the cache is set up, it can be brought online by calling::
int fscache_add_cache(struct fscache_cache *cache,
const struct fscache_cache_ops *ops,
void *cache_priv);
This stores the cache operations table pointer and cache private data into the
cache cookie and moves the cache to the active state, thereby allowing accesses
to take place.
캐시 서비스 철회
95-132캐시 백엔드는 `fscache_withdraw_cache(cache)`를 호출해 캐시를 서비스에서 철회할 수 있습니다. 이 함수는 캐시를 withdrawn 상태로 옮겨 새로운 cache 계층과 volume 계층 접근이 시작되지 않게 하고, 이미 진행 중인 cache 계층 접근이 완료될 때까지 기다립니다.
그 다음 캐시는 보유한 data storage object를 순회하며 각 객체가 속한 cookie에 `fscache_withdraw_cookie(cookie)`를 호출해야 합니다. 이 호출은 지정한 cookie의 철회를 workqueue에 예약합니다.
백엔드는 `fscache_wait_for_objects(cache)`를 호출해 모든 data storage object의 철회 완료를 기다릴 수 있습니다.
모든 data cookie가 철회되면 각 volume에 `fscache_withdraw_volume(volume)`을 호출해 volume 철회를 알립니다. 이 함수는 해당 volume의 진행 중인 모든 접근이 끝날 때까지 기다린 뒤 반환합니다.
캐시 철회가 완전히 끝나면 `fscache_relinquish_cache(cache)`를 호출해야 합니다. 이 함수는 cookie 필드를 지우고 호출자가 가진 참조를 버립니다.
상위 계층을 닫은 뒤 하위 객체부터 안전하게 정리합니다.
Withdrawing a Cache From Service
================================
The cache backend can withdraw a cache from service by calling this function::
void fscache_withdraw_cache(struct fscache_cache *cache);
This moves the cache to the withdrawn state to prevent new cache- and
volume-level accesses from starting and then waits for outstanding cache-level
accesses to complete.
The cache must then go through the data storage objects it has and tell fscache
to withdraw them, calling::
void fscache_withdraw_cookie(struct fscache_cookie *cookie);
on the cookie that each object belongs to. This schedules the specified cookie
for withdrawal. This gets offloaded to a workqueue. The cache backend can
wait for completion by calling::
void fscache_wait_for_objects(struct fscache_cache *cache);
Once all the cookies are withdrawn, a cache backend can withdraw all the
volumes, calling::
void fscache_withdraw_volume(struct fscache_volume *volume);
to tell fscache that a volume has been withdrawn. This waits for all
outstanding accesses on the volume to complete before returning.
When the cache is completely withdrawn, fscache should be notified by
calling::
void fscache_relinquish_cache(struct fscache_cache *cache);
to clear fields in the cookie and discard the caller's ref on it.
Volume cookie 구조
133-170캐시 안에서 data storage object는 논리 volume으로 구성됩니다. API에서는 `struct fscache_volume` 객체로 표현합니다.
`cache`는 부모 cache cookie이고 `cache_priv`는 캐시 백엔드가 private data를 저장할 공간입니다. `debug_id`는 trace point 로그용 debugging ID입니다.
`key`는 volume의 index key를 나타내는 출력 가능한 문자열입니다. `/` 문자를 포함하지 않으며 NUL로 끝나고 4바이트 배수가 되도록 padding됩니다.
`key_hash`는 index key의 hash입니다. CPU architecture와 endian이 달라도 같은 결과가 나와야 합니다.
`coherency`는 volume을 캐시에 bind할 때 검사해야 하는 coherency data이고, `coherency_len`은 해당 buffer에 들어 있는 데이터 양입니다.
볼륨 식별과 일관성 확인에 필요한 값입니다.
Volume Cookies
==============
Within a cache, the data storage objects are organised into logical volumes.
These are represented in the API as objects of type::
struct fscache_volume {
struct fscache_cache *cache;
void *cache_priv;
unsigned int debug_id;
char *key;
unsigned int key_hash;
...
u8 coherency_len;
u8 coherency[];
};
There are a number of fields here that are of interest to the caching backend:
* ``cache`` - The parent cache cookie.
* ``cache_priv`` - A place for the cache to stash private data.
* ``debug_id`` - A debugging ID for logging in tracepoints.
* ``key`` - A printable string with no '/' characters in it that represents
the index key for the volume. The key is NUL-terminated and padded out to
a multiple of 4 bytes.
* ``key_hash`` - A hash of the index key. This should work out the same, no
matter the cpu arch and endianness.
* ``coherency`` - A piece of coherency data that should be checked when the
volume is bound to in the cache.
* ``coherency_len`` - The amount of data in the coherency buffer.
Data storage cookie 구조
171-243volume은 data storage object의 논리 그룹이며, 네트워크 파일시스템은 각 객체를 cookie로 인식합니다. API에서는 `struct fscache_cookie`로 표현합니다.
`volume`은 부모 volume cookie이고 `cache_priv`는 캐시가 private data를 저장할 공간입니다. `debug_id`는 trace point 로그용 ID이며 `inval_counter`는 이 cookie에 수행된 invalidation 횟수입니다. `object_size`는 객체 크기이고 `advice`는 cookie 사용 방식에 관한 정보입니다.
`flags`에는 여러 bit flag가 들어 있습니다. `FSCACHE_COOKIE_NO_DATA_TO_READ`는 cookie가 생성되었거나 invalidation되어 캐시에서 읽을 데이터가 없음을 뜻합니다. `FSCACHE_COOKIE_NEEDS_UPDATE`는 coherency data 또는 object size가 바뀌어 commit해야 함을 뜻합니다.
`FSCACHE_COOKIE_LOCAL_WRITE`는 netfs 데이터가 로컬에서 수정되어 캐시 객체가 서버와 일관되지 않을 수 있음을 뜻합니다. `FSCACHE_COOKIE_HAVE_DATA`는 백엔드가 데이터를 캐시에 성공적으로 저장했을 때 설정해야 합니다. `FSCACHE_COOKIE_RETIRED`는 cookie를 relinquish할 때 invalidation되었으므로 캐시 데이터를 버려야 함을 뜻합니다.
`key_hash`는 CPU architecture와 endian에 관계없이 같아야 하는 index key hash입니다. `key_len`은 index key 길이이고 `aux_len`은 coherency data buffer 길이입니다.
각 cookie에는 cookie 내부 또는 외부에 저장될 수 있는 index key가 있습니다. `fscache_get_key(cookie)`로 포인터를 얻습니다. index key는 binary blob이며 저장 공간은 4바이트 배수가 되도록 padding됩니다.
각 cookie에는 coherency data buffer도 있습니다. 이 buffer 역시 cookie 내부 또는 분리된 공간에 있을 수 있으며 `fscache_get_aux(cookie)`로 포인터를 얻습니다.
백엔드가 캐시 데이터의 현재 상태를 판단하는 플래그입니다.
Data Storage Cookies
====================
A volume is a logical group of data storage objects, each of which is
represented to the network filesystem by a cookie. Cookies are represented in
the API as objects of type::
struct fscache_cookie {
struct fscache_volume *volume;
void *cache_priv;
unsigned long flags;
unsigned int debug_id;
unsigned int inval_counter;
loff_t object_size;
u8 advice;
u32 key_hash;
u8 key_len;
u8 aux_len;
...
};
The fields in the cookie that are of interest to the cache backend are:
* ``volume`` - The parent volume cookie.
* ``cache_priv`` - A place for the cache to stash private data.
* ``flags`` - A collection of bit flags, including:
* FSCACHE_COOKIE_NO_DATA_TO_READ - There is no data available in the
cache to be read as the cookie has been created or invalidated.
* FSCACHE_COOKIE_NEEDS_UPDATE - The coherency data and/or object size has
been changed and needs committing.
* FSCACHE_COOKIE_LOCAL_WRITE - The netfs's data has been modified
locally, so the cache object may be in an incoherent state with respect
to the server.
* FSCACHE_COOKIE_HAVE_DATA - The backend should set this if it
successfully stores data into the cache.
* FSCACHE_COOKIE_RETIRED - The cookie was invalidated when it was
relinquished and the cached data should be discarded.
* ``debug_id`` - A debugging ID for logging in tracepoints.
* ``inval_counter`` - The number of invalidations done on the cookie.
* ``advice`` - Information about how the cookie is to be used.
* ``key_hash`` - A hash of the index key. This should work out the same, no
matter the cpu arch and endianness.
* ``key_len`` - The length of the index key.
* ``aux_len`` - The length of the coherency data buffer.
Each cookie has an index key, which may be stored inline to the cookie or
elsewhere. A pointer to this can be obtained by calling::
void *fscache_get_key(struct fscache_cookie *cookie);
The index key is a binary blob, the storage for which is padded out to a
multiple of 4 bytes.
Each cookie also has a buffer for coherency data. This may also be inline or
detached from the cookie and a pointer is obtained by calling::
void *fscache_get_aux(struct fscache_cookie *cookie);
Cookie 객체 계수
244-264data storage cookie 수는 cache withdrawal 완료를 모든 객체가 파괴될 때까지 막는 데 사용됩니다. 캐시는 `fscache_count_object(cache)`, `fscache_uncount_object(cache)`, `fscache_wait_for_objects(cache)`를 사용합니다.
count 함수는 캐시에서 객체가 할당되었음을 기록하고 uncount 함수는 객체가 파괴되었음을 기록합니다. 주의할 점은 uncount 함수가 반환할 때에는 캐시 자체가 이미 파괴되었을 수 있다는 것입니다.
withdrawal 절차에서 wait 함수로 FS-Cache가 캐시의 모든 객체 철회를 끝낼 때까지 기다릴 수 있습니다. 완료되면 cache object 또는 어느 volume object를 참조하는 객체도 남지 않습니다.
cache 수명보다 data object가 오래 남지 않도록 보장합니다.
Cookie Accounting
=================
Data storage cookies are counted and this is used to block cache withdrawal
completion until all objects have been destroyed. The following functions are
provided to the cache to deal with that::
void fscache_count_object(struct fscache_cache *cache);
void fscache_uncount_object(struct fscache_cache *cache);
void fscache_wait_for_objects(struct fscache_cache *cache);
The count function records the allocation of an object in a cache and the
uncount function records its destruction. Warning: by the time the uncount
function returns, the cache may have been destroyed.
The wait function can be used during the withdrawal procedure to wait for
fscache to finish withdrawing all the objects in the cache. When it completes,
there will be no remaining objects referring to the cache object or any volume
objects.
Cache management table과 volume callback
265-299캐시 백엔드는 FS-Cache가 캐시의 여러 측면을 관리할 수 있도록 operation table을 제공해 cache management API를 구현합니다. 이 table은 `struct fscache_cache_ops` 형식이며 출력 가능한 백엔드 드라이버 이름과 메서드 포인터를 담습니다.
선택적 `acquire_volume(volume)`은 volume cookie를 만들 때 호출됩니다. 호출자는 작업 동안 캐시가 사라지지 않도록 cache 계층 access pin을 보유합니다. 이 메서드는 캐시 안의 volume에 접근하는 데 필요한 자원을 설정하고 완료할 때까지 반환하지 않아야 합니다. 성공하면 `volume->cache_priv`에 백엔드 데이터를 저장할 수 있습니다.
선택적 `free_volume(volume)`은 volume cookie를 해제할 때 `cache_priv`가 설정되어 있으면 호출됩니다.
volume cookie 생성과 해제에 대응하는 선택적 연산입니다.
Cache Management API
====================
The cache backend implements the cache management API by providing a table of
operations that fscache can use to manage various aspects of the cache. These
are held in a structure of type::
struct fscache_cache_ops {
const char *name;
...
};
This contains a printable name for the cache backend driver plus a number of
pointers to methods to allow fscache to request management of the cache:
* Set up a volume cookie [optional]::
void (*acquire_volume)(struct fscache_volume *volume);
This method is called when a volume cookie is being created. The caller
holds a cache-level access pin to prevent the cache from going away for
the duration. This method should set up the resources to access a volume
in the cache and should not return until it has done so.
If successful, it can set ``cache_priv`` to its own data.
* Clean up volume cookie [optional]::
void (*free_volume)(struct fscache_volume *volume);
This method is called when a volume cookie is being released if
``cache_priv`` is set.
`lookup_cookie` callback
300-322필수 `bool (*lookup_cookie)(struct fscache_cookie *cookie)` 메서드는 cookie의 data storage에 접근하는 데 필요한 자원을 조회하거나 생성합니다. volume이 철회되지 않도록 volume 계층 access pin을 보유한 worker thread에서 호출됩니다.
성공하면 true, 실패하면 false를 반환해야 합니다. false를 반환하면 뒤에서 설명하는 `withdraw_cookie` 연산이 호출됩니다.
조회는 실패했지만 객체를 새로 만들 수 있는 경우, 예를 들어 이전에 캐시된 적이 없는 경우에는 `fscache_cookie_lookup_negative(cookie)`를 호출할 수 있습니다. 그러면 캐시 백엔드가 객체를 만드는 동안 네트워크 파일시스템은 진행하여 데이터 다운로드를 시작할 수 있습니다.
조회 또는 생성에 성공하면 `cookie->cache_priv`를 설정할 수 있습니다.
기존 객체 조회와 비동기 신규 생성의 두 경로입니다.
* Look up a cookie in the cache [mandatory]::
bool (*lookup_cookie)(struct fscache_cookie *cookie);
This method is called to look up/create the resources needed to access the
data storage for a cookie. It is called from a worker thread with a
volume-level access pin in the cache to prevent it from being withdrawn.
True should be returned if successful and false otherwise. If false is
returned, the withdraw_cookie op (see below) will be called.
If lookup fails, but the object could still be created (e.g. it hasn't
been cached before), then::
void fscache_cookie_lookup_negative(
struct fscache_cookie *cookie);
can be called to let the network filesystem proceed and start downloading
stuff whilst the cache backend gets on with the job of creating things.
If successful, ``cookie->cache_priv`` can be set.
`withdraw_cookie` callback
323-338필수 `withdraw_cookie(cookie)` 메서드는 access count를 보유하지 않은 상태에서 cookie를 서비스에서 철회합니다.
netfs가 cookie를 relinquish했을 때, 캐시 백엔드가 철회하거나 cull했을 때, 또는 FS-Cache가 일정 기간 사용하지 않은 cookie를 닫을 때 호출됩니다.
호출자는 access pin을 보유하지 않지만, 여러 철회 경로 사이의 경쟁을 관리하기 위해 재진입하지 않는 work item에서 호출됩니다.
연관 데이터를 캐시에서 제거해야 한다면 cookie에 `FSCACHE_COOKIE_RETIRED` 플래그가 설정되어 있습니다.
하나의 비재진입 work item이 여러 철회 경로를 직렬화합니다.
* Withdraw an object without any cookie access counts held [mandatory]::
void (*withdraw_cookie)(struct fscache_cookie *cookie);
This method is called to withdraw a cookie from service. It will be
called when the cookie is relinquished by the netfs, withdrawn or culled
by the cache backend or closed after a period of non-use by fscache.
The caller doesn't hold any access pins, but it is called from a
non-reentrant work item to manage races between the various ways
withdrawal can occur.
The cookie will have the ``FSCACHE_COOKIE_RETIRED`` flag set on it if the
associated data is to be removed from the cache.
`resize_cookie` callback
339-353필수 `resize_cookie(cres, new_size)` 메서드는 로컬 truncation으로 netfs 파일 크기가 바뀌었음을 캐시 백엔드에 알립니다.
이 호출은 netfs inode mutex 아래에서 이루어지므로 백엔드는 반환하기 전에 필요한 변경을 모두 완료해야 합니다.
호출자는 withdrawal과의 경쟁을 막는 cookie 계층 access pin을 보유합니다. 또한 garbage collection 또는 culling이 자원을 제거하지 않도록 netfs가 cookie를 in-use로 표시해 두어야 합니다.
inode 직렬화와 cookie 수명 보호 아래에서 동기적으로 수행됩니다.
* Change the size of a data storage object [mandatory]::
void (*resize_cookie)(struct netfs_cache_resources *cres,
loff_t new_size);
This method is called to inform the cache backend of a change in size of
the netfs file due to local truncation. The cache backend should make all
of the changes it needs to make before returning as this is done under the
netfs inode mutex.
The caller holds a cookie-level access pin to prevent a race with
withdrawal and the netfs must have the cookie marked in-use to prevent
garbage collection or culling from removing any resources.
`invalidate_cookie` callback
354-371필수 `invalidate_cookie(cookie)`는 네트워크 파일시스템이 제3자 변경을 감지했거나 로컬에서 `O_DIRECT` 쓰기를 수행했을 때 호출됩니다. 캐시 백엔드는 이 객체의 캐시 데이터를 모두 버리고 새로 시작해야 하며, 성공하면 true, 실패하면 false를 반환합니다.
메서드 진입 시 새로운 I/O와 operation은 차단되어 있습니다. 캐시가 다시 I/O를 받을 수 있는 상태가 되면 백엔드는 `fscache_resume_after_invalidation(cookie)`를 호출해 차단을 해제해야 합니다.
메서드가 false를 반환하면 이 cookie에 대한 caching을 철회합니다.
오래된 데이터를 폐기하는 동안 새 I/O를 차단합니다.
* Invalidate a data storage object [mandatory]::
bool (*invalidate_cookie)(struct fscache_cookie *cookie);
This is called when the network filesystem detects a third-party
modification or when an O_DIRECT write is made locally. This requests
that the cache backend should throw away all the data in the cache for
this object and start afresh. It should return true if successful and
false otherwise.
On entry, new I O/operations are blocked. Once the cache is in a position
to accept I/O again, the backend should release the block by calling::
void fscache_resume_after_invalidation(struct fscache_cookie *cookie);
If the method returns false, caching will be withdrawn for this cookie.
`prepare_to_write` callback
372-383필수 `prepare_to_write(cookie)`는 로컬 쓰기나 truncation 때문에 네트워크 파일시스템이 캐시 내용을 수정해야 한다고 판단할 때 호출됩니다.
이 callback은 캐시 객체가 서버와 일관되지 않을 수 있고 나중에 writeback이 필요할 수 있음을 백엔드가 기록할 기회를 줍니다. 변경 상태가 올바르게 commit되지 않으면 나중에 다시 bind할 때 캐시 데이터를 폐기하게 할 수도 있습니다.
서버와 캐시의 일관성 상태를 변경 전에 기록합니다.
* Prepare to make local modifications to the cache [mandatory]::
void (*prepare_to_write)(struct fscache_cookie *cookie);
This method is called when the network filesystem finds that it is going
to need to modify the contents of the cache due to local writes or
truncations. This gives the cache a chance to note that a cache object
may be incoherent with respect to the server and may need writing back
later. This may also cause the cached data to be scrapped on later
rebinding if not properly committed.
`begin_operation`과 요청 상태
384-412필수 `begin_operation(cres, want_state)`는 read, write 또는 resize I/O operation을 설정할 때 호출됩니다. 호출자는 cookie access pin을 보유하고 cookie를 in-use로 표시해 두어야 합니다.
설정할 수 있다면 백엔드는 operation 동안 유지해야 하는 자원을 `netfs_cache_resources` 객체에 연결하고 true를 반환합니다. 설정을 완료할 수 없으면 false를 반환합니다.
`want_state`는 호출자가 캐시 객체에 요구하는 상태와 operation에서 하려는 일을 나타냅니다.
`FSCACHE_WANT_PARAMS`는 data I/O 없이 캐시 객체 매개변수만 접근하려는 요청입니다. `FSCACHE_WANT_READ`는 데이터를 읽으려는 요청입니다. `FSCACHE_WANT_WRITE`는 캐시 객체에 쓰거나 크기를 바꾸려는 요청입니다.
cookie가 아직 생성 중이라면 `cookie->cache_priv`에 반드시 무언가가 연결되어 있으리라는 보장은 없습니다.
operation 시작 시 백엔드가 준비해야 하는 수준입니다.
* Begin an operation for the netfs lib [mandatory]::
bool (*begin_operation)(struct netfs_cache_resources *cres,
enum fscache_want_state want_state);
This method is called when an I/O operation is being set up (read, write
or resize). The caller holds an access pin on the cookie and must have
marked the cookie as in-use.
If it can, the backend should attach any resources it needs to keep around
to the netfs_cache_resources object and return true.
If it can't complete the setup, it should return false.
The want_state parameter indicates the state the caller needs the cache
object to be in and what it wants to do during the operation:
* ``FSCACHE_WANT_PARAMS`` - The caller just wants to access cache
object parameters; it doesn't need to do data I/O yet.
* ``FSCACHE_WANT_READ`` - The caller wants to read data.
* ``FSCACHE_WANT_WRITE`` - The caller wants to write to or resize the
cache object.
Note that there won't necessarily be anything attached to the cookie's
cache_priv yet if the cookie is still being created.
Data I/O API 연결
413-422캐시 백엔드는 앞에서 설명한 `begin_operation` 메서드가 `struct netfs_cache_resources`에 연결하는 netfs library의 `struct netfs_cache_ops`를 통해 data I/O API를 제공합니다.
자세한 설명은 `Documentation/filesystems/netfs_library.rst`를 참고하십시오.
관리 callback이 실제 data I/O operation table을 전달합니다.
Data I/O API
============
A cache backend provides a data I/O API by through the netfs library's ``struct
netfs_cache_ops`` attached to a ``struct netfs_cache_resources`` by the
``begin_operation`` method described above.
See the Documentation/filesystems/netfs_library.rst for a description.
기타 유틸리티 함수
423-475`fscache_io_error(cache)`는 캐시에서 I/O 오류가 발생했음을 FS-Cache에 알립니다. 그 뒤 해당 캐시에서 새 I/O가 시작되지 않습니다. 이 함수가 캐시를 실제로 철회하지는 않으므로 withdrawal은 별도로 수행해야 합니다.
`fscache_caching_failed(cookie)`는 backing storage 생성 실패나 invalidation 실패처럼 cookie에서 수행하던 caching이 실패했음을 기록합니다. 캐시를 reset할 때까지 해당 cookie에서 더 이상의 I/O operation을 수행하지 않아야 함을 나타냅니다.
`fscache_count_read()`와 `fscache_count_write()`는 캐시에서의 read와 캐시로의 write를 기록합니다. 계수는 `/proc/fs/fscache/stats`에 표시됩니다.
`fscache_count_no_write_space()`와 `fscache_count_no_create_space()`는 캐시의 `ENOSPC` 오류를 각각 data write 실패와 `mkdir` 같은 파일시스템 객체 생성 실패로 나누어 기록합니다.
`fscache_count_culled()`는 객체 culling을 기록합니다.
`fscache_cres_cookie(cres)`는 cache resources에서 cookie 포인터를 꺼냅니다. cookie가 설정되지 않았다면 `NULL`을 반환할 수 있습니다.
오류 차단, 실패 기록과 운영 계수를 제공하는 함수입니다.
Miscellaneous Functions
=======================
FS-Cache provides some utilities that a cache backend may make use of:
* Note occurrence of an I/O error in a cache::
void fscache_io_error(struct fscache_cache *cache);
This tells FS-Cache that an I/O error occurred in the cache. This
prevents any new I/O from being started on the cache.
This does not actually withdraw the cache. That must be done separately.
* Note cessation of caching on a cookie due to failure::
void fscache_caching_failed(struct fscache_cookie *cookie);
This notes that a the caching that was being done on a cookie failed in
some way, for instance the backing storage failed to be created or
invalidation failed and that no further I/O operations should take place
on it until the cache is reset.
* Count I/O requests::
void fscache_count_read(void);
void fscache_count_write(void);
These record reads and writes from/to the cache. The numbers are
displayed in /proc/fs/fscache/stats.
* Count out-of-space errors::
void fscache_count_no_write_space(void);
void fscache_count_no_create_space(void);
These record ENOSPC errors in the cache, divided into failures of data
writes and failures of filesystem object creations (e.g. mkdir).
* Count objects culled::
void fscache_count_culled(void);
This records the culling of an object.
* Get the cookie from a set of cache resources::
struct fscache_cookie *fscache_cres_cookie(struct netfs_cache_resources *cres)
Pull a pointer to the cookie from the cache resources. This may return a
NULL cookie if no cookie was set.
API 함수 참조
476-479이 절의 API 함수 참조는 `include/linux/fscache-cache.h`의 kernel-doc 주석에서 생성됩니다.
헤더의 선언과 주석이 렌더링되는 경로입니다.
API Function Reference
======================
.. kernel-doc:: include/linux/fscache-cache.h
요약·해설
backend-api.rst:1-479FS-Cache backend API는 cache, volume, data cookie의 세 계층으로 네트워크 파일시스템의 캐시 저장소를 모델링합니다. 이름으로 공유되는 cache cookie 아래에 volume과 data object를 연결하고, 계층별 access pin과 object count로 online·withdrawal 사이의 수명 경쟁을 막습니다.
백엔드는 `fscache_cache_ops` callback으로 volume 준비, cookie 조회·철회, resize, invalidation, 로컬 쓰기 준비와 I/O operation 시작을 구현합니다. 실제 data I/O는 `begin_operation()`이 `netfs_cache_resources`에 연결한 `netfs_cache_ops`를 통해 netfs library가 수행합니다.
등록부터 I/O와 안전한 철회까지의 핵심 경로입니다.