← Documents Documentation/filesystems/caching/netfs-api.rst GitHub 원문 ↗

Linux 6.18.37 · Filesystems

Network Filesystem Caching API

Fscache volume·data cookie 등록, in-use 수명, DIO, coherency·invalidation과 writeback API의 전문 번역입니다.

Source pathDocumentation/filesystems/caching/netfs-api.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

netfs-api.rst:1-452

Fscache netfs API는 superblock을 volume cookie로, inode의 data storage object를 data cookie로 모델링합니다. key는 객체를 식별하고 coherency data와 object size는 저장 데이터의 유효성을 검증합니다. cookie는 접근 전에 in-use로 표시하며, 실제 I/O 전에 operation을 시작해 backend 자원을 pin합니다.

직접 read·write는 `iov_iter` 기반 DIO이고 callback 유무에 따라 비동기 또는 동기로 실행됩니다. 원격 변경은 invalidation counter와 `-ESTALE`로 진행 중 read를 차단하며, dirty folio writeback과 로컬 수정 캐싱은 inode·page 표시를 통해 종료 중 자원 접근과 경쟁 DIO를 방지합니다.

Netfs cache 객체의 전체 수명
`fscache_acquire_volume()`으로 superblock 범위 등록`fscache_acquire_cookie()`로 inode 데이터 객체 등록open·dirty 구간에 cookie in-use와 cache resource pin 유지netfslib 또는 직접 Fscache DIO API로 read·write·resizecoherency update 또는 remote change invalidation 수행writeback·page release 표시를 모두 정리data cookie를 먼저, volume cookie를 나중에 반환

