// SPDX-License-Identifier: GPL-2.0-or-later
/* FS-Cache cache handling
 *
 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#define FSCACHE_DEBUG_LEVEL CACHE
#include <linux/export.h>
#include <linux/slab.h>
#include "internal.h"

static LIST_HEAD(fscache_caches);
DECLARE_RWSEM(fscache_addremove_sem);
EXPORT_SYMBOL(fscache_addremove_sem);
DECLARE_WAIT_QUEUE_HEAD(fscache_clearance_waiters);
EXPORT_SYMBOL(fscache_clearance_waiters);

static atomic_t fscache_cache_debug_id;

/*
 * Allocate a cache cookie.
 */
static struct fscache_cache *fscache_alloc_cache(const char *name)
{
	struct fscache_cache *cache;

	cache = kzalloc(sizeof(*cache), GFP_KERNEL);
	if (cache) {
		if (name) {
			cache->name = kstrdup(name, GFP_KERNEL);
			if (!cache->name) {
				kfree(cache);
				return NULL;
			}
		}
		refcount_set(&cache->ref, 1);
		INIT_LIST_HEAD(&cache->cache_link);
		cache->debug_id = atomic_inc_return(&fscache_cache_debug_id);
	}
	return cache;
}

static bool fscache_get_cache_maybe(struct fscache_cache *cache,
				    enum fscache_cache_trace where)
{
	bool success;
	int ref;

	success = __refcount_inc_not_zero(&cache->ref, &ref);
	if (success)
		trace_fscache_cache(cache->debug_id, ref + 1, where);
	return success;
}

/*
 * Look up a cache cookie.
 */
struct fscache_cache *fscache_lookup_cache(const char *name, bool is_cache)
{
	struct fscache_cache *candidate, *cache, *unnamed = NULL;

	/* firstly check for the existence of the cache under read lock */
	down_read(&fscache_addremove_sem);

