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

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

#define fscache_volume_hash_shift 10
static struct hlist_bl_head fscache_volume_hash[1 << fscache_volume_hash_shift];
static atomic_t fscache_volume_debug_id;
static LIST_HEAD(fscache_volumes);

static void fscache_create_volume_work(struct work_struct *work);

struct fscache_volume *fscache_get_volume(struct fscache_volume *volume,
					  enum fscache_volume_trace where)
{
	int ref;

	__refcount_inc(&volume->ref, &ref);
	trace_fscache_volume(volume->debug_id, ref + 1, where);
	return volume;
}

struct fscache_volume *fscache_try_get_volume(struct fscache_volume *volume,
					      enum fscache_volume_trace where)
{
	int ref;

	if (!__refcount_inc_not_zero(&volume->ref, &ref))
		return NULL;

	trace_fscache_volume(volume->debug_id, ref + 1, where);
	return volume;
}
EXPORT_SYMBOL(fscache_try_get_volume);

static void fscache_see_volume(struct fscache_volume *volume,
			       enum fscache_volume_trace where)
{
	int ref = refcount_read(&volume->ref);

	trace_fscache_volume(volume->debug_id, ref, where);
}

/*
 * Pin the cache behind a volume so that we can access it.
 */
static void __fscache_begin_volume_access(struct fscache_volume *volume,
					  struct fscache_cookie *cookie,
					  enum fscache_access_trace why)
{
	int n_accesses;

	n_accesses = atomic_inc_return(&volume->n_accesses);
	smp_mb__after_atomic();
	trace_fscache_access_volume(volume->debug_id, cookie ? cookie->debug_id : 0,
				    refcount_read(&volume->ref),
				    n_accesses, why);
}

/**
 * fscache_begin_volume_access - Pin a cache so a volume can be accessed
 * @volume: The volume cookie
 * @cookie: A datafile cookie for a tracing reference (or NULL)
 * @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 a volume 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 volume's n_accesses
 *      count and then recheck the cache liveness, ending the access if it
 *      ceased to be live.
 *
 *  (3) When we end the access, we decrement the volume's n_accesses and wake
 *      up the any waiters if it reaches 0.
 *
 *  (4) Whilst the cache is caching, the volume's 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, the volume's n_accesses is decremented and we wait for it to
 *      become 0.
 *
 * The datafile @cookie and the @why indicator are merely provided for tracing
 * purposes.
 */
bool fscache_begin_volume_access(struct fscache_volume *volume,
				 struct fscache_cookie *cookie,
				 enum fscache_access_trace why)
{
	if (!fscache_cache_is_live(volume->cache))
		return false;
	__fscache_begin_volume_access(volume, cookie, why);
	if (!fscache_cache_is_live(volume->cache)) {
		fscache_end_volume_access(volume, cookie, fscache_access_unlive);
		return false;
	}
	return true;
}

/**
 * fscache_end_volume_access - Unpin a cache at the end of an access.
 * @volume: The volume cookie
 * @cookie: A datafile cookie for a tracing reference (or NULL)
 * @why: An indication of the circumstances of the access for tracing
 *
 * Unpin a cache volume after we've accessed it.  The datafile @cookie and the
 * @why indicator are merely provided for tracing purposes.
 */
void fscache_end_volume_access(struct fscache_volume *volume,
			       struct fscache_cookie *cookie,
			       enum fscache_access_trace why)
{
	int n_accesses;

	smp_mb__before_atomic();
	n_accesses = atomic_dec_return(&volume->n_accesses);
	trace_fscache_access_volume(volume->debug_id, cookie ? cookie->debug_id : 0,
				    refcount_read(&volume->ref),
				    n_accesses, why);
	if (n_accesses == 0)
		wake_up_var(&volume->n_accesses);
}
EXPORT_SYMBOL(fscache_end_volume_access);

static bool fscache_volume_same(const struct fscache_volume *a,
				const struct fscache_volume *b)
{
	size_t klen;

	if (a->key_hash	!= b->key_hash ||
	    a->cache	!= b->cache ||
	    a->key[0]	!= b->key[0])
		return false;

	klen = round_up(a->key[0] + 1, sizeof(__le32));
	return memcmp(a->key, b->key, klen) == 0;
}