등록, 사용, I/O, 일관성 처리, writeback과 반환을 한 흐름으로 연결합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ==============================
4 Network Filesystem Caching API
5 ==============================
6
7 Fscache provides an API by which a network filesystem can make use of local
8 caching facilities. The API is arranged around a number of principles:
9
10 (1) A cache is logically organised into volumes and data storage objects
11 within those volumes.
12
13 (2) Volumes and data storage objects are represented by various types of
14 cookie.
15
16 (3) Cookies have keys that distinguish them from their peers.
17
18 (4) Cookies have coherency data that allows a cache to determine if the
19 cached data is still valid.
20
21 (5) I/O is done asynchronously where possible.
22
23 This API is used by::
24
25 #include <linux/fscache.h>.
26
27 .. This document contains the following sections:
28
29 (1) Overview
30 (2) Volume registration
31 (3) Data file registration
32 (4) Declaring a cookie to be in use
33 (5) Resizing a data file (truncation)
34 (6) Data I/O API
35 (7) Data file coherency
36 (8) Data file invalidation
37 (9) Write back resource management
38 (10) Caching of local modifications
39 (11) Page release and invalidation
40
41
42 Overview
43 ========
44
45 The fscache hierarchy is organised on two levels from a network filesystem's
46 point of view. The upper level represents "volumes" and the lower level
47 represents "data storage objects". These are represented by two types of
48 cookie, hereafter referred to as "volume cookies" and "cookies".
49
50 A network filesystem acquires a volume cookie for a volume using a volume key,
51 which represents all the information that defines that volume (e.g. cell name
52 or server address, volume ID or share name). This must be rendered as a
53 printable string that can be used as a directory name (ie. no '/' characters
54 and shouldn't begin with a '.'). The maximum name length is one less than the
55 maximum size of a filename component (allowing the cache backend one char for
56 its own purposes).
57
58 A filesystem would typically have a volume cookie for each superblock.
59
60 The filesystem then acquires a cookie for each file within that volume using an
61 object key. Object keys are binary blobs and only need to be unique within
62 their parent volume. The cache backend is responsible for rendering the binary
63 blob into something it can use and may employ hash tables, trees or whatever to
64 improve its ability to find an object. This is transparent to the network
65 filesystem.
66
67 A filesystem would typically have a cookie for each inode, and would acquire it
68 in iget and relinquish it when evicting the cookie.
69
70 Once it has a cookie, the filesystem needs to mark the cookie as being in use.
71 This causes fscache to send the cache backend off to look up/create resources
72 for the cookie in the background, to check its coherency and, if necessary, to
73 mark the object as being under modification.
74
75 A filesystem would typically "use" the cookie in its file open routine and
76 unuse it in file release and it needs to use the cookie around calls to
77 truncate the cookie locally. It *also* needs to use the cookie when the
78 pagecache becomes dirty and unuse it when writeback is complete. This is
79 slightly tricky, and provision is made for it.
80
81 When performing a read, write or resize on a cookie, the filesystem must first
82 begin an operation. This copies the resources into a holding struct and puts
83 extra pins into the cache to stop cache withdrawal from tearing down the
84 structures being used. The actual operation can then be issued and conflicting
85 invalidations can be detected upon completion.
86
87 The filesystem is expected to use netfslib to access the cache, but that's not
88 actually required and it can use the fscache I/O API directly.
89
90
91 Volume Registration
92 ===================
93
94 The first step for a network filesystem is to acquire a volume cookie for the
95 volume it wants to access::
96
97 struct fscache_volume *
98 fscache_acquire_volume(const char *volume_key,
99 const char *cache_name,
100 const void *coherency_data,
101 size_t coherency_len);
102
103 This function creates a volume cookie with the specified volume key as its name
104 and notes the coherency data.
105
106 The volume key must be a printable string with no '/' characters in it. It
107 should begin with the name of the filesystem and should be no longer than 254
108 characters. It should uniquely represent the volume and will be matched with
109 what's stored in the cache.
110
111 The caller may also specify the name of the cache to use. If specified,
112 fscache will look up or create a cache cookie of that name and will use a cache
113 of that name if it is online or comes online. If no cache name is specified,
114 it will use the first cache that comes to hand and set the name to that.
115
116 The specified coherency data is stored in the cookie and will be matched
117 against coherency data stored on disk. The data pointer may be NULL if no data
118 is provided. If the coherency data doesn't match, the entire cache volume will
119 be invalidated.
120
121 This function can return errors such as EBUSY if the volume key is already in
122 use by an acquired volume or ENOMEM if an allocation failure occurred. It may
123 also return a NULL volume cookie if fscache is not enabled. It is safe to
124 pass a NULL cookie to any function that takes a volume cookie. This will
125 cause that function to do nothing.
126
127
128 When the network filesystem has finished with a volume, it should relinquish it
129 by calling::
130
131 void fscache_relinquish_volume(struct fscache_volume *volume,
132 const void *coherency_data,
133 bool invalidate);
134
135 This will cause the volume to be committed or removed, and if sealed the
136 coherency data will be set to the value supplied. The amount of coherency data
137 must match the length specified when the volume was acquired. Note that all
138 data cookies obtained in this volume must be relinquished before the volume is
139 relinquished.
140
141
142 Data File Registration
143 ======================
144
145 Once it has a volume cookie, a network filesystem can use it to acquire a
146 cookie for data storage::
147
148 struct fscache_cookie *
149 fscache_acquire_cookie(struct fscache_volume *volume,
150 u8 advice,
151 const void *index_key,
152 size_t index_key_len,
153 const void *aux_data,
154 size_t aux_data_len,
155 loff_t object_size)
156
157 This creates the cookie in the volume using the specified index key. The index
158 key is a binary blob of the given length and must be unique for the volume.
159 This is saved into the cookie. There are no restrictions on the content, but
160 its length shouldn't exceed about three quarters of the maximum filename length
161 to allow for encoding.
162
163 The caller should also pass in a piece of coherency data in aux_data. A buffer
164 of size aux_data_len will be allocated and the coherency data copied in. It is
165 assumed that the size is invariant over time. The coherency data is used to
166 check the validity of data in the cache. Functions are provided by which the
167 coherency data can be updated.
168
169 The file size of the object being cached should also be provided. This may be
170 used to trim the data and will be stored with the coherency data.
171
172 This function never returns an error, though it may return a NULL cookie on
173 allocation failure or if fscache is not enabled. It is safe to pass in a NULL
174 volume cookie and pass the NULL cookie returned to any function that takes it.
175 This will cause that function to do nothing.
176
177
178 When the network filesystem has finished with a cookie, it should relinquish it
179 by calling::
180
181 void fscache_relinquish_cookie(struct fscache_cookie *cookie,
182 bool retire);
183
184 This will cause fscache to either commit the storage backing the cookie or
185 delete it.
186
187
188 Marking A Cookie In-Use
189 =======================
190
191 Once a cookie has been acquired by a network filesystem, the filesystem should
192 tell fscache when it intends to use the cookie (typically done on file open)
193 and should say when it has finished with it (typically on file close)::
194
195 void fscache_use_cookie(struct fscache_cookie *cookie,
196 bool will_modify);
197 void fscache_unuse_cookie(struct fscache_cookie *cookie,
198 const void *aux_data,
199 const loff_t *object_size);
200
201 The *use* function tells fscache that it will use the cookie and, additionally,
202 indicate if the user is intending to modify the contents locally. If not yet
203 done, this will trigger the cache backend to go and gather the resources it
204 needs to access/store data in the cache. This is done in the background, and
205 so may not be complete by the time the function returns.
206
207 The *unuse* function indicates that a filesystem has finished using a cookie.
208 It optionally updates the stored coherency data and object size and then
209 decreases the in-use counter. When the last user unuses the cookie, it is
210 scheduled for garbage collection. If not reused within a short time, the
211 resources will be released to reduce system resource consumption.
212
213 A cookie must be marked in-use before it can be accessed for read, write or
214 resize - and an in-use mark must be kept whilst there is dirty data in the
215 pagecache in order to avoid an oops due to trying to open a file during process
216 exit.
217
218 Note that in-use marks are cumulative. For each time a cookie is marked
219 in-use, it must be unused.
220
221
222 Resizing A Data File (Truncation)
223 =================================
224
225 If a network filesystem file is resized locally by truncation, the following
226 should be called to notify the cache::
227
228 void fscache_resize_cookie(struct fscache_cookie *cookie,
229 loff_t new_size);
230
231 The caller must have first marked the cookie in-use. The cookie and the new
232 size are passed in and the cache is synchronously resized. This is expected to
233 be called from ``->setattr()`` inode operation under the inode lock.
234
235
236 Data I/O API
237 ============
238
239 To do data I/O operations directly through a cookie, the following functions
240 are available::
241
242 int fscache_begin_read_operation(struct netfs_cache_resources *cres,
243 struct fscache_cookie *cookie);
244 int fscache_read(struct netfs_cache_resources *cres,
245 loff_t start_pos,
246 struct iov_iter *iter,
247 enum netfs_read_from_hole read_hole,
248 netfs_io_terminated_t term_func,
249 void *term_func_priv);
250 int fscache_write(struct netfs_cache_resources *cres,
251 loff_t start_pos,
252 struct iov_iter *iter,
253 netfs_io_terminated_t term_func,
254 void *term_func_priv);
255
256 The *begin* function sets up an operation, attaching the resources required to
257 the cache resources block from the cookie. Assuming it doesn't return an error
258 (for instance, it will return -ENOBUFS if given a NULL cookie, but otherwise do
259 nothing), then one of the other two functions can be issued.
260
261 The *read* and *write* functions initiate a direct-IO operation. Both take the
262 previously set up cache resources block, an indication of the start file
263 position, and an I/O iterator that describes buffer and indicates the amount of
264 data.
265
266 The read function also takes a parameter to indicate how it should handle a
267 partially populated region (a hole) in the disk content. This may be to ignore
268 it, skip over an initial hole and place zeros in the buffer or give an error.
269
270 The read and write functions can be given an optional termination function that
271 will be run on completion::
272
273 typedef
274 void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error,
275 bool was_async);
276
277 If a termination function is given, the operation will be run asynchronously
278 and the termination function will be called upon completion. If not given, the
279 operation will be run synchronously. Note that in the asynchronous case, it is
280 possible for the operation to complete before the function returns.
281
282 Both the read and write functions end the operation when they complete,
283 detaching any pinned resources.
284
285 The read operation will fail with ESTALE if invalidation occurred whilst the
286 operation was ongoing.
287
288
289 Data File Coherency
290 ===================
291
292 To request an update of the coherency data and file size on a cookie, the
293 following should be called::
294
295 void fscache_update_cookie(struct fscache_cookie *cookie,
296 const void *aux_data,
297 const loff_t *object_size);
298
299 This will update the cookie's coherency data and/or file size.
300
301
302 Data File Invalidation
303 ======================
304
305 Sometimes it will be necessary to invalidate an object that contains data.
306 Typically this will be necessary when the server informs the network filesystem
307 of a remote third-party change - at which point the filesystem has to throw
308 away the state and cached data that it had for an file and reload from the
309 server.
310
311 To indicate that a cache object should be invalidated, the following should be
312 called::
313
314 void fscache_invalidate(struct fscache_cookie *cookie,
315 const void *aux_data,
316 loff_t size,
317 unsigned int flags);
318
319 This increases the invalidation counter in the cookie to cause outstanding
320 reads to fail with -ESTALE, sets the coherency data and file size from the
321 information supplied, blocks new I/O on the cookie and dispatches the cache to
322 go and get rid of the old data.
323
324 Invalidation runs asynchronously in a worker thread so that it doesn't block
325 too much.
326
327
328 Write-Back Resource Management
329 ==============================
330
331 To write data to the cache from network filesystem writeback, the cache
332 resources required need to be pinned at the point the modification is made (for
333 instance when the page is marked dirty) as it's not possible to open a file in
334 a thread that's exiting.
335
336 The following facilities are provided to manage this:
337
338 * An inode flag, ``I_PINNING_FSCACHE_WB``, is provided to indicate that an
339 in-use is held on the cookie for this inode. It can only be changed if the
340 the inode lock is held.
341
342 * A flag, ``unpinned_fscache_wb`` is placed in the ``writeback_control``
343 struct that gets set if ``__writeback_single_inode()`` clears
344 ``I_PINNING_FSCACHE_WB`` because all the dirty pages were cleared.
345
346 To support this, the following functions are provided::
347
348 bool fscache_dirty_folio(struct address_space *mapping,
349 struct folio *folio,
350 struct fscache_cookie *cookie);
351 void fscache_unpin_writeback(struct writeback_control *wbc,
352 struct fscache_cookie *cookie);
353 void fscache_clear_inode_writeback(struct fscache_cookie *cookie,
354 struct inode *inode,
355 const void *aux);
356
357 The *set* function is intended to be called from the filesystem's
358 ``dirty_folio`` address space operation. If ``I_PINNING_FSCACHE_WB`` is not
359 set, it sets that flag and increments the use count on the cookie (the caller
360 must already have called ``fscache_use_cookie()``).
361
362 The *unpin* function is intended to be called from the filesystem's
363 ``write_inode`` superblock operation. It cleans up after writing by unusing
364 the cookie if unpinned_fscache_wb is set in the writeback_control struct.
365
366 The *clear* function is intended to be called from the netfs's ``evict_inode``
367 superblock operation. It must be called *after*
368 ``truncate_inode_pages_final()``, but *before* ``clear_inode()``. This cleans
369 up any hanging ``I_PINNING_FSCACHE_WB``. It also allows the coherency data to
370 be updated.
371
372
373 Caching of Local Modifications
374 ==============================
375
376 If a network filesystem has locally modified data that it wants to write to the
377 cache, it needs to mark the pages to indicate that a write is in progress, and
378 if the mark is already present, it needs to wait for it to be removed first
379 (presumably due to an already in-progress operation). This prevents multiple
380 competing DIO writes to the same storage in the cache.
381
382 Firstly, the netfs should determine if caching is available by doing something
383 like::
384
385 bool caching = fscache_cookie_enabled(cookie);
386
387 If caching is to be attempted, pages should be waited for and then marked using
388 the following functions provided by the netfs helper library::
389
390 void set_page_fscache(struct page *page);
391 void wait_on_page_fscache(struct page *page);
392 int wait_on_page_fscache_killable(struct page *page);
393
394 Once all the pages in the span are marked, the netfs can ask fscache to
395 schedule a write of that region::
396
397 void fscache_write_to_cache(struct fscache_cookie *cookie,
398 struct address_space *mapping,
399 loff_t start, size_t len, loff_t i_size,
400 netfs_io_terminated_t term_func,
401 void *term_func_priv,
402 bool caching)
403
404 And if an error occurs before that point is reached, the marks can be removed
405 by calling::
406
407 void fscache_clear_page_bits(struct address_space *mapping,
408 loff_t start, size_t len,
409 bool caching)
410
411 In these functions, a pointer to the mapping to which the source pages are
412 attached is passed in and start and len indicate the size of the region that's
413 going to be written (it doesn't have to align to page boundaries necessarily,
414 but it does have to align to DIO boundaries on the backing filesystem). The
415 caching parameter indicates if caching should be skipped, and if false, the
416 functions do nothing.
417
418 The write function takes some additional parameters: the cookie representing
419 the cache object to be written to, i_size indicates the size of the netfs file
420 and term_func indicates an optional completion function, to which
421 term_func_priv will be passed, along with the error or amount written.
422
423 Note that the write function will always run asynchronously and will unmark all
424 the pages upon completion before calling term_func.
425
426
427 Page Release and Invalidation
428 =============================
429
430 Fscache keeps track of whether we have any data in the cache yet for a cache
431 object we've just created. It knows it doesn't have to do any reading until it
432 has done a write and then the page it wrote from has been released by the VM,
433 after which it *has* to look in the cache.
434
435 To inform fscache that a page might now be in the cache, the following function
436 should be called from the ``release_folio`` address space op::
437
438 void fscache_note_page_release(struct fscache_cookie *cookie);
439
440 if the page has been released (ie. release_folio returned true).
441
442 Page release and page invalidation should also wait for any mark left on the
443 page to say that a DIO write is underway from that page::
444
445 void wait_on_page_fscache(struct page *page);
446 int wait_on_page_fscache_killable(struct page *page);
447
448
449 API Function Reference
450 ======================
451
452 .. kernel-doc:: include/linux/fscache.h
453

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

