1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /* General filesystem caching interface
4 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
9 * Documentation/filesystems/caching/netfs-api.rst
11 * for a description of the network filesystem interface declared here.
14 #ifndef _LINUX_FSCACHE_H
15 #define _LINUX_FSCACHE_H
18 #include <linux/netfs.h>
20 #if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
21 #define __fscache_available (1)
22 #define fscache_available() (1)
23 #define fscache_volume_valid(volume) (volume)
24 #define fscache_cookie_valid(cookie) (cookie)
25 #define fscache_resources_valid(cres) ((cres)->cache_priv)
26 #define fscache_cookie_enabled(cookie) (cookie && !test_bit(FSCACHE_COOKIE_DISABLED, &cookie->flags))
28 #define __fscache_available (0)
29 #define fscache_available() (0)
30 #define fscache_volume_valid(volume) (0)
31 #define fscache_cookie_valid(cookie) (0)
32 #define fscache_resources_valid(cres) (false)
33 #define fscache_cookie_enabled(cookie) (0)
36 struct fscache_cookie;
38 #define FSCACHE_ADV_SINGLE_CHUNK 0x01 /* The object is a single chunk of data */
39 #define FSCACHE_ADV_WRITE_CACHE 0x00 /* Do cache if written to locally */
40 #define FSCACHE_ADV_WRITE_NOCACHE 0x02 /* Don't cache if written to locally */
42 #define FSCACHE_INVAL_DIO_WRITE 0x01 /* Invalidate due to DIO write */
47 enum fscache_cookie_state {
48 FSCACHE_COOKIE_STATE_QUIESCENT, /* The cookie is uncached */
49 FSCACHE_COOKIE_STATE_LOOKING_UP, /* The cache object is being looked up */
50 FSCACHE_COOKIE_STATE_CREATING, /* The cache object is being created */
51 FSCACHE_COOKIE_STATE_ACTIVE, /* The cache is active, readable and writable */
52 FSCACHE_COOKIE_STATE_INVALIDATING, /* The cache is being invalidated */
53 FSCACHE_COOKIE_STATE_FAILED, /* The cache failed, withdraw to clear */
54 FSCACHE_COOKIE_STATE_LRU_DISCARDING, /* The cookie is being discarded by the LRU */
55 FSCACHE_COOKIE_STATE_WITHDRAWING, /* The cookie is being withdrawn */
56 FSCACHE_COOKIE_STATE_RELINQUISHING, /* The cookie is being relinquished */
57 FSCACHE_COOKIE_STATE_DROPPED, /* The cookie has been dropped */
58 #define FSCACHE_COOKIE_STATE__NR (FSCACHE_COOKIE_STATE_DROPPED + 1)
59 } __attribute__((mode(byte)));
62 * Volume representation cookie.
64 struct fscache_volume {
66 atomic_t n_cookies; /* Number of data cookies in volume */
67 atomic_t n_accesses; /* Number of cache accesses in progress */
68 unsigned int debug_id;
69 unsigned int key_hash; /* Hash of key string */
70 char *key; /* Volume ID, eg. "afs@example.com@1234" */
71 struct list_head proc_link; /* Link in /proc/fs/fscache/volumes */
72 struct hlist_bl_node hash_link; /* Link in hash table */
73 struct work_struct work;
74 struct fscache_cache *cache; /* The cache in which this resides */
75 void *cache_priv; /* Cache private data */
78 #define FSCACHE_VOLUME_RELINQUISHED 0 /* Volume is being cleaned up */
79 #define FSCACHE_VOLUME_INVALIDATE 1 /* Volume was invalidated */
80 #define FSCACHE_VOLUME_COLLIDED_WITH 2 /* Volume was collided with */
81 #define FSCACHE_VOLUME_ACQUIRE_PENDING 3 /* Volume is waiting to complete acquisition */
82 #define FSCACHE_VOLUME_CREATING 4 /* Volume is being created on disk */
86 * Data file representation cookie.
87 * - a file will only appear in one cache
88 * - a request to cache a file may or may not be honoured, subject to
89 * constraints such as disk space
90 * - indices are created on disk just-in-time
92 struct fscache_cookie {
94 atomic_t n_active; /* number of active users of cookie */
95 atomic_t n_accesses; /* Number of cache accesses in progress */
96 unsigned int debug_id;
97 unsigned int inval_counter; /* Number of invalidations made */
99 struct fscache_volume *volume; /* Parent volume of this file. */
100 void *cache_priv; /* Cache-side representation */
101 struct hlist_bl_node hash_link; /* Link in hash table */
102 struct list_head proc_link; /* Link in proc list */
103 struct list_head commit_link; /* Link in commit queue */
104 struct work_struct work; /* Commit/relinq/withdraw work */
105 loff_t object_size; /* Size of the netfs object */
106 unsigned long unused_at; /* Time at which unused (jiffies) */
108 #define FSCACHE_COOKIE_RELINQUISHED 0 /* T if cookie has been relinquished */
109 #define FSCACHE_COOKIE_RETIRED 1 /* T if this cookie has retired on relinq */
110 #define FSCACHE_COOKIE_IS_CACHING 2 /* T if this cookie is cached */
111 #define FSCACHE_COOKIE_NO_DATA_TO_READ 3 /* T if this cookie has nothing to read */
112 #define FSCACHE_COOKIE_NEEDS_UPDATE 4 /* T if attrs have been updated */
113 #define FSCACHE_COOKIE_HAS_BEEN_CACHED 5 /* T if cookie needs withdraw-on-relinq */
114 #define FSCACHE_COOKIE_DISABLED 6 /* T if cookie has been disabled */
115 #define FSCACHE_COOKIE_LOCAL_WRITE 7 /* T if cookie has been modified locally */
116 #define FSCACHE_COOKIE_NO_ACCESS_WAKE 8 /* T if no wake when n_accesses goes 0 */
117 #define FSCACHE_COOKIE_DO_RELINQUISH 9 /* T if this cookie needs relinquishment */
118 #define FSCACHE_COOKIE_DO_WITHDRAW 10 /* T if this cookie needs withdrawing */
119 #define FSCACHE_COOKIE_DO_LRU_DISCARD 11 /* T if this cookie needs LRU discard */
120 #define FSCACHE_COOKIE_DO_PREP_TO_WRITE 12 /* T if cookie needs write preparation */
121 #define FSCACHE_COOKIE_HAVE_DATA 13 /* T if this cookie has data stored */
122 #define FSCACHE_COOKIE_IS_HASHED 14 /* T if this cookie is hashed */
124 enum fscache_cookie_state state;
125 u8 advice; /* FSCACHE_ADV_* */
126 u8 key_len; /* Length of index key */
127 u8 aux_len; /* Length of auxiliary data */
128 u32 key_hash; /* Hash of volume, key, len */
130 void *key; /* Index key */
131 u8 inline_key[16]; /* - If the key is short enough */
134 void *aux; /* Auxiliary data */
135 u8 inline_aux[8]; /* - If the aux data is short enough */
140 * slow-path functions for when there is actually caching available, and the
141 * netfs does actually have a valid token
142 * - these are not to be called directly
143 * - these are undefined symbols when FS-Cache is not configured and the
144 * optimiser takes care of not using them
146 extern struct fscache_volume *__fscache_acquire_volume(const char *, const char *,
147 const void *, size_t);
148 extern void __fscache_relinquish_volume(struct fscache_volume *, const void *, bool);
150 extern struct fscache_cookie *__fscache_acquire_cookie(
151 struct fscache_volume *,
153 const void *, size_t,
154 const void *, size_t,
156 extern void __fscache_use_cookie(struct fscache_cookie *, bool);
157 extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *);
158 extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
159 extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int);
162 * fscache_acquire_volume - Register a volume as desiring caching services
163 * @volume_key: An identification string for the volume
164 * @cache_name: The name of the cache to use (or NULL for the default)
165 * @coherency_data: Piece of arbitrary coherency data to check (or NULL)
166 * @coherency_len: The size of the coherency data
168 * Register a volume as desiring caching services if they're available. The
169 * caller must provide an identifier for the volume and may also indicate which
170 * cache it should be in. If a preexisting volume entry is found in the cache,
171 * the coherency data must match otherwise the entry will be invalidated.
173 * Returns a cookie pointer on success, -ENOMEM if out of memory or -EBUSY if a
174 * cache volume of that name is already acquired. Note that "NULL" is a valid
175 * cookie pointer and can be returned if caching is refused.
178 struct fscache_volume *fscache_acquire_volume(const char *volume_key,
179 const char *cache_name,
180 const void *coherency_data,
181 size_t coherency_len)
183 if (!fscache_available())
185 return __fscache_acquire_volume(volume_key, cache_name,
186 coherency_data, coherency_len);
190 * fscache_relinquish_volume - Cease caching a volume
191 * @volume: The volume cookie
192 * @coherency_data: Piece of arbitrary coherency data to set (or NULL)
193 * @invalidate: True if the volume should be invalidated
195 * Indicate that a filesystem no longer desires caching services for a volume.
196 * The caller must have relinquished all file cookies prior to calling this.
197 * The stored coherency data is updated.
200 void fscache_relinquish_volume(struct fscache_volume *volume,
201 const void *coherency_data,
204 if (fscache_volume_valid(volume))
205 __fscache_relinquish_volume(volume, coherency_data, invalidate);
209 * fscache_acquire_cookie - Acquire a cookie to represent a cache object
210 * @volume: The volume in which to locate/create this cookie
211 * @advice: Advice flags (FSCACHE_COOKIE_ADV_*)
212 * @index_key: The index key for this cookie
213 * @index_key_len: Size of the index key
214 * @aux_data: The auxiliary data for the cookie (may be NULL)
215 * @aux_data_len: Size of the auxiliary data buffer
216 * @object_size: The initial size of object
218 * Acquire a cookie to represent a data file within the given cache volume.
220 * See Documentation/filesystems/caching/netfs-api.rst for a complete
224 struct fscache_cookie *fscache_acquire_cookie(struct fscache_volume *volume,
226 const void *index_key,
227 size_t index_key_len,
228 const void *aux_data,
232 if (!fscache_volume_valid(volume))
234 return __fscache_acquire_cookie(volume, advice,
235 index_key, index_key_len,
236 aux_data, aux_data_len,
241 * fscache_use_cookie - Request usage of cookie attached to an object
242 * @object: Object description
243 * @will_modify: If cache is expected to be modified locally
245 * Request usage of the cookie attached to an object. The caller should tell
246 * the cache if the object's contents are about to be modified locally and then
247 * the cache can apply the policy that has been set to handle this case.
249 static inline void fscache_use_cookie(struct fscache_cookie *cookie,
252 if (fscache_cookie_valid(cookie))
253 __fscache_use_cookie(cookie, will_modify);
257 * fscache_unuse_cookie - Cease usage of cookie attached to an object
258 * @object: Object description
259 * @aux_data: Updated auxiliary data (or NULL)
260 * @object_size: Revised size of the object (or NULL)
262 * Cease usage of the cookie attached to an object. When the users count
263 * reaches zero then the cookie relinquishment will be permitted to proceed.
265 static inline void fscache_unuse_cookie(struct fscache_cookie *cookie,
266 const void *aux_data,
267 const loff_t *object_size)
269 if (fscache_cookie_valid(cookie))
270 __fscache_unuse_cookie(cookie, aux_data, object_size);
274 * fscache_relinquish_cookie - Return the cookie to the cache, maybe discarding
276 * @cookie: The cookie being returned
277 * @retire: True if the cache object the cookie represents is to be discarded
279 * This function returns a cookie to the cache, forcibly discarding the
280 * associated cache object if retire is set to true.
282 * See Documentation/filesystems/caching/netfs-api.rst for a complete
286 void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
288 if (fscache_cookie_valid(cookie))
289 __fscache_relinquish_cookie(cookie, retire);
293 * Find the auxiliary data on a cookie.
295 static inline void *fscache_get_aux(struct fscache_cookie *cookie)
297 if (cookie->aux_len <= sizeof(cookie->inline_aux))
298 return cookie->inline_aux;
304 * Update the auxiliary data on a cookie.
307 void fscache_update_aux(struct fscache_cookie *cookie,
308 const void *aux_data, const loff_t *object_size)
310 void *p = fscache_get_aux(cookie);
313 memcpy(p, aux_data, cookie->aux_len);
315 cookie->object_size = *object_size;
318 #ifdef CONFIG_FSCACHE_STATS
319 extern atomic_t fscache_n_updates;
323 void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
324 const loff_t *object_size)
326 #ifdef CONFIG_FSCACHE_STATS
327 atomic_inc(&fscache_n_updates);
329 fscache_update_aux(cookie, aux_data, object_size);
331 set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags);
335 * fscache_invalidate - Notify cache that an object needs invalidation
336 * @cookie: The cookie representing the cache object
337 * @aux_data: The updated auxiliary data for the cookie (may be NULL)
338 * @size: The revised size of the object.
339 * @flags: Invalidation flags (FSCACHE_INVAL_*)
341 * Notify the cache that an object is needs to be invalidated and that it
342 * should abort any retrievals or stores it is doing on the cache. This
343 * increments inval_counter on the cookie which can be used by the caller to
344 * reconsider I/O requests as they complete.
346 * If @flags has FSCACHE_INVAL_DIO_WRITE set, this indicates that this is due
347 * to a direct I/O write and will cause caching to be disabled on this cookie
348 * until it is completely unused.
350 * See Documentation/filesystems/caching/netfs-api.rst for a complete
354 void fscache_invalidate(struct fscache_cookie *cookie,
355 const void *aux_data, loff_t size, unsigned int flags)
357 if (fscache_cookie_enabled(cookie))
358 __fscache_invalidate(cookie, aux_data, size, flags);
361 #endif /* _LINUX_FSCACHE_H */