summaryrefslogtreecommitdiff
path: root/fs/cachefiles/interface.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2021-11-17 19:22:21 +0300
committerDavid Howells <dhowells@redhat.com>2022-01-07 16:42:08 +0300
commitdf98e87f2091774c377ddfaedfe64bd90ed4bdca (patch)
tree626bfd7ea0af245966ca301cc7b1c1f28c38f9de /fs/cachefiles/interface.c
parent13871bad1ef7f41947c816a9e342aa9fa8643c5e (diff)
downloadlinux-df98e87f2091774c377ddfaedfe64bd90ed4bdca.tar.xz
cachefiles: Implement object lifecycle funcs
Implement allocate, get, see and put functions for the cachefiles_object struct. The members of the struct we're going to need are also added. Additionally, implement a lifecycle tracepoint. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> cc: linux-cachefs@redhat.com Link: https://lore.kernel.org/r/163819639457.215744.4600093239395728232.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/163906939569.143852.3594314410666551982.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/163967148857.1823006.6332962598220464364.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/164021547762.640689.8422781599594931000.stgit@warthog.procyon.org.uk/ # v4
Diffstat (limited to 'fs/cachefiles/interface.c')
-rw-r--r--fs/cachefiles/interface.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 1793e46bd3e7..68bb7b6c4945 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -13,6 +13,92 @@
#include <trace/events/fscache.h>
#include "internal.h"
+static atomic_t cachefiles_object_debug_id;
+
+/*
+ * Allocate a cache object record.
+ */
+static
+struct cachefiles_object *cachefiles_alloc_object(struct fscache_cookie *cookie)
+{
+ struct fscache_volume *vcookie = cookie->volume;
+ struct cachefiles_volume *volume = vcookie->cache_priv;
+ struct cachefiles_object *object;
+
+ _enter("{%s},%x,", vcookie->key, cookie->debug_id);
+
+ object = kmem_cache_zalloc(cachefiles_object_jar, GFP_KERNEL);
+ if (!object)
+ return NULL;
+
+ refcount_set(&object->ref, 1);
+
+ spin_lock_init(&object->lock);
+ INIT_LIST_HEAD(&object->cache_link);
+ object->volume = volume;
+ object->debug_id = atomic_inc_return(&cachefiles_object_debug_id);
+ object->cookie = fscache_get_cookie(cookie, fscache_cookie_get_attach_object);
+
+ fscache_count_object(vcookie->cache);
+ trace_cachefiles_ref(object->debug_id, cookie->debug_id, 1,
+ cachefiles_obj_new);
+ return object;
+}
+
+/*
+ * Note that an object has been seen.
+ */
+void cachefiles_see_object(struct cachefiles_object *object,
+ enum cachefiles_obj_ref_trace why)
+{
+ trace_cachefiles_ref(object->debug_id, object->cookie->debug_id,
+ refcount_read(&object->ref), why);
+}
+
+/*
+ * Increment the usage count on an object;
+ */
+struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object,
+ enum cachefiles_obj_ref_trace why)
+{
+ int r;
+
+ __refcount_inc(&object->ref, &r);
+ trace_cachefiles_ref(object->debug_id, object->cookie->debug_id, r, why);
+ return object;
+}
+
+/*
+ * dispose of a reference to an object
+ */
+void cachefiles_put_object(struct cachefiles_object *object,
+ enum cachefiles_obj_ref_trace why)
+{
+ unsigned int object_debug_id = object->debug_id;
+ unsigned int cookie_debug_id = object->cookie->debug_id;
+ struct fscache_cache *cache;
+ bool done;
+ int r;
+
+ done = __refcount_dec_and_test(&object->ref, &r);
+ trace_cachefiles_ref(object_debug_id, cookie_debug_id, r, why);
+ if (done) {
+ _debug("- kill object OBJ%x", object_debug_id);
+
+ ASSERTCMP(object->file, ==, NULL);
+
+ kfree(object->d_name);
+
+ cache = object->volume->cache->cache;
+ fscache_put_cookie(object->cookie, fscache_cookie_put_object);
+ object->cookie = NULL;
+ kmem_cache_free(cachefiles_object_jar, object);
+ fscache_uncount_object(cache);
+ }
+
+ _leave("");
+}
+
const struct fscache_cache_ops cachefiles_cache_ops = {
.name = "cachefiles",
.acquire_volume = cachefiles_acquire_volume,