네트워크 파일시스템 캐싱 API의 원칙

1-40

Fscache는 네트워크 파일시스템이 로컬 캐싱 기능을 사용할 수 있게 하는 API를 제공합니다. 캐시는 논리적으로 volume과 그 안의 data storage object로 구성되며, 이 둘은 여러 종류의 cookie로 표현됩니다.

각 cookie에는 같은 계층의 다른 cookie와 구별하는 key가 있습니다. 또한 디스크에 저장된 캐시 데이터가 아직 유효한지를 판정할 coherency data를 가지며, 가능한 I/O는 비동기로 실행합니다.

이 API를 사용하는 코드는 `#include <linux/fscache.h>`를 포함합니다. 원문의 주석 목차는 overview, volume·data file 등록, cookie 사용 선언, truncation, 데이터 I/O, coherency·invalidation, writeback 자원 관리, 로컬 수정 캐싱, page release·invalidation의 11개 주제를 열거합니다.

Fscache API의 기본 모델
캐시를 volume과 data storage object로 논리 구성각 계층을 volume cookie와 data cookie로 표현key로 동급 객체를 구별coherency data로 저장 데이터의 유효성 판정가능한 I/O를 비동기로 실행

원문의 다섯 원칙을 객체 구성에서 I/O 실행까지의 흐름으로 정리합니다.

.. SPDX-License-Identifier: GPL-2.0

