1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* FS-Cache cache handling
4 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
8 #define FSCACHE_DEBUG_LEVEL CACHE
9 #include <linux/export.h>
10 #include <linux/slab.h>
13 static LIST_HEAD(fscache_caches);
14 DECLARE_RWSEM(fscache_addremove_sem);
15 EXPORT_SYMBOL(fscache_addremove_sem);
16 DECLARE_WAIT_QUEUE_HEAD(fscache_clearance_waiters);
17 EXPORT_SYMBOL(fscache_clearance_waiters);
19 static atomic_t fscache_cache_debug_id;
22 * Allocate a cache cookie.
24 static struct fscache_cache *fscache_alloc_cache(const char *name)
26 struct fscache_cache *cache;
28 cache = kzalloc(sizeof(*cache), GFP_KERNEL);
31 cache->name = kstrdup(name, GFP_KERNEL);
37 refcount_set(&cache->ref, 1);
38 INIT_LIST_HEAD(&cache->cache_link);
39 cache->debug_id = atomic_inc_return(&fscache_cache_debug_id);
44 static bool fscache_get_cache_maybe(struct fscache_cache *cache,
45 enum fscache_cache_trace where)
50 success = __refcount_inc_not_zero(&cache->ref, &ref);
52 trace_fscache_cache(cache->debug_id, ref + 1, where);
57 * Look up a cache cookie.
59 struct fscache_cache *fscache_lookup_cache(const char *name, bool is_cache)
61 struct fscache_cache *candidate, *cache, *unnamed = NULL;
63 /* firstly check for the existence of the cache under read lock */
64 down_read(&fscache_addremove_sem);
66 list_for_each_entry(cache, &fscache_caches, cache_link) {
67 if (cache->name && name && strcmp(cache->name, name) == 0 &&
68 fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
70 if (!cache->name && !name &&
71 fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
76 list_for_each_entry(cache, &fscache_caches, cache_link) {
78 fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
83 up_read(&fscache_addremove_sem);
85 /* the cache does not exist - create a candidate */
86 candidate = fscache_alloc_cache(name);
88 return ERR_PTR(-ENOMEM);
90 /* write lock, search again and add if still not present */
91 down_write(&fscache_addremove_sem);
93 list_for_each_entry(cache, &fscache_caches, cache_link) {
94 if (cache->name && name && strcmp(cache->name, name) == 0 &&
95 fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
100 fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
105 if (unnamed && is_cache &&
106 fscache_get_cache_maybe(unnamed, fscache_cache_get_acquire))
107 goto use_unnamed_cache;
110 list_for_each_entry(cache, &fscache_caches, cache_link) {
112 fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
117 list_add_tail(&candidate->cache_link, &fscache_caches);
118 trace_fscache_cache(candidate->debug_id,
119 refcount_read(&candidate->ref),
120 fscache_cache_new_acquire);
121 up_write(&fscache_addremove_sem);
125 up_read(&fscache_addremove_sem);
129 cache->name = candidate->name;
130 candidate->name = NULL;
132 up_write(&fscache_addremove_sem);
133 kfree(candidate->name);
139 * fscache_acquire_cache - Acquire a cache-level cookie.
140 * @name: The name of the cache.
142 * Get a cookie to represent an actual cache. If a name is given and there is
143 * a nameless cache record available, this will acquire that and set its name,
144 * directing all the volumes using it to this cache.
146 * The cache will be switched over to the preparing state if not currently in
147 * use, otherwise -EBUSY will be returned.
149 struct fscache_cache *fscache_acquire_cache(const char *name)
151 struct fscache_cache *cache;
154 cache = fscache_lookup_cache(name, true);
158 if (!fscache_set_cache_state_maybe(cache,
159 FSCACHE_CACHE_IS_NOT_PRESENT,
160 FSCACHE_CACHE_IS_PREPARING)) {
161 pr_warn("Cache tag %s in use\n", name);
162 fscache_put_cache(cache, fscache_cache_put_cache);
163 return ERR_PTR(-EBUSY);
168 EXPORT_SYMBOL(fscache_acquire_cache);
171 * fscache_put_cache - Release a cache-level cookie.
172 * @cache: The cache cookie to be released
173 * @where: An indication of where the release happened
175 * Release the caller's reference on a cache-level cookie. The @where
176 * indication should give information about the circumstances in which the call
177 * occurs and will be logged through a tracepoint.
179 void fscache_put_cache(struct fscache_cache *cache,
180 enum fscache_cache_trace where)
182 unsigned int debug_id = cache->debug_id;
186 if (IS_ERR_OR_NULL(cache))
189 zero = __refcount_dec_and_test(&cache->ref, &ref);
190 trace_fscache_cache(debug_id, ref - 1, where);
193 down_write(&fscache_addremove_sem);
194 list_del_init(&cache->cache_link);
195 up_write(&fscache_addremove_sem);
202 * fscache_relinquish_cache - Reset cache state and release cookie
203 * @cache: The cache cookie to be released
205 * Reset the state of a cache and release the caller's reference on a cache
208 void fscache_relinquish_cache(struct fscache_cache *cache)
210 enum fscache_cache_trace where =
211 (cache->state == FSCACHE_CACHE_IS_PREPARING) ?
212 fscache_cache_put_prep_failed :
213 fscache_cache_put_relinquish;
216 cache->cache_priv = NULL;
217 fscache_set_cache_state(cache, FSCACHE_CACHE_IS_NOT_PRESENT);
218 fscache_put_cache(cache, where);
220 EXPORT_SYMBOL(fscache_relinquish_cache);
223 * fscache_add_cache - Declare a cache as being open for business
224 * @cache: The cache-level cookie representing the cache
225 * @ops: Table of cache operations to use
226 * @cache_priv: Private data for the cache record
228 * Add a cache to the system, making it available for netfs's to use.
230 * See Documentation/filesystems/caching/backend-api.rst for a complete
233 int fscache_add_cache(struct fscache_cache *cache,
234 const struct fscache_cache_ops *ops,
239 _enter("{%s,%s}", ops->name, cache->name);
241 BUG_ON(fscache_cache_state(cache) != FSCACHE_CACHE_IS_PREPARING);
243 /* Get a ref on the cache cookie and keep its n_accesses counter raised
244 * by 1 to prevent wakeups from transitioning it to 0 until we're
245 * withdrawing caching services from it.
247 n_accesses = atomic_inc_return(&cache->n_accesses);
248 trace_fscache_access_cache(cache->debug_id, refcount_read(&cache->ref),
249 n_accesses, fscache_access_cache_pin);
251 down_write(&fscache_addremove_sem);
254 cache->cache_priv = cache_priv;
255 fscache_set_cache_state(cache, FSCACHE_CACHE_IS_ACTIVE);
257 up_write(&fscache_addremove_sem);
258 pr_notice("Cache \"%s\" added (type %s)\n", cache->name, ops->name);
259 _leave(" = 0 [%s]", cache->name);
262 EXPORT_SYMBOL(fscache_add_cache);
265 * fscache_begin_cache_access - Pin a cache so it can be accessed
266 * @cache: The cache-level cookie
267 * @why: An indication of the circumstances of the access for tracing
269 * Attempt to pin the cache to prevent it from going away whilst we're
270 * accessing it and returns true if successful. This works as follows:
272 * (1) If the cache tests as not live (state is not FSCACHE_CACHE_IS_ACTIVE),
273 * then we return false to indicate access was not permitted.
275 * (2) If the cache tests as live, then we increment the n_accesses count and
276 * then recheck the liveness, ending the access if it ceased to be live.
278 * (3) When we end the access, we decrement n_accesses and wake up the any
279 * waiters if it reaches 0.
281 * (4) Whilst the cache is caching, n_accesses is kept artificially
282 * incremented to prevent wakeups from happening.
284 * (5) When the cache is taken offline, the state is changed to prevent new
285 * accesses, n_accesses is decremented and we wait for n_accesses to
288 bool fscache_begin_cache_access(struct fscache_cache *cache, enum fscache_access_trace why)
292 if (!fscache_cache_is_live(cache))
295 n_accesses = atomic_inc_return(&cache->n_accesses);
296 smp_mb__after_atomic(); /* Reread live flag after n_accesses */
297 trace_fscache_access_cache(cache->debug_id, refcount_read(&cache->ref),
299 if (!fscache_cache_is_live(cache)) {
300 fscache_end_cache_access(cache, fscache_access_unlive);
307 * fscache_end_cache_access - Unpin a cache at the end of an access.
308 * @cache: The cache-level cookie
309 * @why: An indication of the circumstances of the access for tracing
311 * Unpin a cache after we've accessed it. The @why indicator is merely
312 * provided for tracing purposes.
314 void fscache_end_cache_access(struct fscache_cache *cache, enum fscache_access_trace why)
318 smp_mb__before_atomic();
319 n_accesses = atomic_dec_return(&cache->n_accesses);
320 trace_fscache_access_cache(cache->debug_id, refcount_read(&cache->ref),
323 wake_up_var(&cache->n_accesses);
327 * fscache_io_error - Note a cache I/O error
328 * @cache: The record describing the cache
330 * Note that an I/O error occurred in a cache and that it should no longer be
331 * used for anything. This also reports the error into the kernel log.
333 * See Documentation/filesystems/caching/backend-api.rst for a complete
336 void fscache_io_error(struct fscache_cache *cache)
338 if (fscache_set_cache_state_maybe(cache,
339 FSCACHE_CACHE_IS_ACTIVE,
340 FSCACHE_CACHE_GOT_IOERROR))
341 pr_err("Cache '%s' stopped due to I/O error\n",
344 EXPORT_SYMBOL(fscache_io_error);
347 * fscache_withdraw_cache - Withdraw a cache from the active service
348 * @cache: The cache cookie
350 * Begin the process of withdrawing a cache from service. This stops new
351 * cache-level and volume-level accesses from taking place and waits for
352 * currently ongoing cache-level accesses to end.
354 void fscache_withdraw_cache(struct fscache_cache *cache)
358 pr_notice("Withdrawing cache \"%s\" (%u objs)\n",
359 cache->name, atomic_read(&cache->object_count));
361 fscache_set_cache_state(cache, FSCACHE_CACHE_IS_WITHDRAWN);
363 /* Allow wakeups on dec-to-0 */
364 n_accesses = atomic_dec_return(&cache->n_accesses);
365 trace_fscache_access_cache(cache->debug_id, refcount_read(&cache->ref),
366 n_accesses, fscache_access_cache_unpin);
368 wait_var_event(&cache->n_accesses,
369 atomic_read(&cache->n_accesses) == 0);
371 EXPORT_SYMBOL(fscache_withdraw_cache);
373 #ifdef CONFIG_PROC_FS
374 static const char fscache_cache_states[NR__FSCACHE_CACHE_STATE] = "-PAEW";
377 * Generate a list of caches in /proc/fs/fscache/caches
379 static int fscache_caches_seq_show(struct seq_file *m, void *v)
381 struct fscache_cache *cache;
383 if (v == &fscache_caches) {
385 "CACHE REF VOLS OBJS ACCES S NAME\n"
386 "======== ===== ===== ===== ===== = ===============\n"
391 cache = list_entry(v, struct fscache_cache, cache_link);
393 "%08x %5d %5d %5d %5d %c %s\n",
395 refcount_read(&cache->ref),
396 atomic_read(&cache->n_volumes),
397 atomic_read(&cache->object_count),
398 atomic_read(&cache->n_accesses),
399 fscache_cache_states[cache->state],
404 static void *fscache_caches_seq_start(struct seq_file *m, loff_t *_pos)
405 __acquires(fscache_addremove_sem)
407 down_read(&fscache_addremove_sem);
408 return seq_list_start_head(&fscache_caches, *_pos);
411 static void *fscache_caches_seq_next(struct seq_file *m, void *v, loff_t *_pos)
413 return seq_list_next(v, &fscache_caches, _pos);
416 static void fscache_caches_seq_stop(struct seq_file *m, void *v)
417 __releases(fscache_addremove_sem)
419 up_read(&fscache_addremove_sem);
422 const struct seq_operations fscache_caches_seq_ops = {
423 .start = fscache_caches_seq_start,
424 .next = fscache_caches_seq_next,
425 .stop = fscache_caches_seq_stop,
426 .show = fscache_caches_seq_show,
428 #endif /* CONFIG_PROC_FS */