^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* FS-Cache cache handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define FSCACHE_DEBUG_LEVEL CACHE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) LIST_HEAD(fscache_cache_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) DECLARE_RWSEM(fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) DECLARE_WAIT_QUEUE_HEAD(fscache_cache_cleared_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) EXPORT_SYMBOL(fscache_cache_cleared_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static LIST_HEAD(fscache_cache_tag_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * look up a cache tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct fscache_cache_tag *tag, *xtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* firstly check for the existence of the tag under read lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) down_read(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) list_for_each_entry(tag, &fscache_cache_tag_list, link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (strcmp(tag->name, name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) atomic_inc(&tag->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) up_read(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) up_read(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* the tag does not exist - create a candidate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) xtag = kzalloc(sizeof(*xtag) + strlen(name) + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (!xtag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* return a dummy tag if out of memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) atomic_set(&xtag->usage, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) strcpy(xtag->name, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* write lock, search again and add if still not present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) down_write(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) list_for_each_entry(tag, &fscache_cache_tag_list, link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (strcmp(tag->name, name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) atomic_inc(&tag->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) up_write(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) kfree(xtag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) list_add_tail(&xtag->link, &fscache_cache_tag_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) up_write(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return xtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * release a reference to a cache tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void __fscache_release_cache_tag(struct fscache_cache_tag *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (tag != ERR_PTR(-ENOMEM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) down_write(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (atomic_dec_and_test(&tag->usage))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) list_del_init(&tag->link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) tag = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) up_write(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) kfree(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * select a cache in which to store an object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * - the cache addremove semaphore must be at least read-locked by the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * - the object will never be an index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct fscache_cache *fscache_select_cache_for_object(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct fscache_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct fscache_cache_tag *tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct fscache_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (list_empty(&fscache_cache_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) _leave(" = NULL [no cache]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* we check the parent to determine the cache to use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) spin_lock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* the first in the parent's backing list should be the preferred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!hlist_empty(&cookie->backing_objects)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) object = hlist_entry(cookie->backing_objects.first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct fscache_object, cookie_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) cache = object->cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (fscache_object_is_dying(object) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) test_bit(FSCACHE_IOERROR, &cache->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) _leave(" = %p [parent]", cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* the parent is unbacked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* cookie not an index and is unbacked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) _leave(" = NULL [cookie ub,ni]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!cookie->def->select_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) goto no_preference;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* ask the netfs for its preference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) tag = cookie->def->select_cache(cookie->parent->netfs_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) cookie->netfs_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (!tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) goto no_preference;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (tag == ERR_PTR(-ENOMEM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) _leave(" = NULL [nomem tag]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!tag->cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) _leave(" = NULL [unbacked tag]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (test_bit(FSCACHE_IOERROR, &tag->cache->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) _leave(" = %p [specific]", tag->cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return tag->cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) no_preference:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* netfs has no preference - just select first cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) cache = list_entry(fscache_cache_list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct fscache_cache, link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) _leave(" = %p [first]", cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * fscache_init_cache - Initialise a cache record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * @cache: The cache record to be initialised
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * @ops: The cache operations to be installed in that record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * @idfmt: Format string to define identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * @...: sprintf-style arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * Initialise a record of a cache and fill in the name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * See Documentation/filesystems/caching/backend-api.rst for a complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * description.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) void fscache_init_cache(struct fscache_cache *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) const struct fscache_cache_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) const char *idfmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) va_list va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) memset(cache, 0, sizeof(*cache));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) cache->ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) va_start(va, idfmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) vsnprintf(cache->identifier, sizeof(cache->identifier), idfmt, va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) va_end(va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) INIT_WORK(&cache->op_gc, fscache_operation_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) INIT_LIST_HEAD(&cache->link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) INIT_LIST_HEAD(&cache->object_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) INIT_LIST_HEAD(&cache->op_gc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) spin_lock_init(&cache->object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) spin_lock_init(&cache->op_gc_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) EXPORT_SYMBOL(fscache_init_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * fscache_add_cache - Declare a cache as being open for business
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * @cache: The record describing the cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * @ifsdef: The record of the cache object describing the top-level index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * @tagname: The tag describing this cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * Add a cache to the system, making it available for netfs's to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * See Documentation/filesystems/caching/backend-api.rst for a complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * description.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int fscache_add_cache(struct fscache_cache *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct fscache_object *ifsdef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) const char *tagname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct fscache_cache_tag *tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ASSERTCMP(ifsdef->cookie, ==, &fscache_fsdef_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) BUG_ON(!cache->ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) BUG_ON(!ifsdef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) cache->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ifsdef->event_mask =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ((1 << NR_FSCACHE_OBJECT_EVENTS) - 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ~(1 << FSCACHE_OBJECT_EV_CLEARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) __set_bit(FSCACHE_OBJECT_IS_AVAILABLE, &ifsdef->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (!tagname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) tagname = cache->identifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) BUG_ON(!tagname[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) _enter("{%s.%s},,%s", cache->ops->name, cache->identifier, tagname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* we use the cache tag to uniquely identify caches */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) tag = __fscache_lookup_cache_tag(tagname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (IS_ERR(tag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (test_and_set_bit(FSCACHE_TAG_RESERVED, &tag->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) goto tag_in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) cache->kobj = kobject_create_and_add(tagname, fscache_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!cache->kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ifsdef->cache = cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) cache->fsdef = ifsdef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) down_write(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) tag->cache = cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) cache->tag = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* add the cache to the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) list_add(&cache->link, &fscache_cache_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* add the cache's netfs definition index object to the cache's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) spin_lock(&cache->object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) list_add_tail(&ifsdef->cache_link, &cache->object_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) spin_unlock(&cache->object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) fscache_objlist_add(ifsdef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* add the cache's netfs definition index object to the top level index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * cookie as a known backing object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) spin_lock(&fscache_fsdef_index.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) hlist_add_head(&ifsdef->cookie_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) &fscache_fsdef_index.backing_objects);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) atomic_inc(&fscache_fsdef_index.usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) spin_unlock(&fscache_fsdef_index.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) up_write(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) pr_notice("Cache \"%s\" added (type %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) cache->tag->name, cache->ops->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) kobject_uevent(cache->kobj, KOBJ_ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) _leave(" = 0 [%s]", cache->identifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) tag_in_use:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) pr_err("Cache tag '%s' already in use\n", tagname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) __fscache_release_cache_tag(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) _leave(" = -EXIST");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) __fscache_release_cache_tag(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) _leave(" = -EINVAL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) _leave(" = -ENOMEM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) EXPORT_SYMBOL(fscache_add_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * fscache_io_error - Note a cache I/O error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * @cache: The record describing the cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * Note that an I/O error occurred in a cache and that it should no longer be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * used for anything. This also reports the error into the kernel log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * See Documentation/filesystems/caching/backend-api.rst for a complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * description.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) void fscache_io_error(struct fscache_cache *cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (!test_and_set_bit(FSCACHE_IOERROR, &cache->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) pr_err("Cache '%s' stopped due to I/O error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) cache->ops->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) EXPORT_SYMBOL(fscache_io_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * request withdrawal of all the objects in a cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * - all the objects being withdrawn are moved onto the supplied list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static void fscache_withdraw_all_objects(struct fscache_cache *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct list_head *dying_objects)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) while (!list_empty(&cache->object_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) spin_lock(&cache->object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!list_empty(&cache->object_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) object = list_entry(cache->object_list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct fscache_object, cache_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) list_move_tail(&object->cache_link, dying_objects);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) _debug("withdraw %p", object->cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* This must be done under object_list_lock to prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * a race with fscache_drop_object().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) spin_unlock(&cache->object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * fscache_withdraw_cache - Withdraw a cache from the active service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * @cache: The record describing the cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * Withdraw a cache from service, unbinding all its cache objects from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * netfs cookies they're currently representing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * See Documentation/filesystems/caching/backend-api.rst for a complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * description.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) void fscache_withdraw_cache(struct fscache_cache *cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) LIST_HEAD(dying_objects);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) pr_notice("Withdrawing cache \"%s\"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) cache->tag->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* make the cache unavailable for cookie acquisition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (test_and_set_bit(FSCACHE_CACHE_WITHDRAWN, &cache->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) down_write(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) list_del_init(&cache->link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) cache->tag->cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) up_write(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* make sure all pages pinned by operations on behalf of the netfs are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * written to disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) fscache_stat(&fscache_n_cop_sync_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) cache->ops->sync_cache(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) fscache_stat_d(&fscache_n_cop_sync_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* dissociate all the netfs pages backed by this cache from the block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * mappings in the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) fscache_stat(&fscache_n_cop_dissociate_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) cache->ops->dissociate_pages(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) fscache_stat_d(&fscache_n_cop_dissociate_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* we now have to destroy all the active objects pertaining to this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * cache - which we do by passing them off to thread pool to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * disposed of */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) _debug("destroy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) fscache_withdraw_all_objects(cache, &dying_objects);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* wait for all extant objects to finish their outstanding operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * and go away */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) _debug("wait for finish");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) wait_event(fscache_cache_cleared_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) atomic_read(&cache->object_count) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) _debug("wait for clearance");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) wait_event(fscache_cache_cleared_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) list_empty(&cache->object_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) _debug("cleared");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ASSERT(list_empty(&dying_objects));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) kobject_put(cache->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) clear_bit(FSCACHE_TAG_RESERVED, &cache->tag->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) fscache_release_cache_tag(cache->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) cache->tag = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) EXPORT_SYMBOL(fscache_withdraw_cache);