==============================
Network Filesystem Caching API
==============================

Fscache provides an API by which a network filesystem can make use of local
caching facilities.  The API is arranged around a number of principles:

 (1) A cache is logically organised into volumes and data storage objects
     within those volumes.

 (2) Volumes and data storage objects are represented by various types of
     cookie.

 (3) Cookies have keys that distinguish them from their peers.

 (4) Cookies have coherency data that allows a cache to determine if the
     cached data is still valid.

 (5) I/O is done asynchronously where possible.

This API is used by::

        #include <linux/fscache.h>.

.. This document contains the following sections:

         (1) Overview
         (2) Volume registration
         (3) Data file registration
         (4) Declaring a cookie to be in use
         (5) Resizing a data file (truncation)
         (6) Data I/O API
         (7) Data file coherency
         (8) Data file invalidation
         (9) Write back resource management
        (10) Caching of local modifications
        (11) Page release and invalidation

계층, key, in-use와 operation

41-90

네트워크 파일시스템에서 본 fscache 계층은 두 단계입니다. 위 단계는 volume, 아래 단계는 data storage object이며 각각 volume cookie와 일반 cookie로 표현됩니다.

volume cookie는 volume을 정의하는 모든 정보, 예를 들어 cell name이나 server address와 volume ID 또는 share name을 담은 volume key로 얻습니다. 이 key는 디렉터리 이름으로 쓸 수 있는 출력 가능한 문자열이어야 하므로 `/`를 포함할 수 없고 `.`으로 시작하지 않는 편이 좋습니다. 최대 길이는 파일명 구성요소의 최대 크기보다 한 글자 짧아야 하며, 남은 한 글자는 cache backend가 자체 목적으로 사용합니다.

일반적으로 파일시스템은 superblock마다 volume cookie 하나를 둡니다. 그 volume 안의 각 파일에는 object key로 cookie를 얻습니다. object key는 부모 volume 안에서만 고유하면 되는 binary blob입니다. backend가 이 blob을 사용 가능한 표현으로 바꾸고 hash table이나 tree 등 적절한 검색 구조를 선택하므로 이 과정은 네트워크 파일시스템에 투명합니다.

보통 inode마다 cookie 하나를 두고 `iget`에서 획득하며 inode를 축출할 때 반환합니다. cookie를 얻은 뒤에는 in-use로 표시해야 합니다. 그러면 fscache가 backend에 자원 검색·생성을 비동기로 요청하고 coherency를 검사하며, 필요하면 객체가 수정 중임을 표시합니다.

파일 open에서 cookie를 use하고 release에서 unuse하는 것이 일반적입니다. 로컬 truncation 호출을 감싸는 동안에도 use해야 하며, pagecache가 dirty가 된 시점부터 writeback이 끝날 때까지도 in-use 표시를 유지해야 합니다.

cookie를 read, write 또는 resize하려면 먼저 operation을 시작합니다. 이 단계는 필요한 자원을 보관 구조체에 복사하고 cache withdrawal이 사용 중 구조를 해체하지 못하도록 추가 pin을 겁니다. 실제 작업이 끝날 때 충돌한 invalidation이 있었는지도 감지할 수 있습니다.

캐시 접근에는 netfslib 사용이 권장되지만 필수는 아니며, 파일시스템이 fscache I/O API를 직접 호출할 수도 있습니다.

cookie 수명과 I/O 준비
superblock용 volume cookie 획득inode용 object key로 data cookie 획득파일 open·dirty page 구간에서 cookie를 in-use로 표시read·write·resize 전에 operation을 시작하고 자원 pin작업 완료 시 invalidation 충돌 확인과 pin 해제inode 축출 전에 cookie 반환

volume 획득부터 operation 종료까지의 일반적인 네트워크 파일시스템 경로입니다.


Overview
========

The fscache hierarchy is organised on two levels from a network filesystem's
point of view.  The upper level represents "volumes" and the lower level
represents "data storage objects".  These are represented by two types of
cookie, hereafter referred to as "volume cookies" and "cookies".

