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