xref: /linux-6.15/include/linux/fscache.h (revision d64f4554)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /* General filesystem caching interface
3  *
4  * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells ([email protected])
6  *
7  * NOTE!!! See:
8  *
9  *	Documentation/filesystems/caching/netfs-api.rst
10  *
11  * for a description of the network filesystem interface declared here.
12  */
13 
14 #ifndef _LINUX_FSCACHE_H
15 #define _LINUX_FSCACHE_H
16 
17 #include <linux/fs.h>
18 #include <linux/netfs.h>
19 
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))
27 #else
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)
34 #endif
35 
36 struct fscache_cookie;
37 
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 */
41 
42 #define FSCACHE_INVAL_DIO_WRITE		0x01 /* Invalidate due to DIO write */
43 
44 enum fscache_want_state {
45 	FSCACHE_WANT_PARAMS,
46 	FSCACHE_WANT_WRITE,
47 	FSCACHE_WANT_READ,
48 };
49 
50 /*
51  * Data object state.
52  */
53 enum fscache_cookie_state {
54 	FSCACHE_COOKIE_STATE_QUIESCENT,		/* The cookie is uncached */
55 	FSCACHE_COOKIE_STATE_LOOKING_UP,	/* The cache object is being looked up */
56 	FSCACHE_COOKIE_STATE_CREATING,		/* The cache object is being created */
57 	FSCACHE_COOKIE_STATE_ACTIVE,		/* The cache is active, readable and writable */
58 	FSCACHE_COOKIE_STATE_INVALIDATING,	/* The cache is being invalidated */
59 	FSCACHE_COOKIE_STATE_FAILED,		/* The cache failed, withdraw to clear */
60 	FSCACHE_COOKIE_STATE_LRU_DISCARDING,	/* The cookie is being discarded by the LRU */
61 	FSCACHE_COOKIE_STATE_WITHDRAWING,	/* The cookie is being withdrawn */
62 	FSCACHE_COOKIE_STATE_RELINQUISHING,	/* The cookie is being relinquished */
63 	FSCACHE_COOKIE_STATE_DROPPED,		/* The cookie has been dropped */
64 #define FSCACHE_COOKIE_STATE__NR (FSCACHE_COOKIE_STATE_DROPPED + 1)
65 } __attribute__((mode(byte)));
66 
67 /*
68  * Volume representation cookie.
69  */
70 struct fscache_volume {
71 	refcount_t			ref;
72 	atomic_t			n_cookies;	/* Number of data cookies in volume */
73 	atomic_t			n_accesses;	/* Number of cache accesses in progress */
74 	unsigned int			debug_id;
75 	unsigned int			key_hash;	/* Hash of key string */
76 	char				*key;		/* Volume ID, eg. "[email protected]@1234" */
77 	struct list_head		proc_link;	/* Link in /proc/fs/fscache/volumes */
78 	struct hlist_bl_node		hash_link;	/* Link in hash table */
79 	struct work_struct		work;
80 	struct fscache_cache		*cache;		/* The cache in which this resides */
81 	void				*cache_priv;	/* Cache private data */
82 	spinlock_t			lock;
83 	unsigned long			flags;
84 #define FSCACHE_VOLUME_RELINQUISHED	0	/* Volume is being cleaned up */
85 #define FSCACHE_VOLUME_INVALIDATE	1	/* Volume was invalidated */
86 #define FSCACHE_VOLUME_COLLIDED_WITH	2	/* Volume was collided with */
87 #define FSCACHE_VOLUME_ACQUIRE_PENDING	3	/* Volume is waiting to complete acquisition */
88 #define FSCACHE_VOLUME_CREATING		4	/* Volume is being created on disk */
89 };
90 
91 /*
92  * Data file representation cookie.
93  * - a file will only appear in one cache
94  * - a request to cache a file may or may not be honoured, subject to
95  *   constraints such as disk space
96  * - indices are created on disk just-in-time
97  */
98 struct fscache_cookie {
99 	refcount_t			ref;
100 	atomic_t			n_active;	/* number of active users of cookie */
101 	atomic_t			n_accesses;	/* Number of cache accesses in progress */
102 	unsigned int			debug_id;
103 	unsigned int			inval_counter;	/* Number of invalidations made */
104 	spinlock_t			lock;
105 	struct fscache_volume		*volume;	/* Parent volume of this file. */
106 	void				*cache_priv;	/* Cache-side representation */
107 	struct hlist_bl_node		hash_link;	/* Link in hash table */
108 	struct list_head		proc_link;	/* Link in proc list */
109 	struct list_head		commit_link;	/* Link in commit queue */
110 	struct work_struct		work;		/* Commit/relinq/withdraw work */
111 	loff_t				object_size;	/* Size of the netfs object */
112 	unsigned long			unused_at;	/* Time at which unused (jiffies) */
113 	unsigned long			flags;
114 #define FSCACHE_COOKIE_RELINQUISHED	0		/* T if cookie has been relinquished */
115 #define FSCACHE_COOKIE_RETIRED		1		/* T if this cookie has retired on relinq */
116 #define FSCACHE_COOKIE_IS_CACHING	2		/* T if this cookie is cached */
117 #define FSCACHE_COOKIE_NO_DATA_TO_READ	3		/* T if this cookie has nothing to read */
118 #define FSCACHE_COOKIE_NEEDS_UPDATE	4		/* T if attrs have been updated */
119 #define FSCACHE_COOKIE_HAS_BEEN_CACHED	5		/* T if cookie needs withdraw-on-relinq */
120 #define FSCACHE_COOKIE_DISABLED		6		/* T if cookie has been disabled */
121 #define FSCACHE_COOKIE_LOCAL_WRITE	7		/* T if cookie has been modified locally */
122 #define FSCACHE_COOKIE_NO_ACCESS_WAKE	8		/* T if no wake when n_accesses goes 0 */
123 #define FSCACHE_COOKIE_DO_RELINQUISH	9		/* T if this cookie needs relinquishment */
124 #define FSCACHE_COOKIE_DO_WITHDRAW	10		/* T if this cookie needs withdrawing */
125 #define FSCACHE_COOKIE_DO_LRU_DISCARD	11		/* T if this cookie needs LRU discard */
126 #define FSCACHE_COOKIE_DO_PREP_TO_WRITE	12		/* T if cookie needs write preparation */
127 #define FSCACHE_COOKIE_HAVE_DATA	13		/* T if this cookie has data stored */
128 #define FSCACHE_COOKIE_IS_HASHED	14		/* T if this cookie is hashed */
129 
130 	enum fscache_cookie_state	state;
131 	u8				advice;		/* FSCACHE_ADV_* */
132 	u8				key_len;	/* Length of index key */
133 	u8				aux_len;	/* Length of auxiliary data */
134 	u32				key_hash;	/* Hash of volume, key, len */
135 	union {
136 		void			*key;		/* Index key */
137 		u8			inline_key[16];	/* - If the key is short enough */
138 	};
139 	union {
140 		void			*aux;		/* Auxiliary data */
141 		u8			inline_aux[8];	/* - If the aux data is short enough */
142 	};
143 };
144 
145 /*
146  * slow-path functions for when there is actually caching available, and the
147  * netfs does actually have a valid token
148  * - these are not to be called directly
149  * - these are undefined symbols when FS-Cache is not configured and the
150  *   optimiser takes care of not using them
151  */
152 extern struct fscache_volume *__fscache_acquire_volume(const char *, const char *,
153 						       const void *, size_t);
154 extern void __fscache_relinquish_volume(struct fscache_volume *, const void *, bool);
155 
156 extern struct fscache_cookie *__fscache_acquire_cookie(
157 	struct fscache_volume *,
158 	u8,
159 	const void *, size_t,
160 	const void *, size_t,
161 	loff_t);
162 extern void __fscache_use_cookie(struct fscache_cookie *, bool);
163 extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *);
164 extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
165 extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int);
166 extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *);
167 
168 /**
169  * fscache_acquire_volume - Register a volume as desiring caching services
170  * @volume_key: An identification string for the volume
171  * @cache_name: The name of the cache to use (or NULL for the default)
172  * @coherency_data: Piece of arbitrary coherency data to check (or NULL)
173  * @coherency_len: The size of the coherency data
174  *
175  * Register a volume as desiring caching services if they're available.  The
176  * caller must provide an identifier for the volume and may also indicate which
177  * cache it should be in.  If a preexisting volume entry is found in the cache,
178  * the coherency data must match otherwise the entry will be invalidated.
179  *
180  * Returns a cookie pointer on success, -ENOMEM if out of memory or -EBUSY if a
181  * cache volume of that name is already acquired.  Note that "NULL" is a valid
182  * cookie pointer and can be returned if caching is refused.
183  */
184 static inline
185 struct fscache_volume *fscache_acquire_volume(const char *volume_key,
186 					      const char *cache_name,
187 					      const void *coherency_data,
188 					      size_t coherency_len)
189 {
190 	if (!fscache_available())
191 		return NULL;
192 	return __fscache_acquire_volume(volume_key, cache_name,
193 					coherency_data, coherency_len);
194 }
195 
196 /**
197  * fscache_relinquish_volume - Cease caching a volume
198  * @volume: The volume cookie
199  * @coherency_data: Piece of arbitrary coherency data to set (or NULL)
200  * @invalidate: True if the volume should be invalidated
201  *
202  * Indicate that a filesystem no longer desires caching services for a volume.
203  * The caller must have relinquished all file cookies prior to calling this.
204  * The stored coherency data is updated.
205  */
206 static inline
207 void fscache_relinquish_volume(struct fscache_volume *volume,
208 			       const void *coherency_data,
209 			       bool invalidate)
210 {
211 	if (fscache_volume_valid(volume))
212 		__fscache_relinquish_volume(volume, coherency_data, invalidate);
213 }
214 
215 /**
216  * fscache_acquire_cookie - Acquire a cookie to represent a cache object
217  * @volume: The volume in which to locate/create this cookie
218  * @advice: Advice flags (FSCACHE_COOKIE_ADV_*)
219  * @index_key: The index key for this cookie
220  * @index_key_len: Size of the index key
221  * @aux_data: The auxiliary data for the cookie (may be NULL)
222  * @aux_data_len: Size of the auxiliary data buffer
223  * @object_size: The initial size of object
224  *
225  * Acquire a cookie to represent a data file within the given cache volume.
226  *
227  * See Documentation/filesystems/caching/netfs-api.rst for a complete
228  * description.
229  */
230 static inline
231 struct fscache_cookie *fscache_acquire_cookie(struct fscache_volume *volume,
232 					      u8 advice,
233 					      const void *index_key,
234 					      size_t index_key_len,
235 					      const void *aux_data,
236 					      size_t aux_data_len,
237 					      loff_t object_size)
238 {
239 	if (!fscache_volume_valid(volume))
240 		return NULL;
241 	return __fscache_acquire_cookie(volume, advice,
242 					index_key, index_key_len,
243 					aux_data, aux_data_len,
244 					object_size);
245 }
246 
247 /**
248  * fscache_use_cookie - Request usage of cookie attached to an object
249  * @object: Object description
250  * @will_modify: If cache is expected to be modified locally
251  *
252  * Request usage of the cookie attached to an object.  The caller should tell
253  * the cache if the object's contents are about to be modified locally and then
254  * the cache can apply the policy that has been set to handle this case.
255  */
256 static inline void fscache_use_cookie(struct fscache_cookie *cookie,
257 				      bool will_modify)
258 {
259 	if (fscache_cookie_valid(cookie))
260 		__fscache_use_cookie(cookie, will_modify);
261 }
262 
263 /**
264  * fscache_unuse_cookie - Cease usage of cookie attached to an object
265  * @object: Object description
266  * @aux_data: Updated auxiliary data (or NULL)
267  * @object_size: Revised size of the object (or NULL)
268  *
269  * Cease usage of the cookie attached to an object.  When the users count
270  * reaches zero then the cookie relinquishment will be permitted to proceed.
271  */
272 static inline void fscache_unuse_cookie(struct fscache_cookie *cookie,
273 					const void *aux_data,
274 					const loff_t *object_size)
275 {
276 	if (fscache_cookie_valid(cookie))
277 		__fscache_unuse_cookie(cookie, aux_data, object_size);
278 }
279 
280 /**
281  * fscache_relinquish_cookie - Return the cookie to the cache, maybe discarding
282  * it
283  * @cookie: The cookie being returned
284  * @retire: True if the cache object the cookie represents is to be discarded
285  *
286  * This function returns a cookie to the cache, forcibly discarding the
287  * associated cache object if retire is set to true.
288  *
289  * See Documentation/filesystems/caching/netfs-api.rst for a complete
290  * description.
291  */
292 static inline
293 void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
294 {
295 	if (fscache_cookie_valid(cookie))
296 		__fscache_relinquish_cookie(cookie, retire);
297 }
298 
299 /*
300  * Find the auxiliary data on a cookie.
301  */
302 static inline void *fscache_get_aux(struct fscache_cookie *cookie)
303 {
304 	if (cookie->aux_len <= sizeof(cookie->inline_aux))
305 		return cookie->inline_aux;
306 	else
307 		return cookie->aux;
308 }
309 
310 /*
311  * Update the auxiliary data on a cookie.
312  */
313 static inline
314 void fscache_update_aux(struct fscache_cookie *cookie,
315 			const void *aux_data, const loff_t *object_size)
316 {
317 	void *p = fscache_get_aux(cookie);
318 
319 	if (aux_data && p)
320 		memcpy(p, aux_data, cookie->aux_len);
321 	if (object_size)
322 		cookie->object_size = *object_size;
323 }
324 
325 #ifdef CONFIG_FSCACHE_STATS
326 extern atomic_t fscache_n_updates;
327 #endif
328 
329 static inline
330 void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
331 			     const loff_t *object_size)
332 {
333 #ifdef CONFIG_FSCACHE_STATS
334 	atomic_inc(&fscache_n_updates);
335 #endif
336 	fscache_update_aux(cookie, aux_data, object_size);
337 	smp_wmb();
338 	set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags);
339 }
340 
341 /**
342  * fscache_invalidate - Notify cache that an object needs invalidation
343  * @cookie: The cookie representing the cache object
344  * @aux_data: The updated auxiliary data for the cookie (may be NULL)
345  * @size: The revised size of the object.
346  * @flags: Invalidation flags (FSCACHE_INVAL_*)
347  *
348  * Notify the cache that an object is needs to be invalidated and that it
349  * should abort any retrievals or stores it is doing on the cache.  This
350  * increments inval_counter on the cookie which can be used by the caller to
351  * reconsider I/O requests as they complete.
352  *
353  * If @flags has FSCACHE_INVAL_DIO_WRITE set, this indicates that this is due
354  * to a direct I/O write and will cause caching to be disabled on this cookie
355  * until it is completely unused.
356  *
357  * See Documentation/filesystems/caching/netfs-api.rst for a complete
358  * description.
359  */
360 static inline
361 void fscache_invalidate(struct fscache_cookie *cookie,
362 			const void *aux_data, loff_t size, unsigned int flags)
363 {
364 	if (fscache_cookie_enabled(cookie))
365 		__fscache_invalidate(cookie, aux_data, size, flags);
366 }
367 
368 /**
369  * fscache_operation_valid - Return true if operations resources are usable
370  * @cres: The resources to check.
371  *
372  * Returns a pointer to the operations table if usable or NULL if not.
373  */
374 static inline
375 const struct netfs_cache_ops *fscache_operation_valid(const struct netfs_cache_resources *cres)
376 {
377 	return fscache_resources_valid(cres) ? cres->ops : NULL;
378 }
379 
380 /**
381  * fscache_begin_read_operation - Begin a read operation for the netfs lib
382  * @cres: The cache resources for the read being performed
383  * @cookie: The cookie representing the cache object
384  *
385  * Begin a read operation on behalf of the netfs helper library.  @cres
386  * indicates the cache resources to which the operation state should be
387  * attached; @cookie indicates the cache object that will be accessed.
388  *
389  * This is intended to be called from the ->begin_cache_operation() netfs lib
390  * operation as implemented by the network filesystem.
391  *
392  * @cres->inval_counter is set from @cookie->inval_counter for comparison at
393  * the end of the operation.  This allows invalidation during the operation to
394  * be detected by the caller.
395  *
396  * Returns:
397  * * 0		- Success
398  * * -ENOBUFS	- No caching available
399  * * Other error code from the cache, such as -ENOMEM.
400  */
401 static inline
402 int fscache_begin_read_operation(struct netfs_cache_resources *cres,
403 				 struct fscache_cookie *cookie)
404 {
405 	if (fscache_cookie_enabled(cookie))
406 		return __fscache_begin_read_operation(cres, cookie);
407 	return -ENOBUFS;
408 }
409 
410 #endif /* _LINUX_FSCACHE_H */
411