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