static bool fscache_is_acquire_pending(struct fscache_volume *volume)
{
	return test_bit(FSCACHE_VOLUME_ACQUIRE_PENDING, &volume->flags);
}

static void fscache_wait_on_volume_collision(struct fscache_volume *candidate,
					     unsigned int collidee_debug_id)
{
	wait_on_bit_timeout(&candidate->flags, FSCACHE_VOLUME_ACQUIRE_PENDING,
			    TASK_UNINTERRUPTIBLE, 20 * HZ);
	if (fscache_is_acquire_pending(candidate)) {
		pr_notice("Potential volume collision new=%08x old=%08x",
			  candidate->debug_id, collidee_debug_id);
		fscache_stat(&fscache_n_volumes_collision);
		wait_on_bit(&candidate->flags, FSCACHE_VOLUME_ACQUIRE_PENDING,
			    TASK_UNINTERRUPTIBLE);
	}
}

/*
 * Attempt to insert the new volume into the hash.  If there's a collision, we
 * wait for the old volume to complete if it's being relinquished and an error
 * otherwise.
 */
static bool fscache_hash_volume(struct fscache_volume *candidate)
{
	struct fscache_volume *cursor;
	struct hlist_bl_head *h;
	struct hlist_bl_node *p;
	unsigned int bucket, collidee_debug_id = 0;

	bucket = candidate->key_hash & (ARRAY_SIZE(fscache_volume_hash) - 1);
	h = &fscache_volume_hash[bucket];

	hlist_bl_lock(h);
	hlist_bl_for_each_entry(cursor, p, h, hash_link) {
		if (fscache_volume_same(candidate, cursor)) {
			if (!test_bit(FSCACHE_VOLUME_RELINQUISHED, &cursor->flags))
				goto collision;
			fscache_see_volume(cursor, fscache_volume_get_hash_collision);
			set_bit(FSCACHE_VOLUME_COLLIDED_WITH, &cursor->flags);
			set_bit(FSCACHE_VOLUME_ACQUIRE_PENDING, &candidate->flags);
			collidee_debug_id = cursor->debug_id;
			break;
		}
	}

	hlist_bl_add_head(&candidate->hash_link, h);
	hlist_bl_unlock(h);

	if (fscache_is_acquire_pending(candidate))
		fscache_wait_on_volume_collision(candidate, collidee_debug_id);
	return true;

collision:
	fscache_see_volume(cursor, fscache_volume_collision);
	hlist_bl_unlock(h);
	return false;
}

/*
 * Allocate and initialise a volume representation cookie.
 */
static struct fscache_volume *fscache_alloc_volume(const char *volume_key,
						   const char *cache_name,
						   const void *coherency_data,
						   size_t coherency_len)
{
	struct fscache_volume *volume;
	struct fscache_cache *cache;
	size_t klen, hlen;
	u8 *key;

	klen = strlen(volume_key);
	if (klen > NAME_MAX)
		return NULL;

	if (!coherency_data)
		coherency_len = 0;

	cache = fscache_lookup_cache(cache_name, false);
	if (IS_ERR(cache))
		return NULL;

	volume = kzalloc(struct_size(volume, coherency, coherency_len),
			 GFP_KERNEL);
	if (!volume)
		goto err_cache;

	volume->cache = cache;
	volume->coherency_len = coherency_len;
	if (coherency_data)
		memcpy(volume->coherency, coherency_data, coherency_len);
	INIT_LIST_HEAD(&volume->proc_link);
	INIT_WORK(&volume->work, fscache_create_volume_work);
	refcount_set(&volume->ref, 1);
	spin_lock_init(&volume->lock);

	/* Stick the length on the front of the key and pad it out to make
	 * hashing easier.
	 */
	hlen = round_up(1 + klen + 1, sizeof(__le32));
	key = kzalloc(hlen, GFP_KERNEL);
	if (!key)
		goto err_vol;
	key[0] = klen;
	memcpy(key + 1, volume_key, klen);

	volume->key = key;
	volume->key_hash = fscache_hash(0, key, hlen);

	volume->debug_id = atomic_inc_return(&fscache_volume_debug_id);
	down_write(&fscache_addremove_sem);
	atomic_inc(&cache->n_volumes);
	list_add_tail(&volume->proc_link, &fscache_volumes);
	fscache_see_volume(volume, fscache_volume_new_acquire);
	fscache_stat(&fscache_n_volumes);
	up_write(&fscache_addremove_sem);
	_leave(" = v=%x", volume->debug_id);
	return volume;

err_vol:
	kfree(volume);
err_cache:
	fscache_put_cache(cache, fscache_cache_put_alloc_volume);
	fscache_stat(&fscache_n_volumes_nomem);
	return NULL;
}