A network filesystem acquires a volume cookie for a volume using a volume key,
which represents all the information that defines that volume (e.g. cell name
or server address, volume ID or share name).  This must be rendered as a
printable string that can be used as a directory name (ie. no '/' characters
and shouldn't begin with a '.').  The maximum name length is one less than the
maximum size of a filename component (allowing the cache backend one char for
its own purposes).

A filesystem would typically have a volume cookie for each superblock.

The filesystem then acquires a cookie for each file within that volume using an
object key.  Object keys are binary blobs and only need to be unique within
their parent volume.  The cache backend is responsible for rendering the binary
blob into something it can use and may employ hash tables, trees or whatever to
improve its ability to find an object.  This is transparent to the network
filesystem.

A filesystem would typically have a cookie for each inode, and would acquire it
in iget and relinquish it when evicting the cookie.

Once it has a cookie, the filesystem needs to mark the cookie as being in use.
This causes fscache to send the cache backend off to look up/create resources
for the cookie in the background, to check its coherency and, if necessary, to
mark the object as being under modification.

A filesystem would typically "use" the cookie in its file open routine and
unuse it in file release and it needs to use the cookie around calls to
truncate the cookie locally.  It *also* needs to use the cookie when the
pagecache becomes dirty and unuse it when writeback is complete.  This is
slightly tricky, and provision is made for it.

When performing a read, write or resize on a cookie, the filesystem must first
begin an operation.  This copies the resources into a holding struct and puts
extra pins into the cache to stop cache withdrawal from tearing down the
structures being used.  The actual operation can then be issued and conflicting
invalidations can be detected upon completion.

The filesystem is expected to use netfslib to access the cache, but that's not
actually required and it can use the fscache I/O API directly.

Volume 등록과 반환

91-141

네트워크 파일시스템의 첫 단계는 `fscache_acquire_volume()`으로 접근할 volume의 cookie를 얻는 것입니다. 인자는 `volume_key`, 선택할 `cache_name`, coherency data와 그 길이입니다. 함수는 volume key를 이름으로 삼아 volume cookie를 만들고 coherency data를 기록합니다.

`volume_key`는 `/`가 없는 출력 가능한 문자열이어야 하고 파일시스템 이름으로 시작해야 하며 254자를 넘지 않아야 합니다. 캐시에 저장된 key와 비교되므로 해당 volume을 고유하게 표현해야 합니다.

호출자는 사용할 cache의 이름도 지정할 수 있습니다. 이름을 지정하면 fscache는 그 이름의 cache cookie를 찾거나 만들고, 해당 cache가 online이거나 이후 online이 되면 사용합니다. 이름을 생략하면 먼저 사용 가능한 cache를 선택하고 그 이름을 설정합니다.

coherency data는 cookie에 보관되어 디스크의 값과 비교됩니다. 데이터가 없으면 포인터를 `NULL`로 줄 수 있습니다. 값이 일치하지 않으면 cache volume 전체가 invalidation됩니다.

이미 획득된 volume이 같은 key를 사용하면 `EBUSY`, 메모리 할당이 실패하면 `ENOMEM` 같은 오류를 반환할 수 있습니다. fscache가 비활성화된 경우에는 `NULL` volume cookie를 반환할 수 있습니다. volume cookie를 받는 모든 함수에 `NULL`을 전달해도 안전하며, 그 함수는 아무 동작도 하지 않습니다.

volume 사용을 마치면 `fscache_relinquish_volume()`으로 반환합니다. 이 호출은 volume을 commit하거나 제거하며, sealed 상태라면 제공한 coherency data로 값을 설정합니다. 데이터 길이는 획득 시 지정한 길이와 같아야 하고, 이 volume에서 얻은 모든 data cookie를 먼저 반환해야 합니다.

Volume API 계약
단계API주요 조건
획득`fscache_acquire_volume()``volume_key`는 고유한 printable string, 최대 254자
cache 선택`cache_name`지정한 이름 또는 먼저 사용 가능한 cache
일관성 확인`coherency_data`디스크 값 불일치 시 volume 전체 invalidation
오류·비활성`EBUSY`, `ENOMEM`, `NULL``NULL` cookie는 모든 volume API에서 no-op
반환`fscache_relinquish_volume()`모든 자식 data cookie를 먼저 반환

획득과 반환에서 보존해야 할 key·coherency·수명 조건입니다.

Volume Registration
===================

The first step for a network filesystem is to acquire a volume cookie for the
volume it wants to access::

        struct fscache_volume *
        fscache_acquire_volume(const char *volume_key,
                               const char *cache_name,
                               const void *coherency_data,
                               size_t coherency_len);

This function creates a volume cookie with the specified volume key as its name
and notes the coherency data.

The volume key must be a printable string with no '/' characters in it.  It
should begin with the name of the filesystem and should be no longer than 254
characters.  It should uniquely represent the volume and will be matched with
what's stored in the cache.

The caller may also specify the name of the cache to use.  If specified,
fscache will look up or create a cache cookie of that name and will use a cache
of that name if it is online or comes online.  If no cache name is specified,
it will use the first cache that comes to hand and set the name to that.

The specified coherency data is stored in the cookie and will be matched
against coherency data stored on disk.  The data pointer may be NULL if no data
is provided.  If the coherency data doesn't match, the entire cache volume will
be invalidated.

This function can return errors such as EBUSY if the volume key is already in
use by an acquired volume or ENOMEM if an allocation failure occurred.  It may
also return a NULL volume cookie if fscache is not enabled.  It is safe to
pass a NULL cookie to any function that takes a volume cookie.  This will
cause that function to do nothing.


When the network filesystem has finished with a volume, it should relinquish it
by calling::

        void fscache_relinquish_volume(struct fscache_volume *volume,
                                       const void *coherency_data,
                                       bool invalidate);

This will cause the volume to be committed or removed, and if sealed the
coherency data will be set to the value supplied.  The amount of coherency data
must match the length specified when the volume was acquired.  Note that all
data cookies obtained in this volume must be relinquished before the volume is
relinquished.

Data file cookie 등록과 반환

142-187

volume cookie를 얻은 뒤 `fscache_acquire_cookie()`로 data storage용 cookie를 획득합니다. 함수는 주어진 `index_key`를 사용해 volume 안에 cookie를 만듭니다.

`index_key`는 지정한 길이의 binary blob이며 해당 volume 안에서 고유해야 합니다. 내용에는 제한이 없지만, backend가 인코딩할 공간을 남기기 위해 길이는 최대 파일명 길이의 약 4분의 3을 넘지 않는 편이 좋습니다.

호출자는 `aux_data`에 coherency data도 전달합니다. fscache는 `aux_data_len` 크기의 버퍼를 할당해 이를 복사하며, 이 크기는 시간에 따라 변하지 않는다고 가정합니다. coherency data는 캐시 데이터의 유효성을 검사하는 데 쓰이고 별도 함수로 갱신할 수 있습니다.

캐시할 객체의 파일 크기인 `object_size`도 제공해야 합니다. 이 값은 데이터를 잘라내는 데 사용될 수 있으며 coherency data와 함께 저장됩니다.

이 함수는 오류값을 반환하지 않지만 메모리 할당 실패나 fscache 비활성화 시 `NULL` cookie를 반환할 수 있습니다. `NULL` volume을 입력해도 안전하고, 반환된 `NULL` cookie 역시 cookie를 받는 다른 함수에 전달할 수 있으며 모두 no-op가 됩니다.

cookie 사용을 마치면 `fscache_relinquish_cookie(cookie, retire)`를 호출합니다. fscache는 `retire` 정책에 따라 cookie를 뒷받침하는 저장소를 commit하거나 삭제합니다.

Data cookie 입력
인자역할제약
`volume`부모 volume cookie`NULL` 허용
`index_key` / `index_key_len`volume 내부 객체 식별binary blob, 부모 안에서 고유
`aux_data` / `aux_data_len`coherency data길이는 수명 동안 불변
`object_size`캐시 객체 파일 크기trim과 저장 metadata에 사용
`retire`반환 시 저장소 정책commit 또는 delete 결정

data storage object를 식별하고 검증하는 필드를 정리합니다.

Data File Registration
======================

Once it has a volume cookie, a network filesystem can use it to acquire a
cookie for data storage::

        struct fscache_cookie *
        fscache_acquire_cookie(struct fscache_volume *volume,
                               u8 advice,
                               const void *index_key,
                               size_t index_key_len,
                               const void *aux_data,
                               size_t aux_data_len,
                               loff_t object_size)

This creates the cookie in the volume using the specified index key.  The index
key is a binary blob of the given length and must be unique for the volume.
This is saved into the cookie.  There are no restrictions on the content, but
its length shouldn't exceed about three quarters of the maximum filename length
to allow for encoding.

The caller should also pass in a piece of coherency data in aux_data.  A buffer
of size aux_data_len will be allocated and the coherency data copied in.  It is
assumed that the size is invariant over time.  The coherency data is used to
check the validity of data in the cache.  Functions are provided by which the
coherency data can be updated.

The file size of the object being cached should also be provided.  This may be
used to trim the data and will be stored with the coherency data.

This function never returns an error, though it may return a NULL cookie on
allocation failure or if fscache is not enabled.  It is safe to pass in a NULL
volume cookie and pass the NULL cookie returned to any function that takes it.
This will cause that function to do nothing.


When the network filesystem has finished with a cookie, it should relinquish it
by calling::

        void fscache_relinquish_cookie(struct fscache_cookie *cookie,
                                       bool retire);

This will cause fscache to either commit the storage backing the cookie or
delete it.

Data file 크기 변경

222-235

네트워크 파일시스템의 파일을 truncation으로 로컬에서 변경하면 `fscache_resize_cookie(cookie, new_size)`를 호출해 캐시에 새 크기를 알려야 합니다.

호출 전에 cookie를 in-use로 표시해야 합니다. 함수는 cookie와 새 크기를 받아 캐시를 동기적으로 resize합니다. inode lock을 잡은 상태에서 `->setattr()` inode operation이 호출하는 것을 전제로 합니다.

Truncation 경로
inode lock 획득cookie를 in-use로 표시`->setattr()`에서 로컬 파일 크기 변경`fscache_resize_cookie(cookie, new_size)`로 동기 resizecookie unuse와 inode lock 해제

inode 크기와 캐시 객체 크기를 같은 잠금 범위에서 맞춥니다.

Resizing A Data File (Truncation)
=================================

If a network filesystem file is resized locally by truncation, the following
should be called to notify the cache::

        void fscache_resize_cookie(struct fscache_cookie *cookie,
                                   loff_t new_size);

The caller must have first marked the cookie in-use.  The cookie and the new
size are passed in and the cache is synchronously resized.  This is expected to
be called from ``->setattr()`` inode operation under the inode lock.

직접 Data I/O API

236-288

cookie를 통해 직접 data I/O를 하려면 `fscache_begin_read_operation()`, `fscache_read()`, `fscache_write()`를 사용합니다. begin 함수는 cookie에서 필요한 자원을 `netfs_cache_resources` 블록에 연결해 operation을 설정합니다.

begin이 오류를 반환하지 않은 경우 read 또는 write를 실행할 수 있습니다. 예를 들어 `NULL` cookie를 주면 `-ENOBUFS`를 반환하지만 그 밖의 부수 동작은 하지 않습니다.

read와 write는 direct I/O operation을 시작합니다. 둘 다 준비된 cache resource block, 시작 파일 위치, buffer와 데이터 양을 설명하는 `iov_iter`를 받습니다.

read는 디스크 내용 중 일부만 채워진 구간인 hole을 처리하는 방법도 받습니다. hole을 무시하거나, 앞쪽 hole을 건너뛰면서 buffer에 0을 채우거나, 오류를 반환하도록 선택할 수 있습니다.

read와 write에는 선택적인 완료 함수 `netfs_io_terminated_t`를 전달할 수 있습니다. callback은 private pointer, 전송 바이트 수 또는 오류인 `transferred_or_error`, 비동기 실행 여부인 `was_async`를 받습니다.

완료 함수를 주면 operation은 비동기로 실행되고 끝날 때 callback을 호출합니다. 완료 함수를 주지 않으면 동기적으로 실행합니다. 비동기인 경우에도 함수 자체가 반환되기 전에 operation이 완료될 수 있습니다.

read와 write는 완료할 때 operation을 끝내고 pin된 자원을 분리합니다. operation이 진행되는 동안 invalidation이 발생했다면 read는 `ESTALE`로 실패합니다.

직접 I/O 호출 계약
API입력·역할완료 동작
`fscache_begin_read_operation()`cookie 자원을 `cres`에 attach`NULL` cookie면 `-ENOBUFS`
`fscache_read()``start_pos`, `iov_iter`, hole 정책invalidation 충돌 시 `ESTALE`
`fscache_write()``start_pos`, `iov_iter`완료 시 operation과 pin 종료
`netfs_io_terminated_t` 제공callback과 private data비동기, 반환 전 완료 가능
callback 생략동일한 I/O 인자동기 실행

준비, 실행 방식, 완료와 invalidation 결과를 비교합니다.

Data I/O API
============

To do data I/O operations directly through a cookie, the following functions
are available::

        int fscache_begin_read_operation(struct netfs_cache_resources *cres,
                                         struct fscache_cookie *cookie);
        int fscache_read(struct netfs_cache_resources *cres,
                         loff_t start_pos,
                         struct iov_iter *iter,
                         enum netfs_read_from_hole read_hole,
                         netfs_io_terminated_t term_func,
                         void *term_func_priv);
        int fscache_write(struct netfs_cache_resources *cres,
                          loff_t start_pos,
                          struct iov_iter *iter,
                          netfs_io_terminated_t term_func,
                          void *term_func_priv);

The *begin* function sets up an operation, attaching the resources required to
the cache resources block from the cookie.  Assuming it doesn't return an error
(for instance, it will return -ENOBUFS if given a NULL cookie, but otherwise do
nothing), then one of the other two functions can be issued.

The *read* and *write* functions initiate a direct-IO operation.  Both take the
previously set up cache resources block, an indication of the start file
position, and an I/O iterator that describes buffer and indicates the amount of
data.

The read function also takes a parameter to indicate how it should handle a
partially populated region (a hole) in the disk content.  This may be to ignore
it, skip over an initial hole and place zeros in the buffer or give an error.

The read and write functions can be given an optional termination function that
will be run on completion::

        typedef
        void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error,
                                      bool was_async);

