cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

backend-api.rst (16512B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3=================
      4Cache Backend API
      5=================
      6
      7The FS-Cache system provides an API by which actual caches can be supplied to
      8FS-Cache for it to then serve out to network filesystems and other interested
      9parties.  This API is used by::
     10
     11	#include <linux/fscache-cache.h>.
     12
     13
     14Overview
     15========
     16
     17Interaction with the API is handled on three levels: cache, volume and data
     18storage, and each level has its own type of cookie object:
     19
     20	=======================	=======================
     21	COOKIE			C TYPE
     22	=======================	=======================
     23	Cache cookie		struct fscache_cache
     24	Volume cookie		struct fscache_volume
     25	Data storage cookie	struct fscache_cookie
     26	=======================	=======================
     27
     28Cookies are used to provide some filesystem data to the cache, manage state and
     29pin the cache during access in addition to acting as reference points for the
     30API functions.  Each cookie has a debugging ID that is included in trace points
     31to make it easier to correlate traces.  Note, though, that debugging IDs are
     32simply allocated from incrementing counters and will eventually wrap.
     33
     34The cache backend and the network filesystem can both ask for cache cookies -
     35and if they ask for one of the same name, they'll get the same cookie.  Volume
     36and data cookies, however, are created at the behest of the filesystem only.
     37
     38
     39Cache Cookies
     40=============
     41
     42Caches are represented in the API by cache cookies.  These are objects of
     43type::
     44
     45	struct fscache_cache {
     46		void		*cache_priv;
     47		unsigned int	debug_id;
     48		char		*name;
     49		...
     50	};
     51
     52There are a few fields that the cache backend might be interested in.  The
     53``debug_id`` can be used in tracing to match lines referring to the same cache
     54and ``name`` is the name the cache was registered with.  The ``cache_priv``
     55member is private data provided by the cache when it is brought online.  The
     56other fields are for internal use.
     57
     58
     59Registering a Cache
     60===================
     61
     62When a cache backend wants to bring a cache online, it should first register
     63the cache name and that will get it a cache cookie.  This is done with::
     64
     65	struct fscache_cache *fscache_acquire_cache(const char *name);
     66
     67This will look up and potentially create a cache cookie.  The cache cookie may
     68have already been created by a network filesystem looking for it, in which case
     69that cache cookie will be used.  If the cache cookie is not in use by another
     70cache, it will be moved into the preparing state, otherwise it will return
     71busy.
     72
     73If successful, the cache backend can then start setting up the cache.  In the
     74event that the initialisation fails, the cache backend should call::
     75
     76	void fscache_relinquish_cache(struct fscache_cache *cache);
     77
     78to reset and discard the cookie.
     79
     80
     81Bringing a Cache Online
     82=======================
     83
     84Once the cache is set up, it can be brought online by calling::
     85
     86	int fscache_add_cache(struct fscache_cache *cache,
     87			      const struct fscache_cache_ops *ops,
     88			      void *cache_priv);
     89
     90This stores the cache operations table pointer and cache private data into the
     91cache cookie and moves the cache to the active state, thereby allowing accesses
     92to take place.
     93
     94
     95Withdrawing a Cache From Service
     96================================
     97
     98The cache backend can withdraw a cache from service by calling this function::
     99
    100	void fscache_withdraw_cache(struct fscache_cache *cache);
    101
    102This moves the cache to the withdrawn state to prevent new cache- and
    103volume-level accesses from starting and then waits for outstanding cache-level
    104accesses to complete.
    105
    106The cache must then go through the data storage objects it has and tell fscache
    107to withdraw them, calling::
    108
    109	void fscache_withdraw_cookie(struct fscache_cookie *cookie);
    110
    111on the cookie that each object belongs to.  This schedules the specified cookie
    112for withdrawal.  This gets offloaded to a workqueue.  The cache backend can
    113wait for completion by calling::
    114
    115	void fscache_wait_for_objects(struct fscache_cache *cache);
    116
    117Once all the cookies are withdrawn, a cache backend can withdraw all the
    118volumes, calling::
    119
    120	void fscache_withdraw_volume(struct fscache_volume *volume);
    121
    122to tell fscache that a volume has been withdrawn.  This waits for all
    123outstanding accesses on the volume to complete before returning.
    124
    125When the the cache is completely withdrawn, fscache should be notified by
    126calling::
    127
    128	void fscache_relinquish_cache(struct fscache_cache *cache);
    129
    130to clear fields in the cookie and discard the caller's ref on it.
    131
    132
    133Volume Cookies
    134==============
    135
    136Within a cache, the data storage objects are organised into logical volumes.
    137These are represented in the API as objects of type::
    138
    139	struct fscache_volume {
    140		struct fscache_cache		*cache;
    141		void				*cache_priv;
    142		unsigned int			debug_id;
    143		char				*key;
    144		unsigned int			key_hash;
    145		...
    146		u8				coherency_len;
    147		u8				coherency[];
    148	};
    149
    150There are a number of fields here that are of interest to the caching backend:
    151
    152   * ``cache`` - The parent cache cookie.
    153
    154   * ``cache_priv`` - A place for the cache to stash private data.
    155
    156   * ``debug_id`` - A debugging ID for logging in tracepoints.
    157
    158   * ``key`` - A printable string with no '/' characters in it that represents
    159     the index key for the volume.  The key is NUL-terminated and padded out to
    160     a multiple of 4 bytes.
    161
    162   * ``key_hash`` - A hash of the index key.  This should work out the same, no
    163     matter the cpu arch and endianness.
    164
    165   * ``coherency`` - A piece of coherency data that should be checked when the
    166     volume is bound to in the cache.
    167
    168   * ``coherency_len`` - The amount of data in the coherency buffer.
    169
    170
    171Data Storage Cookies
    172====================
    173
    174A volume is a logical group of data storage objects, each of which is
    175represented to the network filesystem by a cookie.  Cookies are represented in
    176the API as objects of type::
    177
    178	struct fscache_cookie {
    179		struct fscache_volume		*volume;
    180		void				*cache_priv;
    181		unsigned long			flags;
    182		unsigned int			debug_id;
    183		unsigned int			inval_counter;
    184		loff_t				object_size;
    185		u8				advice;
    186		u32				key_hash;
    187		u8				key_len;
    188		u8				aux_len;
    189		...
    190	};
    191
    192The fields in the cookie that are of interest to the cache backend are:
    193
    194   * ``volume`` - The parent volume cookie.
    195
    196   * ``cache_priv`` - A place for the cache to stash private data.
    197
    198   * ``flags`` - A collection of bit flags, including:
    199
    200      * FSCACHE_COOKIE_NO_DATA_TO_READ - There is no data available in the
    201	cache to be read as the cookie has been created or invalidated.
    202
    203      * FSCACHE_COOKIE_NEEDS_UPDATE - The coherency data and/or object size has
    204	been changed and needs committing.
    205
    206      * FSCACHE_COOKIE_LOCAL_WRITE - The netfs's data has been modified
    207	locally, so the cache object may be in an incoherent state with respect
    208	to the server.
    209
    210      * FSCACHE_COOKIE_HAVE_DATA - The backend should set this if it
    211	successfully stores data into the cache.
    212
    213      * FSCACHE_COOKIE_RETIRED - The cookie was invalidated when it was
    214	relinquished and the cached data should be discarded.
    215
    216   * ``debug_id`` - A debugging ID for logging in tracepoints.
    217
    218   * ``inval_counter`` - The number of invalidations done on the cookie.
    219
    220   * ``advice`` - Information about how the cookie is to be used.
    221
    222   * ``key_hash`` - A hash of the index key.  This should work out the same, no
    223     matter the cpu arch and endianness.
    224
    225   * ``key_len`` - The length of the index key.
    226
    227   * ``aux_len`` - The length of the coherency data buffer.
    228
    229Each cookie has an index key, which may be stored inline to the cookie or
    230elsewhere.  A pointer to this can be obtained by calling::
    231
    232	void *fscache_get_key(struct fscache_cookie *cookie);
    233
    234The index key is a binary blob, the storage for which is padded out to a
    235multiple of 4 bytes.
    236
    237Each cookie also has a buffer for coherency data.  This may also be inline or
    238detached from the cookie and a pointer is obtained by calling::
    239
    240	void *fscache_get_aux(struct fscache_cookie *cookie);
    241
    242
    243
    244Cookie Accounting
    245=================
    246
    247Data storage cookies are counted and this is used to block cache withdrawal
    248completion until all objects have been destroyed.  The following functions are
    249provided to the cache to deal with that::
    250
    251	void fscache_count_object(struct fscache_cache *cache);
    252	void fscache_uncount_object(struct fscache_cache *cache);
    253	void fscache_wait_for_objects(struct fscache_cache *cache);
    254
    255The count function records the allocation of an object in a cache and the
    256uncount function records its destruction.  Warning: by the time the uncount
    257function returns, the cache may have been destroyed.
    258
    259The wait function can be used during the withdrawal procedure to wait for
    260fscache to finish withdrawing all the objects in the cache.  When it completes,
    261there will be no remaining objects referring to the cache object or any volume
    262objects.
    263
    264
    265Cache Management API
    266====================
    267
    268The cache backend implements the cache management API by providing a table of
    269operations that fscache can use to manage various aspects of the cache.  These
    270are held in a structure of type::
    271
    272	struct fscache_cache_ops {
    273		const char *name;
    274		...
    275	};
    276
    277This contains a printable name for the cache backend driver plus a number of
    278pointers to methods to allow fscache to request management of the cache:
    279
    280   * Set up a volume cookie [optional]::
    281
    282	void (*acquire_volume)(struct fscache_volume *volume);
    283
    284     This method is called when a volume cookie is being created.  The caller
    285     holds a cache-level access pin to prevent the cache from going away for
    286     the duration.  This method should set up the resources to access a volume
    287     in the cache and should not return until it has done so.
    288
    289     If successful, it can set ``cache_priv`` to its own data.
    290
    291
    292   * Clean up volume cookie [optional]::
    293
    294       void (*free_volume)(struct fscache_volume *volume);
    295
    296     This method is called when a volume cookie is being released if
    297     ``cache_priv`` is set.
    298
    299
    300   * Look up a cookie in the cache [mandatory]::
    301
    302	bool (*lookup_cookie)(struct fscache_cookie *cookie);
    303
    304     This method is called to look up/create the resources needed to access the
    305     data storage for a cookie.  It is called from a worker thread with a
    306     volume-level access pin in the cache to prevent it from being withdrawn.
    307
    308     True should be returned if successful and false otherwise.  If false is
    309     returned, the withdraw_cookie op (see below) will be called.
    310
    311     If lookup fails, but the object could still be created (e.g. it hasn't
    312     been cached before), then::
    313
    314		void fscache_cookie_lookup_negative(
    315			struct fscache_cookie *cookie);
    316
    317     can be called to let the network filesystem proceed and start downloading
    318     stuff whilst the cache backend gets on with the job of creating things.
    319
    320     If successful, ``cookie->cache_priv`` can be set.
    321
    322
    323   * Withdraw an object without any cookie access counts held [mandatory]::
    324
    325	void (*withdraw_cookie)(struct fscache_cookie *cookie);
    326
    327     This method is called to withdraw a cookie from service.  It will be
    328     called when the cookie is relinquished by the netfs, withdrawn or culled
    329     by the cache backend or closed after a period of non-use by fscache.
    330
    331     The caller doesn't hold any access pins, but it is called from a
    332     non-reentrant work item to manage races between the various ways
    333     withdrawal can occur.
    334
    335     The cookie will have the ``FSCACHE_COOKIE_RETIRED`` flag set on it if the
    336     associated data is to be removed from the cache.
    337
    338
    339   * Change the size of a data storage object [mandatory]::
    340
    341	void (*resize_cookie)(struct netfs_cache_resources *cres,
    342			      loff_t new_size);
    343
    344     This method is called to inform the cache backend of a change in size of
    345     the netfs file due to local truncation.  The cache backend should make all
    346     of the changes it needs to make before returning as this is done under the
    347     netfs inode mutex.
    348
    349     The caller holds a cookie-level access pin to prevent a race with
    350     withdrawal and the netfs must have the cookie marked in-use to prevent
    351     garbage collection or culling from removing any resources.
    352
    353
    354   * Invalidate a data storage object [mandatory]::
    355
    356	bool (*invalidate_cookie)(struct fscache_cookie *cookie);
    357
    358     This is called when the network filesystem detects a third-party
    359     modification or when an O_DIRECT write is made locally.  This requests
    360     that the cache backend should throw away all the data in the cache for
    361     this object and start afresh.  It should return true if successful and
    362     false otherwise.
    363
    364     On entry, new I O/operations are blocked.  Once the cache is in a position
    365     to accept I/O again, the backend should release the block by calling::
    366
    367	void fscache_resume_after_invalidation(struct fscache_cookie *cookie);
    368
    369     If the method returns false, caching will be withdrawn for this cookie.
    370
    371
    372   * Prepare to make local modifications to the cache [mandatory]::
    373
    374	void (*prepare_to_write)(struct fscache_cookie *cookie);
    375
    376     This method is called when the network filesystem finds that it is going
    377     to need to modify the contents of the cache due to local writes or
    378     truncations.  This gives the cache a chance to note that a cache object
    379     may be incoherent with respect to the server and may need writing back
    380     later.  This may also cause the cached data to be scrapped on later
    381     rebinding if not properly committed.
    382
    383
    384   * Begin an operation for the netfs lib [mandatory]::
    385
    386	bool (*begin_operation)(struct netfs_cache_resources *cres,
    387				enum fscache_want_state want_state);
    388
    389     This method is called when an I/O operation is being set up (read, write
    390     or resize).  The caller holds an access pin on the cookie and must have
    391     marked the cookie as in-use.
    392
    393     If it can, the backend should attach any resources it needs to keep around
    394     to the netfs_cache_resources object and return true.
    395
    396     If it can't complete the setup, it should return false.
    397
    398     The want_state parameter indicates the state the caller needs the cache
    399     object to be in and what it wants to do during the operation:
    400
    401	* ``FSCACHE_WANT_PARAMS`` - The caller just wants to access cache
    402	  object parameters; it doesn't need to do data I/O yet.
    403
    404	* ``FSCACHE_WANT_READ`` - The caller wants to read data.
    405
    406	* ``FSCACHE_WANT_WRITE`` - The caller wants to write to or resize the
    407          cache object.
    408
    409     Note that there won't necessarily be anything attached to the cookie's
    410     cache_priv yet if the cookie is still being created.
    411
    412
    413Data I/O API
    414============
    415
    416A cache backend provides a data I/O API by through the netfs library's ``struct
    417netfs_cache_ops`` attached to a ``struct netfs_cache_resources`` by the
    418``begin_operation`` method described above.
    419
    420See the Documentation/filesystems/netfs_library.rst for a description.
    421
    422
    423Miscellaneous Functions
    424=======================
    425
    426FS-Cache provides some utilities that a cache backend may make use of:
    427
    428   * Note occurrence of an I/O error in a cache::
    429
    430	void fscache_io_error(struct fscache_cache *cache);
    431
    432     This tells FS-Cache that an I/O error occurred in the cache.  This
    433     prevents any new I/O from being started on the cache.
    434
    435     This does not actually withdraw the cache.  That must be done separately.
    436
    437   * Note cessation of caching on a cookie due to failure::
    438
    439	void fscache_caching_failed(struct fscache_cookie *cookie);
    440
    441     This notes that a the caching that was being done on a cookie failed in
    442     some way, for instance the backing storage failed to be created or
    443     invalidation failed and that no further I/O operations should take place
    444     on it until the cache is reset.
    445
    446   * Count I/O requests::
    447
    448	void fscache_count_read(void);
    449	void fscache_count_write(void);
    450
    451     These record reads and writes from/to the cache.  The numbers are
    452     displayed in /proc/fs/fscache/stats.
    453
    454   * Count out-of-space errors::
    455
    456	void fscache_count_no_write_space(void);
    457	void fscache_count_no_create_space(void);
    458
    459     These record ENOSPC errors in the cache, divided into failures of data
    460     writes and failures of filesystem object creations (e.g. mkdir).
    461
    462   * Count objects culled::
    463
    464	void fscache_count_culled(void);
    465
    466     This records the culling of an object.
    467
    468   * Get the cookie from a set of cache resources::
    469
    470	struct fscache_cookie *fscache_cres_cookie(struct netfs_cache_resources *cres)
    471
    472     Pull a pointer to the cookie from the cache resources.  This may return a
    473     NULL cookie if no cookie was set.
    474
    475
    476API Function Reference
    477======================
    478
    479.. kernel-doc:: include/linux/fscache-cache.h