/*
 * Create a volume's representation on disk.  Have a volume ref and a cache
 * access we have to release.
 */
static void fscache_create_volume_work(struct work_struct *work)
{
	const struct fscache_cache_ops *ops;
	struct fscache_volume *volume =
		container_of(work, struct fscache_volume, work);

	fscache_see_volume(volume, fscache_volume_see_create_work);

	ops = volume->cache->ops;
	if (ops->acquire_volume)
		ops->acquire_volume(volume);
	fscache_end_cache_access(volume->cache,
				 fscache_access_acquire_volume_end);

	clear_and_wake_up_bit(FSCACHE_VOLUME_CREATING, &volume->flags);
	fscache_put_volume(volume, fscache_volume_put_create_work);
}

/*
 * Dispatch a worker thread to create a volume's representation on disk.
 */
void fscache_create_volume(struct fscache_volume *volume, bool wait)
{
	if (test_and_set_bit(FSCACHE_VOLUME_CREATING, &volume->flags))
		goto maybe_wait;
	if (volume->cache_priv)
		goto no_wait; /* We raced */
	if (!fscache_begin_cache_access(volume->cache,
					fscache_access_acquire_volume))
		goto no_wait;

	fscache_get_volume(volume, fscache_volume_get_create_work);
	if (!schedule_work(&volume->work))
		fscache_put_volume(volume, fscache_volume_put_create_work);

maybe_wait:
	if (wait) {
		fscache_see_volume(volume, fscache_volume_wait_create_work);
		wait_on_bit(&volume->flags, FSCACHE_VOLUME_CREATING,
			    TASK_UNINTERRUPTIBLE);
	}
	return;
no_wait:
	clear_bit_unlock(FSCACHE_VOLUME_CREATING, &volume->flags);
	wake_up_bit(&volume->flags, FSCACHE_VOLUME_CREATING);
}

/*
 * Acquire a volume representation cookie and link it to a (proposed) cache.
 */
struct fscache_volume *__fscache_acquire_volume(const char *volume_key,
						const char *cache_name,
						const void *coherency_data,
						size_t coherency_len)
{
	struct fscache_volume *volume;

	volume = fscache_alloc_volume(volume_key, cache_name,
				      coherency_data, coherency_len);
	if (!volume)
		return ERR_PTR(-ENOMEM);

	if (!fscache_hash_volume(volume)) {
		fscache_put_volume(volume, fscache_volume_put_hash_collision);
		return ERR_PTR(-EBUSY);
	}

	fscache_create_volume(volume, false);
	return volume;
}
EXPORT_SYMBOL(__fscache_acquire_volume);

static void fscache_wake_pending_volume(struct fscache_volume *volume,
					struct hlist_bl_head *h)
{
	struct fscache_volume *cursor;
	struct hlist_bl_node *p;

	hlist_bl_for_each_entry(cursor, p, h, hash_link) {
		if (fscache_volume_same(cursor, volume)) {
			fscache_see_volume(cursor, fscache_volume_see_hash_wake);
			clear_and_wake_up_bit(FSCACHE_VOLUME_ACQUIRE_PENDING,
					      &cursor->flags);
			return;
		}
	}
}

/*
 * Remove a volume cookie from the hash table.
 */
static void fscache_unhash_volume(struct fscache_volume *volume)
{
	struct hlist_bl_head *h;
	unsigned int bucket;

	bucket = volume->key_hash & (ARRAY_SIZE(fscache_volume_hash) - 1);
	h = &fscache_volume_hash[bucket];

	hlist_bl_lock(h);
	hlist_bl_del(&volume->hash_link);
	if (test_bit(FSCACHE_VOLUME_COLLIDED_WITH, &volume->flags))
		fscache_wake_pending_volume(volume, h);
	hlist_bl_unlock(h);
}