	list_for_each_entry(cache, &fscache_caches, cache_link) {
		if (cache->name && name && strcmp(cache->name, name) == 0 &&
		    fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
			goto got_cache_r;
		if (!cache->name && !name &&
		    fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
			goto got_cache_r;
	}

	if (!name) {
		list_for_each_entry(cache, &fscache_caches, cache_link) {
			if (cache->name &&
			    fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
				goto got_cache_r;
		}
	}

	up_read(&fscache_addremove_sem);

	/* the cache does not exist - create a candidate */
	candidate = fscache_alloc_cache(name);
	if (!candidate)
		return ERR_PTR(-ENOMEM);

	/* write lock, search again and add if still not present */
	down_write(&fscache_addremove_sem);

	list_for_each_entry(cache, &fscache_caches, cache_link) {
		if (cache->name && name && strcmp(cache->name, name) == 0 &&
		    fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
			goto got_cache_w;
		if (!cache->name) {
			unnamed = cache;
			if (!name &&
			    fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
				goto got_cache_w;
		}
	}

	if (unnamed && is_cache &&
	    fscache_get_cache_maybe(unnamed, fscache_cache_get_acquire))
		goto use_unnamed_cache;

	if (!name) {
		list_for_each_entry(cache, &fscache_caches, cache_link) {
			if (cache->name &&
			    fscache_get_cache_maybe(cache, fscache_cache_get_acquire))
				goto got_cache_w;
		}
	}

	list_add_tail(&candidate->cache_link, &fscache_caches);
	trace_fscache_cache(candidate->debug_id,
			    refcount_read(&candidate->ref),
			    fscache_cache_new_acquire);
	up_write(&fscache_addremove_sem);
	return candidate;

got_cache_r:
	up_read(&fscache_addremove_sem);
	return cache;
use_unnamed_cache:
	cache = unnamed;
	cache->name = candidate->name;
	candidate->name = NULL;
got_cache_w:
	up_write(&fscache_addremove_sem);
	kfree(candidate->name);
	kfree(candidate);
	return cache;
}

/**
 * fscache_acquire_cache - Acquire a cache-level cookie.
 * @name: The name of the cache.
 *
 * Get a cookie to represent an actual cache.  If a name is given and there is
 * a nameless cache record available, this will acquire that and set its name,
 * directing all the volumes using it to this cache.
 *
 * The cache will be switched over to the preparing state if not currently in
 * use, otherwise -EBUSY will be returned.
 */
struct fscache_cache *fscache_acquire_cache(const char *name)
{
	struct fscache_cache *cache;

	ASSERT(name);
	cache = fscache_lookup_cache(name, true);
	if (IS_ERR(cache))
		return cache;

	if (!fscache_set_cache_state_maybe(cache,
					   FSCACHE_CACHE_IS_NOT_PRESENT,
					   FSCACHE_CACHE_IS_PREPARING)) {
		pr_warn("Cache tag %s in use\n", name);
		fscache_put_cache(cache, fscache_cache_put_cache);
		return ERR_PTR(-EBUSY);
	}

	return cache;
}
EXPORT_SYMBOL(fscache_acquire_cache);

/**
 * fscache_put_cache - Release a cache-level cookie.
 * @cache: The cache cookie to be released
 * @where: An indication of where the release happened
 *
 * Release the caller's reference on a cache-level cookie.  The @where
 * indication should give information about the circumstances in which the call
 * occurs and will be logged through a tracepoint.
 */
void fscache_put_cache(struct fscache_cache *cache,
		       enum fscache_cache_trace where)
{
	unsigned int debug_id = cache->debug_id;
	bool zero;
	int ref;

	if (IS_ERR_OR_NULL(cache))
		return;

	zero = __refcount_dec_and_test(&cache->ref, &ref);
	trace_fscache_cache(debug_id, ref - 1, where);

	if (zero) {
		down_write(&fscache_addremove_sem);
		list_del_init(&cache->cache_link);
		up_write(&fscache_addremove_sem);
		kfree(cache->name);
		kfree(cache);
	}
}

/**
 * fscache_relinquish_cache - Reset cache state and release cookie
 * @cache: The cache cookie to be released
 *
 * Reset the state of a cache and release the caller's reference on a cache
 * cookie.
 */
void fscache_relinquish_cache(struct fscache_cache *cache)
{
	enum fscache_cache_trace where =
		(cache->state == FSCACHE_CACHE_IS_PREPARING) ?
		fscache_cache_put_prep_failed :
		fscache_cache_put_relinquish;

	cache->ops = NULL;
	cache->cache_priv = NULL;
	smp_store_release(&cache->state, FSCACHE_CACHE_IS_NOT_PRESENT);
	fscache_put_cache(cache, where);
}
EXPORT_SYMBOL(fscache_relinquish_cache);

/**
 * fscache_add_cache - Declare a cache as being open for business
 * @cache: The cache-level cookie representing the cache
 * @ops: Table of cache operations to use
 * @cache_priv: Private data for the cache record
 *
 * Add a cache to the system, making it available for netfs's to use.
 *
 * See Documentation/filesystems/caching/backend-api.rst for a complete
 * description.
 */
int fscache_add_cache(struct fscache_cache *cache,
		      const struct fscache_cache_ops *ops,
		      void *cache_priv)
{
	int n_accesses;

	_enter("{%s,%s}", ops->name, cache->name);

	BUG_ON(fscache_cache_state(cache) != FSCACHE_CACHE_IS_PREPARING);

	/* Get a ref on the cache cookie and keep its n_accesses counter raised
	 * by 1 to prevent wakeups from transitioning it to 0 until we're
	 * withdrawing caching services from it.
	 */
	n_accesses = atomic_inc_return(&cache->n_accesses);
	trace_fscache_access_cache(cache->debug_id, refcount_read(&cache->ref),
				   n_accesses, fscache_access_cache_pin);

	down_write(&fscache_addremove_sem);

	cache->ops = ops;
	cache->cache_priv = cache_priv;
	fscache_set_cache_state(cache, FSCACHE_CACHE_IS_ACTIVE);

	up_write(&fscache_addremove_sem);
	pr_notice("Cache \"%s\" added (type %s)\n", cache->name, ops->name);
	_leave(" = 0 [%s]", cache->name);
	return 0;
}
EXPORT_SYMBOL(fscache_add_cache);

/**
 * fscache_begin_cache_access - Pin a cache so it can be accessed
 * @cache: The cache-level cookie
 * @why: An indication of the circumstances of the access for tracing
 *
 * Attempt to pin the cache to prevent it from going away whilst we're
 * accessing it and returns true if successful.  This works as follows:
 *
 *  (1) If the cache tests as not live (state is not FSCACHE_CACHE_IS_ACTIVE),
 *      then we return false to indicate access was not permitted.
 *
 *  (2) If the cache tests as live, then we increment the n_accesses count and
 *      then recheck the liveness, ending the access if it ceased to be live.
 *
 *  (3) When we end the access, we decrement n_accesses and wake up the any
 *      waiters if it reaches 0.
 *
 *  (4) Whilst the cache is caching, n_accesses is kept artificially
 *      incremented to prevent wakeups from happening.
 *
 *  (5) When the cache is taken offline, the state is changed to prevent new
 *      accesses, n_accesses is decremented and we wait for n_accesses to
 *      become 0.
 */
bool fscache_begin_cache_access(struct fscache_cache *cache, enum fscache_access_trace why)
{
	int n_accesses;

	if (!fscache_cache_is_live(cache))
		return false;

	n_accesses = atomic_inc_return(&cache->n_accesses);
	smp_mb__after_atomic(); /* Reread live flag after n_accesses */
	trace_fscache_access_cache(cache->debug_id, refcount_read(&cache->ref),
				   n_accesses, why);
	if (!fscache_cache_is_live(cache)) {
		fscache_end_cache_access(cache, fscache_access_unlive);
		return false;
	}
	return true;
}

/**
 * fscache_end_cache_access - Unpin a cache at the end of an access.
 * @cache: The cache-level cookie
 * @why: An indication of the circumstances of the access for tracing
 *
 * Unpin a cache after we've accessed it.  The @why indicator is merely
 * provided for tracing purposes.
 */
void fscache_end_cache_access(struct fscache_cache *cache, enum fscache_access_trace why)
{
	int n_accesses;

	smp_mb__before_atomic();
	n_accesses = atomic_dec_return(&cache->n_accesses);
	trace_fscache_access_cache(cache->debug_id, refcount_read(&cache->ref),
				   n_accesses, why);
	if (n_accesses == 0)
		wake_up_var(&cache->n_accesses);
}

/**
 * fscache_io_error - Note a cache I/O error
 * @cache: The record describing the cache
 *
 * Note that an I/O error occurred in a cache and that it should no longer be
 * used for anything.  This also reports the error into the kernel log.
 *
 * See Documentation/filesystems/caching/backend-api.rst for a complete
 * description.
 */
void fscache_io_error(struct fscache_cache *cache)
{
	if (fscache_set_cache_state_maybe(cache,
					  FSCACHE_CACHE_IS_ACTIVE,
					  FSCACHE_CACHE_GOT_IOERROR))
		pr_err("Cache '%s' stopped due to I/O error\n",
		       cache->name);
}
EXPORT_SYMBOL(fscache_io_error);

/**
 * fscache_withdraw_cache - Withdraw a cache from the active service
 * @cache: The cache cookie
 *
 * Begin the process of withdrawing a cache from service.  This stops new
 * cache-level and volume-level accesses from taking place and waits for
 * currently ongoing cache-level accesses to end.
 */
void fscache_withdraw_cache(struct fscache_cache *cache)
{
	int n_accesses;

	pr_notice("Withdrawing cache \"%s\" (%u objs)\n",
		  cache->name, atomic_read(&cache->object_count));

	fscache_set_cache_state(cache, FSCACHE_CACHE_IS_WITHDRAWN);

	/* Allow wakeups on dec-to-0 */
	n_accesses = atomic_dec_return(&cache->n_accesses);
	trace_fscache_access_cache(cache->debug_id, refcount_read(&cache->ref),
				   n_accesses, fscache_access_cache_unpin);

	wait_var_event(&cache->n_accesses,
		       atomic_read(&cache->n_accesses) == 0);
}
EXPORT_SYMBOL(fscache_withdraw_cache);

#ifdef CONFIG_PROC_FS
static const char fscache_cache_states[NR__FSCACHE_CACHE_STATE] = "-PAEW";

/*
 * Generate a list of caches in /proc/fs/fscache/caches
 */
static int fscache_caches_seq_show(struct seq_file *m, void *v)
{
	struct fscache_cache *cache;

	if (v == &fscache_caches) {
		seq_puts(m,
			 "CACHE    REF   VOLS  OBJS  ACCES S NAME\n"
			 "======== ===== ===== ===== ===== = ===============\n"
			 );
		return 0;
	}

	cache = list_entry(v, struct fscache_cache, cache_link);
	seq_printf(m,
		   "%08x %5d %5d %5d %5d %c %s\n",
		   cache->debug_id,
		   refcount_read(&cache->ref),
		   atomic_read(&cache->n_volumes),
		   atomic_read(&cache->object_count),
		   atomic_read(&cache->n_accesses),
		   fscache_cache_states[cache->state],
		   cache->name ?: "-");
	return 0;
}

static void *fscache_caches_seq_start(struct seq_file *m, loff_t *_pos)
	__acquires(fscache_addremove_sem)
{
	down_read(&fscache_addremove_sem);
	return seq_list_start_head(&fscache_caches, *_pos);
}

static void *fscache_caches_seq_next(struct seq_file *m, void *v, loff_t *_pos)
{
	return seq_list_next(v, &fscache_caches, _pos);
}

static void fscache_caches_seq_stop(struct seq_file *m, void *v)
	__releases(fscache_addremove_sem)
{
	up_read(&fscache_addremove_sem);
}

const struct seq_operations fscache_caches_seq_ops = {
	.start  = fscache_caches_seq_start,
	.next   = fscache_caches_seq_next,
	.stop   = fscache_caches_seq_stop,
	.show   = fscache_caches_seq_show,
};
#endif /* CONFIG_PROC_FS */
