0f36d1fac23730c3a5beffc40a4fe9c5efd63d0f
[linux-2.6-microblaze.git] / include / linux / fscache.h
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 (dhowells@redhat.com)
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 /*
45  * Data object state.
46  */
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)));
60
61 /*
62  * Volume representation cookie.
63  */
64 struct fscache_volume {
65         refcount_t                      ref;
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 */
76         spinlock_t                      lock;
77         unsigned long                   flags;
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 */
83 };
84
85 /*
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
91  */
92 struct fscache_cookie {
93         refcount_t                      ref;
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 */
98         spinlock_t                      lock;
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) */
107         unsigned long                   flags;
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 */
123
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 */
129         union {
130                 void                    *key;           /* Index key */
131                 u8                      inline_key[16]; /* - If the key is short enough */
132         };
133         union {
134                 void                    *aux;           /* Auxiliary data */
135                 u8                      inline_aux[8];  /* - If the aux data is short enough */
136         };
137 };
138
139 /*
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
145  */
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);
149
150 extern struct fscache_cookie *__fscache_acquire_cookie(
151         struct fscache_volume *,
152         u8,
153         const void *, size_t,
154         const void *, size_t,
155         loff_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);
160
161 /**
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
167  *
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.
172  *
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.
176  */
177 static inline
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)
182 {
183         if (!fscache_available())
184                 return NULL;
185         return __fscache_acquire_volume(volume_key, cache_name,
186                                         coherency_data, coherency_len);
187 }
188
189 /**
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
194  *
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.
198  */
199 static inline
200 void fscache_relinquish_volume(struct fscache_volume *volume,
201                                const void *coherency_data,
202                                bool invalidate)
203 {
204         if (fscache_volume_valid(volume))
205                 __fscache_relinquish_volume(volume, coherency_data, invalidate);
206 }
207
208 /**
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
217  *
218  * Acquire a cookie to represent a data file within the given cache volume.
219  *
220  * See Documentation/filesystems/caching/netfs-api.rst for a complete
221  * description.
222  */
223 static inline
224 struct fscache_cookie *fscache_acquire_cookie(struct fscache_volume *volume,
225                                               u8 advice,
226                                               const void *index_key,
227                                               size_t index_key_len,
228                                               const void *aux_data,
229                                               size_t aux_data_len,
230                                               loff_t object_size)
231 {
232         if (!fscache_volume_valid(volume))
233                 return NULL;
234         return __fscache_acquire_cookie(volume, advice,
235                                         index_key, index_key_len,
236                                         aux_data, aux_data_len,
237                                         object_size);
238 }
239
240 /**
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
244  *
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.
248  */
249 static inline void fscache_use_cookie(struct fscache_cookie *cookie,
250                                       bool will_modify)
251 {
252         if (fscache_cookie_valid(cookie))
253                 __fscache_use_cookie(cookie, will_modify);
254 }
255
256 /**
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)
261  *
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.
264  */
265 static inline void fscache_unuse_cookie(struct fscache_cookie *cookie,
266                                         const void *aux_data,
267                                         const loff_t *object_size)
268 {
269         if (fscache_cookie_valid(cookie))
270                 __fscache_unuse_cookie(cookie, aux_data, object_size);
271 }
272
273 /**
274  * fscache_relinquish_cookie - Return the cookie to the cache, maybe discarding
275  * it
276  * @cookie: The cookie being returned
277  * @retire: True if the cache object the cookie represents is to be discarded
278  *
279  * This function returns a cookie to the cache, forcibly discarding the
280  * associated cache object if retire is set to true.
281  *
282  * See Documentation/filesystems/caching/netfs-api.rst for a complete
283  * description.
284  */
285 static inline
286 void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
287 {
288         if (fscache_cookie_valid(cookie))
289                 __fscache_relinquish_cookie(cookie, retire);
290 }
291
292 /*
293  * Find the auxiliary data on a cookie.
294  */
295 static inline void *fscache_get_aux(struct fscache_cookie *cookie)
296 {
297         if (cookie->aux_len <= sizeof(cookie->inline_aux))
298                 return cookie->inline_aux;
299         else
300                 return cookie->aux;
301 }
302
303 /*
304  * Update the auxiliary data on a cookie.
305  */
306 static inline
307 void fscache_update_aux(struct fscache_cookie *cookie,
308                         const void *aux_data, const loff_t *object_size)
309 {
310         void *p = fscache_get_aux(cookie);
311
312         if (aux_data && p)
313                 memcpy(p, aux_data, cookie->aux_len);
314         if (object_size)
315                 cookie->object_size = *object_size;
316 }
317
318 #ifdef CONFIG_FSCACHE_STATS
319 extern atomic_t fscache_n_updates;
320 #endif
321
322 static inline
323 void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
324                              const loff_t *object_size)
325 {
326 #ifdef CONFIG_FSCACHE_STATS
327         atomic_inc(&fscache_n_updates);
328 #endif
329         fscache_update_aux(cookie, aux_data, object_size);
330         smp_wmb();
331         set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags);
332 }
333
334 /**
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_*)
340  *
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.
345  *
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.
349  *
350  * See Documentation/filesystems/caching/netfs-api.rst for a complete
351  * description.
352  */
353 static inline
354 void fscache_invalidate(struct fscache_cookie *cookie,
355                         const void *aux_data, loff_t size, unsigned int flags)
356 {
357         if (fscache_cookie_enabled(cookie))
358                 __fscache_invalidate(cookie, aux_data, size, flags);
359 }
360
361 #endif /* _LINUX_FSCACHE_H */