/*
 * Drop a cache's volume attachments.
 */
static void fscache_free_volume(struct fscache_volume *volume)
{
	struct fscache_cache *cache = volume->cache;

	if (volume->cache_priv) {
		__fscache_begin_volume_access(volume, NULL,
					      fscache_access_relinquish_volume);
		if (volume->cache_priv)
			cache->ops->free_volume(volume);
		fscache_end_volume_access(volume, NULL,
					  fscache_access_relinquish_volume_end);
	}

	down_write(&fscache_addremove_sem);
	list_del_init(&volume->proc_link);
	atomic_dec(&volume->cache->n_volumes);
	up_write(&fscache_addremove_sem);

	if (!hlist_bl_unhashed(&volume->hash_link))
		fscache_unhash_volume(volume);

	trace_fscache_volume(volume->debug_id, 0, fscache_volume_free);
	kfree(volume->key);
	kfree(volume);
	fscache_stat_d(&fscache_n_volumes);
	fscache_put_cache(cache, fscache_cache_put_volume);
}

/*
 * Drop a reference to a volume cookie.
 */
void fscache_put_volume(struct fscache_volume *volume,
			enum fscache_volume_trace where)
{
	if (volume) {
		unsigned int debug_id = volume->debug_id;
		bool zero;
		int ref;

		zero = __refcount_dec_and_test(&volume->ref, &ref);
		trace_fscache_volume(debug_id, ref - 1, where);
		if (zero)
			fscache_free_volume(volume);
	}
}
EXPORT_SYMBOL(fscache_put_volume);

/*
 * Relinquish a volume representation cookie.
 */
void __fscache_relinquish_volume(struct fscache_volume *volume,
				 const void *coherency_data,
				 bool invalidate)
{
	if (WARN_ON(test_and_set_bit(FSCACHE_VOLUME_RELINQUISHED, &volume->flags)))
		return;

	if (invalidate) {
		set_bit(FSCACHE_VOLUME_INVALIDATE, &volume->flags);
	} else if (coherency_data) {
		memcpy(volume->coherency, coherency_data, volume->coherency_len);
	}

	fscache_put_volume(volume, fscache_volume_put_relinquish);
}
EXPORT_SYMBOL(__fscache_relinquish_volume);

/**
 * fscache_withdraw_volume - Withdraw a volume from being cached
 * @volume: Volume cookie
 *
 * Withdraw a cache volume from service, waiting for all accesses to complete
 * before returning.
 */
void fscache_withdraw_volume(struct fscache_volume *volume)
{
	int n_accesses;

	_debug("withdraw V=%x", volume->debug_id);

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

	wait_var_event(&volume->n_accesses,
		       atomic_read(&volume->n_accesses) == 0);
}
EXPORT_SYMBOL(fscache_withdraw_volume);

#ifdef CONFIG_PROC_FS
/*
 * Generate a list of volumes in /proc/fs/fscache/volumes
 */
static int fscache_volumes_seq_show(struct seq_file *m, void *v)
{
	struct fscache_volume *volume;

	if (v == &fscache_volumes) {
		seq_puts(m,
			 "VOLUME   REF   nCOOK ACC FL CACHE           KEY\n"
			 "======== ===== ===== === == =============== ================\n");
		return 0;
	}

	volume = list_entry(v, struct fscache_volume, proc_link);
	seq_printf(m,
		   "%08x %5d %5d %3d %02lx %-15.15s %s\n",
		   volume->debug_id,
		   refcount_read(&volume->ref),
		   atomic_read(&volume->n_cookies),
		   atomic_read(&volume->n_accesses),
		   volume->flags,
		   volume->cache->name ?: "-",
		   volume->key + 1);
	return 0;
}

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

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

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

const struct seq_operations fscache_volumes_seq_ops = {
	.start  = fscache_volumes_seq_start,
	.next   = fscache_volumes_seq_next,
	.stop   = fscache_volumes_seq_stop,
	.show   = fscache_volumes_seq_show,
};
#endif /* CONFIG_PROC_FS */
