Skip to content

Commit df98e87

Browse files
committed
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 <[email protected]> Reviewed-by: Jeff Layton <[email protected]> cc: [email protected] 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
1 parent 13871ba commit df98e87

File tree

5 files changed

+197
-2
lines changed

5 files changed

+197
-2
lines changed

fs/cachefiles/interface.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,92 @@
1313
#include <trace/events/fscache.h>
1414
#include "internal.h"
1515

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+
16102
const struct fscache_cache_ops cachefiles_cache_ops = {
17103
.name = "cachefiles",
18104
.acquire_volume = cachefiles_acquire_volume,

fs/cachefiles/internal.h

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@
1919
struct cachefiles_cache;
2020
struct cachefiles_object;
2121

22+
enum cachefiles_content {
23+
/* These values are saved on disk */
24+
CACHEFILES_CONTENT_NO_DATA = 0, /* No content stored */
25+
CACHEFILES_CONTENT_SINGLE = 1, /* Content is monolithic, all is present */
26+
CACHEFILES_CONTENT_ALL = 2, /* Content is all present, no map */
27+
CACHEFILES_CONTENT_BACKFS_MAP = 3, /* Content is piecemeal, mapped through backing fs */
28+
CACHEFILES_CONTENT_DIRTY = 4, /* Content is dirty (only seen on disk) */
29+
nr__cachefiles_content
30+
};
31+
2232
/*
2333
* Cached volume representation.
2434
*/
@@ -31,10 +41,20 @@ struct cachefiles_volume {
3141
};
3242

3343
/*
34-
* Data file records.
44+
* Backing file state.
3545
*/
3646
struct cachefiles_object {
37-
int debug_id; /* debugging ID */
47+
struct fscache_cookie *cookie; /* Netfs data storage object cookie */
48+
struct cachefiles_volume *volume; /* Cache volume that holds this object */
49+
struct list_head cache_link; /* Link in cache->*_list */
50+
struct file *file; /* The file representing this object */
51+
char *d_name; /* Backing file name */
52+
int debug_id;
53+
spinlock_t lock;
54+
refcount_t ref;
55+
u8 d_name_len; /* Length of filename */
56+
enum cachefiles_content content_info:8; /* Info about content presence */
57+
unsigned long flags;
3858
};
3959

4060
/*
@@ -146,6 +166,17 @@ static inline int cachefiles_inject_remove_error(void)
146166
* interface.c
147167
*/
148168
extern const struct fscache_cache_ops cachefiles_cache_ops;
169+
extern void cachefiles_see_object(struct cachefiles_object *object,
170+
enum cachefiles_obj_ref_trace why);
171+
extern struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object,
172+
enum cachefiles_obj_ref_trace why);
173+
extern void cachefiles_put_object(struct cachefiles_object *object,
174+
enum cachefiles_obj_ref_trace why);
175+
176+
/*
177+
* main.c
178+
*/
179+
extern struct kmem_cache *cachefiles_object_jar;
149180

150181
/*
151182
* namei.c

fs/cachefiles/main.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ MODULE_DESCRIPTION("Mounted-filesystem based cache");
3131
MODULE_AUTHOR("Red Hat, Inc.");
3232
MODULE_LICENSE("GPL");
3333

34+
struct kmem_cache *cachefiles_object_jar;
35+
3436
static struct miscdevice cachefiles_dev = {
3537
.minor = MISC_DYNAMIC_MINOR,
3638
.name = "cachefiles",
@@ -51,9 +53,22 @@ static int __init cachefiles_init(void)
5153
if (ret < 0)
5254
goto error_dev;
5355

56+
/* create an object jar */
57+
ret = -ENOMEM;
58+
cachefiles_object_jar =
59+
kmem_cache_create("cachefiles_object_jar",
60+
sizeof(struct cachefiles_object),
61+
0, SLAB_HWCACHE_ALIGN, NULL);
62+
if (!cachefiles_object_jar) {
63+
pr_notice("Failed to allocate an object jar\n");
64+
goto error_object_jar;
65+
}
66+
5467
pr_info("Loaded\n");
5568
return 0;
5669

70+
error_object_jar:
71+
misc_deregister(&cachefiles_dev);
5772
error_dev:
5873
cachefiles_unregister_error_injection();
5974
error_einj:
@@ -70,6 +85,7 @@ static void __exit cachefiles_exit(void)
7085
{
7186
pr_info("Unloading\n");
7287

88+
kmem_cache_destroy(cachefiles_object_jar);
7389
misc_deregister(&cachefiles_dev);
7490
cachefiles_unregister_error_injection();
7591
}

include/trace/events/cachefiles.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@
1818
#ifndef __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
1919
#define __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
2020

