xref: /linux-6.15/fs/cachefiles/interface.c (revision df98e87f)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* FS-Cache interface to CacheFiles
3  *
4  * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells ([email protected])
6  */
7 
8 #include <linux/slab.h>
9 #include <linux/mount.h>
10 #include <linux/xattr.h>
11 #include <linux/file.h>
12 #include <linux/falloc.h>
13 #include <trace/events/fscache.h>
14 #include "internal.h"
15 
16 static atomic_t cachefiles_object_debug_id;
17 
18 /*
19  * Allocate a cache object record.
20  */
21 static
22 struct cachefiles_object *cachefiles_alloc_object(struct fscache_cookie *cookie)
23 {
24 	struct fscache_volume *vcookie = cookie->volume;
25 	struct cachefiles_volume *volume = vcookie->cache_priv;
26 	struct cachefiles_object *object;
27 
28 	_enter("{%s},%x,", vcookie->key, cookie->debug_id);
29 
30 	object = kmem_cache_zalloc(cachefiles_object_jar, GFP_KERNEL);
31 	if (!object)
32 		return NULL;
33 
34 	refcount_set(&object->ref, 1);
35 
36 	spin_lock_init(&object->lock);
37 	INIT_LIST_HEAD(&object->cache_link);
38 	object->volume = volume;
39 	object->debug_id = atomic_inc_return(&cachefiles_object_debug_id);
40 	object->cookie = fscache_get_cookie(cookie, fscache_cookie_get_attach_object);
41 
42 	fscache_count_object(vcookie->cache);
43 	trace_cachefiles_ref(object->debug_id, cookie->debug_id, 1,
44 			     cachefiles_obj_new);
45 	return object;
46 }
47 
48 /*
49  * Note that an object has been seen.
50  */
51 void cachefiles_see_object(struct cachefiles_object *object,
52 			   enum cachefiles_obj_ref_trace why)
53 {
54 	trace_cachefiles_ref(object->debug_id, object->cookie->debug_id,
55 			     refcount_read(&object->ref), why);
56 }
57 
58 /*
59  * Increment the usage count on an object;
60  */
61 struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object,
62 						 enum cachefiles_obj_ref_trace why)
63 {
64 	int r;
65 
66 	__refcount_inc(&object->ref, &r);
67 	trace_cachefiles_ref(object->debug_id, object->cookie->debug_id, r, why);
68 	return object;
69 }
70 
71 /*
72  * dispose of a reference to an object
73  */
74 void cachefiles_put_object(struct cachefiles_object *object,
75 			   enum cachefiles_obj_ref_trace why)
76 {
77 	unsigned int object_debug_id = object->debug_id;
78 	unsigned int cookie_debug_id = object->cookie->debug_id;
79 	struct fscache_cache *cache;
80 	bool done;
81 	int r;
82 
83 	done = __refcount_dec_and_test(&object->ref, &r);
84 	trace_cachefiles_ref(object_debug_id, cookie_debug_id, r, why);
85 	if (done) {
86 		_debug("- kill object OBJ%x", object_debug_id);
87 
88 		ASSERTCMP(object->file, ==, NULL);
89 
90 		kfree(object->d_name);
91 
92 		cache = object->volume->cache->cache;
93 		fscache_put_cookie(object->cookie, fscache_cookie_put_object);
94 		object->cookie = NULL;
95 		kmem_cache_free(cachefiles_object_jar, object);
96 		fscache_uncount_object(cache);
97 	}
98 
99 	_leave("");
100 }
101 
102 const struct fscache_cache_ops cachefiles_cache_ops = {
103 	.name			= "cachefiles",
104 	.acquire_volume		= cachefiles_acquire_volume,
105 	.free_volume		= cachefiles_free_volume,
106 };
107