If a termination function is given, the operation will be run asynchronously
and the termination function will be called upon completion.  If not given, the
operation will be run synchronously.  Note that in the asynchronous case, it is
possible for the operation to complete before the function returns.

Both the read and write functions end the operation when they complete,
detaching any pinned resources.

The read operation will fail with ESTALE if invalidation occurred whilst the
operation was ongoing.

Coherency data와 파일 크기 갱신

289-301

cookie의 coherency data와 파일 크기 갱신을 요청하려면 `fscache_update_cookie(cookie, aux_data, object_size)`를 호출합니다.

`aux_data`와 `object_size`는 포인터이므로 호출자는 필요한 값만 제공할 수 있습니다. 함수는 cookie에 저장된 coherency data 및 파일 크기를 갱신합니다.

Cookie metadata 갱신
네트워크 파일시스템이 최신 coherency data 또는 size 확보`fscache_update_cookie()`에 필요한 포인터 전달cookie의 `aux_data` 갱신선택적으로 `object_size` 갱신

서버에서 확인한 상태를 캐시 객체의 검증 정보에 반영합니다.

Data File Coherency
===================

To request an update of the coherency data and file size on a cookie, the
following should be called::

        void fscache_update_cookie(struct fscache_cookie *cookie,
                                   const void *aux_data,
                                   const loff_t *object_size);

