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