^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) /* netfs cookie management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2004-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) * See Documentation/filesystems/caching/netfs-api.rst for more information on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * the netfs API.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define FSCACHE_DEBUG_LEVEL COOKIE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct kmem_cache *fscache_cookie_jar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static atomic_t fscache_object_debug_id = ATOMIC_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define fscache_cookie_hash_shift 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static struct hlist_bl_head fscache_cookie_hash[1 << fscache_cookie_hash_shift];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) loff_t object_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static int fscache_alloc_object(struct fscache_cache *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct fscache_cookie *cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static int fscache_attach_object(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct fscache_object *object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static void fscache_print_cookie(struct fscache_cookie *cookie, char prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct hlist_node *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) const u8 *k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) unsigned loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) pr_err("%c-cookie c=%p [p=%p fl=%lx nc=%u na=%u]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) prefix, cookie, cookie->parent, cookie->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) atomic_read(&cookie->n_children),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) atomic_read(&cookie->n_active));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) pr_err("%c-cookie d=%p n=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) prefix, cookie->def, cookie->netfs_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) object = READ_ONCE(cookie->backing_objects.first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (object)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) pr_err("%c-cookie o=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) prefix, hlist_entry(object, struct fscache_object, cookie_link));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) pr_err("%c-key=[%u] '", prefix, cookie->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) k = (cookie->key_len <= sizeof(cookie->inline_key)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) cookie->inline_key : cookie->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) for (loop = 0; loop < cookie->key_len; loop++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) pr_cont("%02x", k[loop]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) pr_cont("'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) void fscache_free_cookie(struct fscache_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (cookie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) BUG_ON(!hlist_empty(&cookie->backing_objects));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (cookie->aux_len > sizeof(cookie->inline_aux))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) kfree(cookie->aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (cookie->key_len > sizeof(cookie->inline_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) kfree(cookie->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) kmem_cache_free(fscache_cookie_jar, cookie);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * Set the index key in a cookie. The cookie struct has space for a 16-byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * key plus length and hash, but if that's not big enough, it's instead a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * pointer to a buffer containing 3 bytes of hash, 1 byte of length and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * the key data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int fscache_set_key(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) const void *index_key, size_t index_key_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u32 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int bufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) bufs = DIV_ROUND_UP(index_key_len, sizeof(*buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (index_key_len > sizeof(cookie->inline_key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) buf = kcalloc(bufs, sizeof(*buf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) cookie->key = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) buf = (u32 *)cookie->inline_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) memcpy(buf, index_key, index_key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) cookie->key_hash = fscache_hash(0, buf, bufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static long fscache_compare_cookie(const struct fscache_cookie *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) const struct fscache_cookie *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) const void *ka, *kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (a->key_hash != b->key_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return (long)a->key_hash - (long)b->key_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (a->parent != b->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return (long)a->parent - (long)b->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (a->key_len != b->key_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return (long)a->key_len - (long)b->key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (a->type != b->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return (long)a->type - (long)b->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (a->key_len <= sizeof(a->inline_key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ka = &a->inline_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) kb = &b->inline_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ka = a->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) kb = b->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return memcmp(ka, kb, a->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Allocate a cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct fscache_cookie *fscache_alloc_cookie(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct fscache_cookie *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) const struct fscache_cookie_def *def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) const void *index_key, size_t index_key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) const void *aux_data, size_t aux_data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) void *netfs_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) loff_t object_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct fscache_cookie *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* allocate and initialise a cookie */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) cookie = kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) cookie->key_len = index_key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) cookie->aux_len = aux_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (fscache_set_key(cookie, index_key, index_key_len) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (cookie->aux_len <= sizeof(cookie->inline_aux)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) memcpy(cookie->inline_aux, aux_data, cookie->aux_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) cookie->aux = kmemdup(aux_data, cookie->aux_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (!cookie->aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) goto nomem;
^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) atomic_set(&cookie->usage, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) atomic_set(&cookie->n_children, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* We keep the active count elevated until relinquishment to prevent an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * attempt to wake up every time the object operations queue quiesces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) atomic_set(&cookie->n_active, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) cookie->def = def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) cookie->parent = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) cookie->netfs_data = netfs_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) cookie->type = def->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) spin_lock_init(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) spin_lock_init(&cookie->stores_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) INIT_HLIST_HEAD(&cookie->backing_objects);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* radix tree insertion won't use the preallocation pool unless it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * told it may not wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) fscache_free_cookie(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * Attempt to insert the new cookie into the hash. If there's a collision, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * return the old cookie if it's not in use and an error otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *candidate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct fscache_cookie *cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct hlist_bl_head *h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct hlist_bl_node *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned int bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) bucket = candidate->key_hash & (ARRAY_SIZE(fscache_cookie_hash) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) h = &fscache_cookie_hash[bucket];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) hlist_bl_lock(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) hlist_bl_for_each_entry(cursor, p, h, hash_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (fscache_compare_cookie(candidate, cursor) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) goto collision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) __set_bit(FSCACHE_COOKIE_ACQUIRED, &candidate->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) fscache_cookie_get(candidate->parent, fscache_cookie_get_acquire_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) atomic_inc(&candidate->parent->n_children);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) hlist_bl_add_head(&candidate->hash_link, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) hlist_bl_unlock(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return candidate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) collision:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (test_and_set_bit(FSCACHE_COOKIE_ACQUIRED, &cursor->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) trace_fscache_cookie(cursor, fscache_cookie_collision,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) atomic_read(&cursor->usage));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) pr_err("Duplicate cookie detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) fscache_print_cookie(cursor, 'O');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) fscache_print_cookie(candidate, 'N');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) hlist_bl_unlock(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) fscache_cookie_get(cursor, fscache_cookie_get_reacquire);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) hlist_bl_unlock(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * request a cookie to represent an object (index, datafile, xattr, etc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * - parent specifies the parent object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * - the top level index cookie for each netfs is stored in the fscache_netfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * struct upon registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * - def points to the definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * - the netfs_data will be passed to the functions pointed to in *def
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * - all attached caches will be searched to see if they contain this object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * - index objects aren't stored on disk until there's a dependent file that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * needs storing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * - other objects are stored in a selected cache immediately, and all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * indices forming the path to it are instantiated if necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * - we never let on to the netfs about errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * - we may set a negative cookie pointer, but that's okay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct fscache_cookie *__fscache_acquire_cookie(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct fscache_cookie *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) const struct fscache_cookie_def *def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) const void *index_key, size_t index_key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) const void *aux_data, size_t aux_data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) void *netfs_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) loff_t object_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct fscache_cookie *candidate, *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) BUG_ON(!def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) _enter("{%s},{%s},%p,%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) parent ? (char *) parent->def->name : "<no-parent>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) def->name, netfs_data, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!index_key || !index_key_len || index_key_len > 255 || aux_data_len > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!aux_data || !aux_data_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) aux_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) aux_data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) fscache_stat(&fscache_n_acquires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* if there's no parent cookie, then we don't create one here either */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (!parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) fscache_stat(&fscache_n_acquires_null);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) _leave(" [no parent]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* validate the definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) BUG_ON(!def->name[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) parent->type != FSCACHE_COOKIE_TYPE_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) candidate = fscache_alloc_cookie(parent, def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) index_key, index_key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) aux_data, aux_data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) netfs_data, object_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (!candidate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) fscache_stat(&fscache_n_acquires_oom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) _leave(" [ENOMEM]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) cookie = fscache_hash_cookie(candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (!cookie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) trace_fscache_cookie(candidate, fscache_cookie_discard, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (cookie == candidate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) candidate = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) switch (cookie->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) case FSCACHE_COOKIE_TYPE_INDEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) fscache_stat(&fscache_n_cookie_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case FSCACHE_COOKIE_TYPE_DATAFILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) fscache_stat(&fscache_n_cookie_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) fscache_stat(&fscache_n_cookie_special);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) trace_fscache_acquire(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* if the object is an index then we need do nothing more here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * - we create indices on disk when we need them as an index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * may exist in multiple caches */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (fscache_acquire_non_index_cookie(cookie, object_size) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) atomic_dec(&parent->n_children);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) fscache_cookie_put(cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) fscache_cookie_put_acquire_nobufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) fscache_stat(&fscache_n_acquires_nobufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) _leave(" = NULL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) fscache_stat(&fscache_n_acquires_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) fscache_free_cookie(candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) EXPORT_SYMBOL(__fscache_acquire_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * Enable a cookie to permit it to accept new operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) void __fscache_enable_cookie(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) const void *aux_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) loff_t object_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) bool (*can_enable)(void *data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) _enter("%p", cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) trace_fscache_enable(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) fscache_update_aux(cookie, aux_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (can_enable && !can_enable(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* The netfs decided it didn't want to enable after all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) } else if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* Wait for outstanding disablement to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) __fscache_wait_on_invalidate(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (fscache_acquire_non_index_cookie(cookie, object_size) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) EXPORT_SYMBOL(__fscache_enable_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * acquire a non-index cookie
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * - this must make sure the index chain is instantiated and instantiate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * object representation too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) loff_t object_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct fscache_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* now we need to see whether the backing objects for this cookie yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * exist, if not there'll be nothing to search */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) down_read(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (list_empty(&fscache_cache_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) up_read(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) _leave(" = 0 [no caches]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* select a cache in which to store the object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) cache = fscache_select_cache_for_object(cookie->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (!cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) up_read(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) fscache_stat(&fscache_n_acquires_no_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) _leave(" = -ENOMEDIUM [no cache]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return -ENOMEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) _debug("cache %s", cache->tag->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) set_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* ask the cache to allocate objects for this cookie and its parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * chain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ret = fscache_alloc_object(cache, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) up_read(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) spin_lock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (hlist_empty(&cookie->backing_objects)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) goto unavailable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) object = hlist_entry(cookie->backing_objects.first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct fscache_object, cookie_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) fscache_set_store_limit(object, object_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /* initiate the process of looking up all the objects in the chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * (done by fscache_initialise_object()) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) fscache_raise_event(object, FSCACHE_OBJECT_EV_NEW_CHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* we may be required to wait for lookup to complete at this point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (!fscache_defer_lookup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) _debug("non-deferred lookup %p", &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) wait_on_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) _debug("complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (test_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) goto unavailable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) up_read(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) _leave(" = 0 [deferred]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) unavailable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) up_read(&fscache_addremove_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) _leave(" = -ENOBUFS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * recursively allocate cache object records for a cookie/cache combination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * - caller must be holding the addremove sem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static int fscache_alloc_object(struct fscache_cache *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct fscache_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) _enter("%p,%p{%s}", cache, cookie, cookie->def->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) spin_lock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) hlist_for_each_entry(object, &cookie->backing_objects,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) cookie_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (object->cache == cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) goto object_already_extant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* ask the cache to allocate an object (we may end up with duplicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * objects at this stage, but we sort that out later) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) fscache_stat(&fscache_n_cop_alloc_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) object = cache->ops->alloc_object(cache, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) fscache_stat_d(&fscache_n_cop_alloc_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (IS_ERR(object)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) fscache_stat(&fscache_n_object_no_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret = PTR_ERR(object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ASSERTCMP(object->cookie, ==, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) fscache_stat(&fscache_n_object_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) object->debug_id = atomic_inc_return(&fscache_object_debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) _debug("ALLOC OBJ%x: %s {%lx}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) object->debug_id, cookie->def->name, object->events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = fscache_alloc_object(cache, cookie->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) goto error_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* only attach if we managed to allocate all we needed, otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * discard the object we just allocated and instead use the one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * attached to the cookie */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (fscache_attach_object(cookie, object) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) fscache_stat(&fscache_n_cop_put_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) cache->ops->put_object(object, fscache_obj_put_attach_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) fscache_stat_d(&fscache_n_cop_put_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) _leave(" = 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) object_already_extant:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (fscache_object_is_dying(object) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) fscache_cache_is_broken(object)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) _leave(" = 0 [found]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) error_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) fscache_stat(&fscache_n_cop_put_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) cache->ops->put_object(object, fscache_obj_put_alloc_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) fscache_stat_d(&fscache_n_cop_put_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * attach a cache object to a cookie
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static int fscache_attach_object(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct fscache_object *object)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct fscache_object *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct fscache_cache *cache = object->cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) _enter("{%s},{OBJ%x}", cookie->def->name, object->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ASSERTCMP(object->cookie, ==, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) spin_lock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* there may be multiple initial creations of this object, but we only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * want one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) hlist_for_each_entry(p, &cookie->backing_objects, cookie_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (p->cache == object->cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (fscache_object_is_dying(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) goto cant_attach_object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* pin the parent object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) spin_lock_nested(&cookie->parent->lock, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) hlist_for_each_entry(p, &cookie->parent->backing_objects,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) cookie_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (p->cache == object->cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (fscache_object_is_dying(p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) spin_unlock(&cookie->parent->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) goto cant_attach_object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) object->parent = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) spin_lock(&p->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) p->n_children++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) spin_unlock(&p->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) spin_unlock(&cookie->parent->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* attach to the cache's object list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (list_empty(&object->cache_link)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) spin_lock(&cache->object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) list_add(&object->cache_link, &cache->object_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) spin_unlock(&cache->object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /* Attach to the cookie. The object already has a ref on it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) hlist_add_head(&object->cookie_link, &cookie->backing_objects);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) fscache_objlist_add(object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) cant_attach_object:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * Invalidate an object. Callable with spinlocks held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) void __fscache_invalidate(struct fscache_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) _enter("{%s}", cookie->def->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) fscache_stat(&fscache_n_invalidates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* Only permit invalidation of data files. Invalidating an index will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * require the caller to release all its attachments to the tree rooted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * there, and if it's doing that, it may as well just retire the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ASSERTCMP(cookie->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* If there's an object, we tell the object state machine to handle the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * invalidation on our behalf, otherwise there's nothing to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (!hlist_empty(&cookie->backing_objects)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) spin_lock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (fscache_cookie_enabled(cookie) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) !hlist_empty(&cookie->backing_objects) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) !test_and_set_bit(FSCACHE_COOKIE_INVALIDATING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) &cookie->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) object = hlist_entry(cookie->backing_objects.first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct fscache_object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) cookie_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (fscache_object_is_live(object))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) fscache_raise_event(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) object, FSCACHE_OBJECT_EV_INVALIDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) EXPORT_SYMBOL(__fscache_invalidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * Wait for object invalidation to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) void __fscache_wait_on_invalidate(struct fscache_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) _enter("%p", cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) wait_on_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) EXPORT_SYMBOL(__fscache_wait_on_invalidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * update the index entries backing a cookie
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) fscache_stat(&fscache_n_updates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (!cookie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) fscache_stat(&fscache_n_updates_null);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) _leave(" [no cookie]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) _enter("{%s}", cookie->def->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) spin_lock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) fscache_update_aux(cookie, aux_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (fscache_cookie_enabled(cookie)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /* update the index entry on disk in each cache backing this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) hlist_for_each_entry(object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) &cookie->backing_objects, cookie_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) EXPORT_SYMBOL(__fscache_update_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * Disable a cookie to stop it from accepting new requests from the netfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) void __fscache_disable_cookie(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) const void *aux_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) bool invalidate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) bool awaken = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) _enter("%p,%u", cookie, invalidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) trace_fscache_disable(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) ASSERTCMP(atomic_read(&cookie->n_active), >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (atomic_read(&cookie->n_children) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) pr_err("Cookie '%s' still has children\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) cookie->def->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) fscache_update_aux(cookie, aux_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (!test_and_clear_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) goto out_unlock_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* If the cookie is being invalidated, wait for that to complete first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * so that we can reuse the flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) __fscache_wait_on_invalidate(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* Dispose of the backing objects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) set_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) spin_lock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!hlist_empty(&cookie->backing_objects)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (invalidate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) set_bit(FSCACHE_OBJECT_RETIRED, &object->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) awaken = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (awaken)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /* Wait for cessation of activity requiring access to the netfs (when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * n_active reaches 0). This makes sure outstanding reads and writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * have completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (!atomic_dec_and_test(&cookie->n_active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) wait_var_event(&cookie->n_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) !atomic_read(&cookie->n_active));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) /* Make sure any pending writes are cancelled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) fscache_invalidate_writes(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /* Reset the cookie state if it wasn't relinquished */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (!test_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) atomic_inc(&cookie->n_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) out_unlock_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) EXPORT_SYMBOL(__fscache_disable_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * release a cookie back to the cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * - the object will be marked as recyclable on disk if retire is true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * - all dependents of this cookie must have already been unregistered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * (indices/files/pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) void __fscache_relinquish_cookie(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) const void *aux_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) bool retire)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) fscache_stat(&fscache_n_relinquishes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (retire)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) fscache_stat(&fscache_n_relinquishes_retire);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!cookie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) fscache_stat(&fscache_n_relinquishes_null);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) _leave(" [no cookie]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) _enter("%p{%s,%p,%d},%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) cookie, cookie->def->name, cookie->netfs_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) atomic_read(&cookie->n_active), retire);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) trace_fscache_relinquish(cookie, retire);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* No further netfs-accessing operations on this cookie permitted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (test_and_set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) __fscache_disable_cookie(cookie, aux_data, retire);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* Clear pointers back to the netfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) cookie->netfs_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) cookie->def = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) BUG_ON(!radix_tree_empty(&cookie->stores));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (cookie->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ASSERTCMP(atomic_read(&cookie->parent->usage), >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ASSERTCMP(atomic_read(&cookie->parent->n_children), >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) atomic_dec(&cookie->parent->n_children);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* Dispose of the netfs's link to the cookie */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ASSERTCMP(atomic_read(&cookie->usage), >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) fscache_cookie_put(cookie, fscache_cookie_put_relinquish);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) EXPORT_SYMBOL(__fscache_relinquish_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * Remove a cookie from the hash table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static void fscache_unhash_cookie(struct fscache_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct hlist_bl_head *h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) unsigned int bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) bucket = cookie->key_hash & (ARRAY_SIZE(fscache_cookie_hash) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) h = &fscache_cookie_hash[bucket];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) hlist_bl_lock(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) hlist_bl_del(&cookie->hash_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) hlist_bl_unlock(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * Drop a reference to a cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) void fscache_cookie_put(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) enum fscache_cookie_trace where)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct fscache_cookie *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) int usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) _enter("%p", cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) usage = atomic_dec_return(&cookie->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) trace_fscache_cookie(cookie, where, usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (usage > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) BUG_ON(usage < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) parent = cookie->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) fscache_unhash_cookie(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) fscache_free_cookie(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) cookie = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) where = fscache_cookie_put_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) } while (cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) * check the consistency between the netfs inode and the backing cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * NOTE: it only serves no-index type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) int __fscache_check_consistency(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) const void *aux_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct fscache_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) bool wake_cookie = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) _enter("%p,", cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ASSERTCMP(cookie->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (fscache_wait_for_deferred_lookup(cookie) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (hlist_empty(&cookie->backing_objects))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) op = kzalloc(sizeof(*op), GFP_NOIO | __GFP_NOMEMALLOC | __GFP_NORETRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) fscache_operation_init(cookie, op, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) op->flags = FSCACHE_OP_MYTHREAD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) (1 << FSCACHE_OP_WAITING) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) (1 << FSCACHE_OP_UNUSE_COOKIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) trace_fscache_page_op(cookie, NULL, op, fscache_page_op_check_consistency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) spin_lock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) fscache_update_aux(cookie, aux_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (!fscache_cookie_enabled(cookie) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) hlist_empty(&cookie->backing_objects))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) goto inconsistent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) object = hlist_entry(cookie->backing_objects.first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) struct fscache_object, cookie_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) goto inconsistent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) op->debug_id = atomic_inc_return(&fscache_op_debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) __fscache_use_cookie(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (fscache_submit_op(object, op) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) goto submit_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) /* the work queue now carries its own ref on the object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ret = fscache_wait_for_operation_activation(object, op, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) /* ask the cache to honour the operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) ret = object->cache->ops->check_consistency(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) fscache_op_complete(op, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) } else if (ret == -ENOBUFS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) fscache_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) submit_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) wake_cookie = __fscache_unuse_cookie(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) inconsistent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) spin_unlock(&cookie->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (wake_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) __fscache_wake_unused_cookie(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) kfree(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) _leave(" = -ESTALE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) EXPORT_SYMBOL(__fscache_check_consistency);