This will update the cookie's coherency data and/or file size.

Data file invalidation

302-327

서버가 원격 제3자의 변경을 네트워크 파일시스템에 알리는 경우처럼, 데이터를 담은 캐시 객체를 invalidation해야 할 때가 있습니다. 파일시스템은 해당 파일에 보관하던 상태와 cached data를 버리고 서버에서 다시 읽어야 합니다.

`fscache_invalidate(cookie, aux_data, size, flags)`를 호출하면 cookie의 invalidation counter를 증가시켜 진행 중 read가 `-ESTALE`로 실패하게 합니다. 또한 제공한 정보로 coherency data와 file size를 설정하고, cookie의 새 I/O를 차단한 뒤 backend가 오래된 데이터를 제거하도록 요청합니다.

invalidation은 worker thread에서 비동기로 실행되어 호출 경로를 오래 막지 않습니다.

원격 변경의 invalidation 경로
서버가 remote third-party change 통지netfs가 기존 상태와 cached data를 폐기 대상으로 결정`fscache_invalidate()`가 counter 증가와 새 I/O 차단진행 중 read는 `-ESTALE`로 완료worker thread가 오래된 backend 데이터를 비동기 제거갱신한 coherency data와 size로 후속 접근 재개

서버 변경 통지에서 오래된 캐시 데이터 제거까지의 순서입니다.

Data File Invalidation
======================

Sometimes it will be necessary to invalidate an object that contains data.
Typically this will be necessary when the server informs the network filesystem
of a remote third-party change - at which point the filesystem has to throw
away the state and cached data that it had for an file and reload from the
server.

To indicate that a cache object should be invalidated, the following should be
called::

        void fscache_invalidate(struct fscache_cookie *cookie,
                                const void *aux_data,
                                loff_t size,
                                unsigned int flags);

This increases the invalidation counter in the cookie to cause outstanding
reads to fail with -ESTALE, sets the coherency data and file size from the
information supplied, blocks new I/O on the cookie and dispatches the cache to
go and get rid of the old data.

Invalidation runs asynchronously in a worker thread so that it doesn't block
too much.

Writeback 자원 pin 관리

328-372

네트워크 파일시스템 writeback에서 캐시로 데이터를 쓰려면 수정이 발생한 시점, 예를 들어 folio가 dirty로 표시될 때 필요한 cache resource를 pin해야 합니다. 종료 중인 thread에서는 파일을 새로 열 수 없기 때문입니다.

inode flag `I_PINNING_FSCACHE_WB`는 해당 inode의 cookie에 in-use 표시를 보유 중임을 나타냅니다. 이 flag는 inode lock을 잡은 상태에서만 변경할 수 있습니다.

`writeback_control` 구조체의 `unpinned_fscache_wb` flag는 모든 dirty page가 정리되어 `__writeback_single_inode()`가 `I_PINNING_FSCACHE_WB`를 지웠을 때 설정됩니다.

`fscache_dirty_folio()`는 파일시스템의 `dirty_folio` address space operation에서 호출하도록 설계되었습니다. `I_PINNING_FSCACHE_WB`가 설정되지 않았다면 flag를 설정하고 cookie use count를 증가시킵니다. 호출자는 그 전에 이미 `fscache_use_cookie()`를 호출했어야 합니다.

`fscache_unpin_writeback()`은 파일시스템의 `write_inode` superblock operation에서 호출합니다. `writeback_control`의 `unpinned_fscache_wb`가 설정되어 있으면 cookie를 unuse해 writeback 뒤를 정리합니다.

`fscache_clear_inode_writeback()`은 netfs의 `evict_inode` superblock operation에서 호출합니다. 반드시 `truncate_inode_pages_final()` 뒤이면서 `clear_inode()` 앞이어야 합니다. 남아 있는 `I_PINNING_FSCACHE_WB`를 정리하고 coherency data도 갱신할 수 있게 합니다.

Writeback pin 수명
Helper호출 지점효과
`fscache_dirty_folio()``dirty_folio``I_PINNING_FSCACHE_WB` 설정과 use count 증가
`fscache_unpin_writeback()``write_inode``unpinned_fscache_wb`이면 cookie unuse
`fscache_clear_inode_writeback()``evict_inode`남은 pin 정리와 coherency 갱신
순서 조건`truncate_inode_pages_final()` 뒤`clear_inode()` 전에 clear helper 호출

세 helper의 호출 지점과 정리 책임을 구분합니다.

Write-Back Resource Management
==============================

To write data to the cache from network filesystem writeback, the cache
resources required need to be pinned at the point the modification is made (for
instance when the page is marked dirty) as it's not possible to open a file in
a thread that's exiting.

The following facilities are provided to manage this:

 * An inode flag, ``I_PINNING_FSCACHE_WB``, is provided to indicate that an
   in-use is held on the cookie for this inode.  It can only be changed if the
   the inode lock is held.

 * A flag, ``unpinned_fscache_wb`` is placed in the ``writeback_control``
   struct that gets set if ``__writeback_single_inode()`` clears
   ``I_PINNING_FSCACHE_WB`` because all the dirty pages were cleared.

To support this, the following functions are provided::

        bool fscache_dirty_folio(struct address_space *mapping,
                                 struct folio *folio,
                                 struct fscache_cookie *cookie);
        void fscache_unpin_writeback(struct writeback_control *wbc,
                                     struct fscache_cookie *cookie);
        void fscache_clear_inode_writeback(struct fscache_cookie *cookie,
                                           struct inode *inode,
                                           const void *aux);

The *set* function is intended to be called from the filesystem's
``dirty_folio`` address space operation.  If ``I_PINNING_FSCACHE_WB`` is not
set, it sets that flag and increments the use count on the cookie (the caller
must already have called ``fscache_use_cookie()``).

The *unpin* function is intended to be called from the filesystem's
``write_inode`` superblock operation.  It cleans up after writing by unusing
the cookie if unpinned_fscache_wb is set in the writeback_control struct.

The *clear* function is intended to be called from the netfs's ``evict_inode``
superblock operation.  It must be called *after*
``truncate_inode_pages_final()``, but *before* ``clear_inode()``.  This cleans
up any hanging ``I_PINNING_FSCACHE_WB``.  It also allows the coherency data to
be updated.

로컬 수정 데이터 캐싱

373-426

