Commit df98e87f authored by David Howells's avatar David Howells
Browse files

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: default avatarDavid Howells <dhowells@redhat.com>
Reviewed-by: default avatarJeff 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
parent 13871bad
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
@@ -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,
+33 −2
Original line number Diff line number Diff line
@@ -19,6 +19,16 @@
struct cachefiles_cache;
struct cachefiles_object;

enum cachefiles_content {
	/* These values are saved on disk */
	CACHEFILES_CONTENT_NO_DATA	= 0, /* No content stored */
	CACHEFILES_CONTENT_SINGLE	= 1, /* Content is monolithic, all is present */
	CACHEFILES_CONTENT_ALL		= 2, /* Content is all present, no map */
	CACHEFILES_CONTENT_BACKFS_MAP	= 3, /* Content is piecemeal, mapped through backing fs */
	CACHEFILES_CONTENT_DIRTY	= 4, /* Content is dirty (only seen on disk) */
	nr__cachefiles_content
};

/*
 * Cached volume representation.
 */
@@ -31,10 +41,20 @@ struct cachefiles_volume {
};

/*
 * Data file records.
 * Backing file state.
 */
struct cachefiles_object {
	int				debug_id;	/* debugging ID */
	struct fscache_cookie		*cookie;	/* Netfs data storage object cookie */
	struct cachefiles_volume	*volume;	/* Cache volume that holds this object */
	struct list_head		cache_link;	/* Link in cache->*_list */
	struct file			*file;		/* The file representing this object */
	char				*d_name;	/* Backing file name */
	int				debug_id;
	spinlock_t			lock;
	refcount_t			ref;
	u8				d_name_len;	/* Length of filename */
	enum cachefiles_content		content_info:8;	/* Info about content presence */
	unsigned long			flags;
};

/*
@@ -146,6 +166,17 @@ static inline int cachefiles_inject_remove_error(void)
 * interface.c
 */
extern const struct fscache_cache_ops cachefiles_cache_ops;
extern void cachefiles_see_object(struct cachefiles_object *object,
				  enum cachefiles_obj_ref_trace why);
extern struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object,
							enum cachefiles_obj_ref_trace why);
extern void cachefiles_put_object(struct cachefiles_object *object,
				  enum cachefiles_obj_ref_trace why);

/*
 * main.c
 */
extern struct kmem_cache *cachefiles_object_jar;

/*
 * namei.c
+16 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ MODULE_DESCRIPTION("Mounted-filesystem based cache");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");

struct kmem_cache *cachefiles_object_jar;

static struct miscdevice cachefiles_dev = {
	.minor	= MISC_DYNAMIC_MINOR,
	.name	= "cachefiles",
@@ -51,9 +53,22 @@ static int __init cachefiles_init(void)
	if (ret < 0)
		goto error_dev;

	/* create an object jar */
	ret = -ENOMEM;
	cachefiles_object_jar =
		kmem_cache_create("cachefiles_object_jar",
				  sizeof(struct cachefiles_object),
				  0, SLAB_HWCACHE_ALIGN, NULL);
	if (!cachefiles_object_jar) {
		pr_notice("Failed to allocate an object jar\n");
		goto error_object_jar;
	}

	pr_info("Loaded\n");
	return 0;

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

	kmem_cache_destroy(cachefiles_object_jar);
	misc_deregister(&cachefiles_dev);
	cachefiles_unregister_error_injection();
}
+58 −0
Original line number Diff line number Diff line
@@ -18,6 +18,21 @@
#ifndef __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
#define __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY

enum cachefiles_obj_ref_trace {
	cachefiles_obj_get_ioreq,
	cachefiles_obj_new,
	cachefiles_obj_put_alloc_fail,
	cachefiles_obj_put_detach,
	cachefiles_obj_put_ioreq,
	cachefiles_obj_see_clean_commit,
	cachefiles_obj_see_clean_delete,
	cachefiles_obj_see_clean_drop_tmp,
	cachefiles_obj_see_lookup_cookie,
	cachefiles_obj_see_lookup_failed,
	cachefiles_obj_see_withdraw_cookie,
	cachefiles_obj_see_withdrawal,
};