21+
enum cachefiles_obj_ref_trace {
22+
cachefiles_obj_get_ioreq,
23+
cachefiles_obj_new,
24+
cachefiles_obj_put_alloc_fail,
25+
cachefiles_obj_put_detach,
26+
cachefiles_obj_put_ioreq,
27+
cachefiles_obj_see_clean_commit,
28+
cachefiles_obj_see_clean_delete,
29+
cachefiles_obj_see_clean_drop_tmp,
30+
cachefiles_obj_see_lookup_cookie,
31+
cachefiles_obj_see_lookup_failed,
32+
cachefiles_obj_see_withdraw_cookie,
33+
cachefiles_obj_see_withdrawal,
34+
};
35+
2136
enum fscache_why_object_killed {
2237
FSCACHE_OBJECT_IS_STALE,
2338
FSCACHE_OBJECT_IS_WEIRD,
@@ -66,6 +81,20 @@ enum cachefiles_error_trace {
6681
EM(FSCACHE_OBJECT_WAS_RETIRED, "was_retired") \
6782
E_(FSCACHE_OBJECT_WAS_CULLED, "was_culled")
6883

84+
#define cachefiles_obj_ref_traces \
85+
EM(cachefiles_obj_get_ioreq, "GET ioreq") \
86+
EM(cachefiles_obj_new, "NEW obj") \
87+
EM(cachefiles_obj_put_alloc_fail, "PUT alloc_fail") \
88+
EM(cachefiles_obj_put_detach, "PUT detach") \
89+
EM(cachefiles_obj_put_ioreq, "PUT ioreq") \
90+
EM(cachefiles_obj_see_clean_commit, "SEE clean_commit") \
91+
EM(cachefiles_obj_see_clean_delete, "SEE clean_delete") \
92+
EM(cachefiles_obj_see_clean_drop_tmp, "SEE clean_drop_tmp") \
93+
EM(cachefiles_obj_see_lookup_cookie, "SEE lookup_cookie") \
94+
EM(cachefiles_obj_see_lookup_failed, "SEE lookup_failed") \
95+
EM(cachefiles_obj_see_withdraw_cookie, "SEE withdraw_cookie") \
96+
E_(cachefiles_obj_see_withdrawal, "SEE withdrawal")
97+
6998
#define cachefiles_trunc_traces \
7099
EM(cachefiles_trunc_dio_adjust, "DIOADJ") \
71100
EM(cachefiles_trunc_expand_tmpfile, "EXPTMP") \
@@ -100,6 +129,7 @@ enum cachefiles_error_trace {
100129
#define E_(a, b) TRACE_DEFINE_ENUM(a);
101130

102131
cachefiles_obj_kill_traces;
132+
cachefiles_obj_ref_traces;
103133
cachefiles_trunc_traces;
104134
cachefiles_error_traces;
105135

@@ -113,6 +143,34 @@ cachefiles_error_traces;
113143
#define E_(a, b) { a, b }
114144

115145

146+
TRACE_EVENT(cachefiles_ref,
147+
TP_PROTO(unsigned int object_debug_id,
148+
unsigned int cookie_debug_id,
149+
int usage,
150+
enum cachefiles_obj_ref_trace why),
151+
152+
TP_ARGS(object_debug_id, cookie_debug_id, usage, why),
153+
154+
/* Note that obj may be NULL */
155+
TP_STRUCT__entry(
156+
__field(unsigned int, obj )
157+
__field(unsigned int, cookie )
158+
__field(enum cachefiles_obj_ref_trace, why )
159+
__field(int, usage )
160+
),
161+
162+
TP_fast_assign(
163+
__entry->obj = object_debug_id;
164+
__entry->cookie = cookie_debug_id;
165+
__entry->usage = usage;
166+
__entry->why = why;
167+
),
168+
169+
TP_printk("c=%08x o=%08x u=%d %s",
170+
__entry->cookie, __entry->obj, __entry->usage,
171+
__print_symbolic(__entry->why, cachefiles_obj_ref_traces))
172+
);
173+
116174
TRACE_EVENT(cachefiles_lookup,
117175
TP_PROTO(struct cachefiles_object *obj,
118176
struct dentry *de),

include/trace/events/fscache.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ enum fscache_volume_trace {
4949
enum fscache_cookie_trace {
5050
fscache_cookie_collision,
5151
fscache_cookie_discard,
52+
fscache_cookie_get_attach_object,
5253
fscache_cookie_get_end_access,
5354
fscache_cookie_get_hash_collision,
5455
fscache_cookie_get_inval_work,
@@ -57,6 +58,7 @@ enum fscache_cookie_trace {
5758
fscache_cookie_new_acquire,
5859
fscache_cookie_put_hash_collision,
5960
fscache_cookie_put_lru,
61+
fscache_cookie_put_object,
6062
fscache_cookie_put_over_queued,
6163
fscache_cookie_put_relinquish,
6264
fscache_cookie_put_withdrawn,
@@ -122,6 +124,7 @@ enum fscache_access_trace {
122124
#define fscache_cookie_traces \
123125
EM(fscache_cookie_collision, "*COLLIDE*") \
124126
EM(fscache_cookie_discard, "DISCARD ") \
127+
EM(fscache_cookie_get_attach_object, "GET attch") \
125128
EM(fscache_cookie_get_hash_collision, "GET hcoll") \
126129
EM(fscache_cookie_get_end_access, "GQ endac") \
127130
EM(fscache_cookie_get_inval_work, "GQ inval") \
@@ -130,6 +133,7 @@ enum fscache_access_trace {
130133
EM(fscache_cookie_new_acquire, "NEW acq ") \
131134
EM(fscache_cookie_put_hash_collision, "PUT hcoll") \
132135
EM(fscache_cookie_put_lru, "PUT lru ") \
136+
EM(fscache_cookie_put_object, "PUT obj ") \
133137
EM(fscache_cookie_put_over_queued, "PQ overq") \
134138
EM(fscache_cookie_put_relinquish, "PUT relnq") \
135139
EM(fscache_cookie_put_withdrawn, "PUT wthdn") \

0 commit comments

Comments
 (0)