로컬에서 수정한 데이터를 캐시에 쓰려면 네트워크 파일시스템은 write가 진행 중임을 page에 표시해야 합니다. 표시가 이미 있으면 먼저 사라질 때까지 기다려야 하며, 이는 같은 캐시 저장소에 대한 여러 direct I/O write가 경쟁하는 것을 막습니다.

먼저 `fscache_cookie_enabled(cookie)` 같은 검사로 캐싱 가능 여부를 정합니다. 캐싱을 시도한다면 netfs helper library의 `wait_on_page_fscache()`, `wait_on_page_fscache_killable()`로 기존 표시가 풀리기를 기다린 뒤 `set_page_fscache()`로 page를 표시합니다.

구간의 모든 page가 표시되면 `fscache_write_to_cache()`로 해당 영역의 write를 예약합니다. 인자는 cache object의 cookie, source page가 연결된 `address_space`, `start`, `len`, netfs 파일 크기 `i_size`, 완료 callback과 private data, 캐싱 여부입니다.

write 예약 지점에 도달하기 전에 오류가 발생하면 `fscache_clear_page_bits(mapping, start, len, caching)`로 표시를 제거할 수 있습니다.

`start`와 `len`은 쓸 영역을 나타냅니다. 반드시 page boundary에 맞을 필요는 없지만 backing filesystem의 DIO boundary에는 맞아야 합니다. `caching`이 false이면 두 함수는 캐싱을 건너뛰고 아무 동작도 하지 않습니다.

완료 함수에는 `term_func_priv`와 함께 오류 또는 기록한 양이 전달됩니다. 이 write 함수는 항상 비동기로 실행되고, 완료 시 모든 page의 표시를 먼저 해제한 뒤 `term_func`를 호출합니다.

로컬 수정 write의 직렬화
`fscache_cookie_enabled()`로 캐싱 가능 여부 확인각 page의 기존 fscache 표시가 사라질 때까지 대기`set_page_fscache()`로 대상 span 전체 표시`fscache_write_to_cache()`로 DIO 정렬 영역을 비동기 예약사전 오류면 `fscache_clear_page_bits()`로 표시 해제완료 시 page 표시를 모두 해제한 뒤 callback 호출

page 표시가 같은 cache range에 대한 경쟁 DIO를 막습니다.

Caching of Local Modifications
==============================

If a network filesystem has locally modified data that it wants to write to the
cache, it needs to mark the pages to indicate that a write is in progress, and
if the mark is already present, it needs to wait for it to be removed first
(presumably due to an already in-progress operation).  This prevents multiple
competing DIO writes to the same storage in the cache.

Firstly, the netfs should determine if caching is available by doing something
like::

        bool caching = fscache_cookie_enabled(cookie);

If caching is to be attempted, pages should be waited for and then marked using
the following functions provided by the netfs helper library::

        void set_page_fscache(struct page *page);
        void wait_on_page_fscache(struct page *page);
        int wait_on_page_fscache_killable(struct page *page);

Once all the pages in the span are marked, the netfs can ask fscache to
schedule a write of that region::

        void fscache_write_to_cache(struct fscache_cookie *cookie,
                                    struct address_space *mapping,
                                    loff_t start, size_t len, loff_t i_size,
                                    netfs_io_terminated_t term_func,
                                    void *term_func_priv,
                                    bool caching)

And if an error occurs before that point is reached, the marks can be removed
by calling::

        void fscache_clear_page_bits(struct address_space *mapping,
                                     loff_t start, size_t len,
                                     bool caching)

In these functions, a pointer to the mapping to which the source pages are
attached is passed in and start and len indicate the size of the region that's
going to be written (it doesn't have to align to page boundaries necessarily,
but it does have to align to DIO boundaries on the backing filesystem).  The
caching parameter indicates if caching should be skipped, and if false, the
functions do nothing.

The write function takes some additional parameters: the cookie representing
the cache object to be written to, i_size indicates the size of the netfs file
and term_func indicates an optional completion function, to which
term_func_priv will be passed, along with the error or amount written.

Note that the write function will always run asynchronously and will unmark all
the pages upon completion before calling term_func.

Page release와 invalidation 대기

427-448

Fscache는 새 cache object에 아직 캐시 데이터가 존재하는지 추적합니다. 처음에는 read할 필요가 없지만, 한 번 write를 수행하고 source page가 VM에서 release된 뒤에는 해당 데이터가 cache에 있을 수 있으므로 cache를 확인해야 합니다.

page가 실제로 release되었다면, 즉 `release_folio`가 true를 반환했다면 해당 address space operation에서 `fscache_note_page_release(cookie)`를 호출해 page가 이제 cache에 존재할 수 있음을 알립니다.

page release와 page invalidation은 해당 page에서 DIO write가 진행 중임을 나타내는 표시가 남아 있으면 `wait_on_page_fscache()` 또는 killable 변형으로 완료를 기다려야 합니다.

첫 write 이후 cache read 전환
새 cache object는 아직 저장 데이터가 없다고 간주page를 source로 첫 cache write 수행VM이 page를 release하고 `release_folio`가 true 반환`fscache_note_page_release()`로 cache 존재 가능성 기록후속 read는 cache를 확인release·invalidation은 진행 중 DIO page 표시가 풀릴 때까지 대기

새 객체가 캐시를 확인해야 하는 시점을 추적하는 상태 변화입니다.

Page Release and Invalidation
=============================

Fscache keeps track of whether we have any data in the cache yet for a cache
object we've just created.  It knows it doesn't have to do any reading until it
has done a write and then the page it wrote from has been released by the VM,
after which it *has* to look in the cache.

To inform fscache that a page might now be in the cache, the following function
should be called from the ``release_folio`` address space op::

        void fscache_note_page_release(struct fscache_cookie *cookie);

if the page has been released (ie. release_folio returned true).

Page release and page invalidation should also wait for any mark left on the
page to say that a DIO write is underway from that page::

        void wait_on_page_fscache(struct page *page);
        int wait_on_page_fscache_killable(struct page *page);

API 함수 참조

449-452

이 문서의 함수별 상세 참조는 `include/linux/fscache.h`의 kernel-doc 주석에서 생성됩니다. 선언과 parameter contract가 바뀌면 이 참조 섹션도 해당 header의 최신 설명을 반영합니다.

참조 원천
지시source path결과
`.. kernel-doc::``include/linux/fscache.h`Fscache API 함수 참조 생성

문서 끝의 Sphinx kernel-doc 지시가 API 선언 설명을 가져오는 위치입니다.

API Function Reference
======================

.. kernel-doc:: include/linux/fscache.h