enum fscache_why_object_killed {
	FSCACHE_OBJECT_IS_STALE,
	FSCACHE_OBJECT_IS_WEIRD,
@@ -66,6 +81,20 @@ enum cachefiles_error_trace {
	EM(FSCACHE_OBJECT_WAS_RETIRED,	"was_retired")		\
	E_(FSCACHE_OBJECT_WAS_CULLED,	"was_culled")

#define cachefiles_obj_ref_traces					\
	EM(cachefiles_obj_get_ioreq,		"GET ioreq")		\
	EM(cachefiles_obj_new,			"NEW obj")		\
	EM(cachefiles_obj_put_alloc_fail,	"PUT alloc_fail")	\
	EM(cachefiles_obj_put_detach,		"PUT detach")		\
	EM(cachefiles_obj_put_ioreq,		"PUT ioreq")		\
	EM(cachefiles_obj_see_clean_commit,	"SEE clean_commit")	\
	EM(cachefiles_obj_see_clean_delete,	"SEE clean_delete")	\
	EM(cachefiles_obj_see_clean_drop_tmp,	"SEE clean_drop_tmp")	\
	EM(cachefiles_obj_see_lookup_cookie,	"SEE lookup_cookie")	\
	EM(cachefiles_obj_see_lookup_failed,	"SEE lookup_failed")	\
	EM(cachefiles_obj_see_withdraw_cookie,	"SEE withdraw_cookie")	\
	E_(cachefiles_obj_see_withdrawal,	"SEE withdrawal")

#define cachefiles_trunc_traces						\
	EM(cachefiles_trunc_dio_adjust,		"DIOADJ")		\
	EM(cachefiles_trunc_expand_tmpfile,	"EXPTMP")		\
@@ -100,6 +129,7 @@ enum cachefiles_error_trace {
#define E_(a, b) TRACE_DEFINE_ENUM(a);

cachefiles_obj_kill_traces;
cachefiles_obj_ref_traces;
cachefiles_trunc_traces;
cachefiles_error_traces;

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


TRACE_EVENT(cachefiles_ref,
	    TP_PROTO(unsigned int object_debug_id,
		     unsigned int cookie_debug_id,
		     int usage,
		     enum cachefiles_obj_ref_trace why),

	    TP_ARGS(object_debug_id, cookie_debug_id, usage, why),

	    /* Note that obj may be NULL */
	    TP_STRUCT__entry(
		    __field(unsigned int,			obj		)
		    __field(unsigned int,			cookie		)
		    __field(enum cachefiles_obj_ref_trace,	why		)
		    __field(int,				usage		)
			     ),

	    TP_fast_assign(
		    __entry->obj	= object_debug_id;
		    __entry->cookie	= cookie_debug_id;
		    __entry->usage	= usage;
		    __entry->why	= why;
			   ),

	    TP_printk("c=%08x o=%08x u=%d %s",
		      __entry->cookie, __entry->obj, __entry->usage,
		      __print_symbolic(__entry->why, cachefiles_obj_ref_traces))
	    );

TRACE_EVENT(cachefiles_lookup,
	    TP_PROTO(struct cachefiles_object *obj,
		     struct dentry *de),
+4 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ enum fscache_volume_trace {
enum fscache_cookie_trace {
	fscache_cookie_collision,
	fscache_cookie_discard,
	fscache_cookie_get_attach_object,
	fscache_cookie_get_end_access,
	fscache_cookie_get_hash_collision,
	fscache_cookie_get_inval_work,
@@ -57,6 +58,7 @@ enum fscache_cookie_trace {
	fscache_cookie_new_acquire,
	fscache_cookie_put_hash_collision,
	fscache_cookie_put_lru,
	fscache_cookie_put_object,
	fscache_cookie_put_over_queued,
	fscache_cookie_put_relinquish,
	fscache_cookie_put_withdrawn,
@@ -122,6 +124,7 @@ enum fscache_access_trace {
#define fscache_cookie_traces						\
	EM(fscache_cookie_collision,		"*COLLIDE*")		\
	EM(fscache_cookie_discard,		"DISCARD  ")		\
	EM(fscache_cookie_get_attach_object,	"GET attch")		\
	EM(fscache_cookie_get_hash_collision,	"GET hcoll")		\
	EM(fscache_cookie_get_end_access,	"GQ  endac")		\
	EM(fscache_cookie_get_inval_work,	"GQ  inval")		\
@@ -130,6 +133,7 @@ enum fscache_access_trace {
	EM(fscache_cookie_new_acquire,		"NEW acq  ")		\
	EM(fscache_cookie_put_hash_collision,	"PUT hcoll")		\
	EM(fscache_cookie_put_lru,		"PUT lru  ")		\
	EM(fscache_cookie_put_object,		"PUT obj  ")		\
	EM(fscache_cookie_put_over_queued,	"PQ  overq")		\
	EM(fscache_cookie_put_relinquish,	"PUT relnq")		\
	EM(fscache_cookie_put_withdrawn,	"PUT wthdn")		\