linux/fs/netfs/fscache_cookie.c

// SPDX-License-Identifier: GPL-2.0-or-later
/* netfs cookie management
 *
 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells ([email protected])
 *
 * See Documentation/filesystems/caching/netfs-api.rst for more information on
 * the netfs API.
 */

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

struct kmem_cache *fscache_cookie_jar;

static void fscache_cookie_lru_timed_out(struct timer_list *timer);
static void fscache_cookie_lru_worker(struct work_struct *work);
static void fscache_cookie_worker(struct work_struct *work);
static void fscache_unhash_cookie(struct fscache_cookie *cookie);
static void fscache_perform_invalidation(struct fscache_cookie *cookie);

#define fscache_cookie_hash_shift
static struct hlist_bl_head fscache_cookie_hash[1 << fscache_cookie_hash_shift];
static LIST_HEAD(fscache_cookies);
static DEFINE_RWLOCK(fscache_cookies_lock);
static LIST_HEAD(fscache_cookie_lru);
static DEFINE_SPINLOCK(fscache_cookie_lru_lock);
DEFINE_TIMER(fscache_cookie_lru_timer, fscache_cookie_lru_timed_out);
static DECLARE_WORK(fscache_cookie_lru_work, fscache_cookie_lru_worker);
static const char fscache_cookie_states[FSCACHE_COOKIE_STATE__NR] =;
static unsigned int fscache_lru_cookie_timeout =;

void fscache_print_cookie(struct fscache_cookie *cookie, char prefix)
{}

static void fscache_free_cookie(struct fscache_cookie *cookie)
{}

static void __fscache_queue_cookie(struct fscache_cookie *cookie)
{}

static void fscache_queue_cookie(struct fscache_cookie *cookie,
				 enum fscache_cookie_trace where)
{}

/*
 * Initialise the access gate on a cookie by setting a flag to prevent the
 * state machine from being queued when the access counter transitions to 0.
 * We're only interested in this when we withdraw caching services from the
 * cookie.
 */
static void fscache_init_access_gate(struct fscache_cookie *cookie)
{}

/**
 * fscache_end_cookie_access - Unpin a cache at the end of an access.
 * @cookie: A data file cookie
 * @why: An indication of the circumstances of the access for tracing
 *
 * Unpin a cache cookie after we've accessed it and bring a deferred
 * relinquishment or withdrawal state into effect.
 *
 * The @why indicator is provided for tracing purposes.
 */
void fscache_end_cookie_access(struct fscache_cookie *cookie,
			       enum fscache_access_trace why)
{}
EXPORT_SYMBOL();

/*
 * Pin the cache behind a cookie so that we can access it.
 */
static void __fscache_begin_cookie_access(struct fscache_cookie *cookie,
					  enum fscache_access_trace why)
{}

/**
 * fscache_begin_cookie_access - Pin a cache so data can be accessed
 * @cookie: A data file 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 data and returns true if successful.  This works as follows:
 *
 *  (1) If the cookie is not being cached (ie. FSCACHE_COOKIE_IS_CACHING is not
 *      set), we return false to indicate access was not permitted.
 *
 *  (2) If the cookie is being cached, we increment its n_accesses count and
 *      then recheck the IS_CACHING flag, ending the access if it got cleared.
 *
 *  (3) When we end the access, we decrement the cookie's n_accesses and wake
 *      up the any waiters if it reaches 0.
 *
 *  (4) Whilst the cookie is actively being cached, its n_accesses is kept
 *      artificially incremented to prevent wakeups from happening.
 *
 *  (5) When the cache is taken offline or if the cookie is culled, the flag is
 *      cleared to prevent new accesses, the cookie's n_accesses is decremented
 *      and we wait for it to become 0.
 *
 * The @why indicator are merely provided for tracing purposes.
 */
bool fscache_begin_cookie_access(struct fscache_cookie *cookie,
				 enum fscache_access_trace why)
{}

static inline void wake_up_cookie_state(struct fscache_cookie *cookie)
{}

/*
 * Change the state a cookie is at and wake up anyone waiting for that.  Impose
 * an ordering between the stuff stored in the cookie and the state member.
 * Paired with fscache_cookie_state().
 */
static void __fscache_set_cookie_state(struct fscache_cookie *cookie,
				       enum fscache_cookie_state state)
{}

static void fscache_set_cookie_state(struct fscache_cookie *cookie,
				     enum fscache_cookie_state state)
{}

/**
 * fscache_cookie_lookup_negative - Note negative lookup
 * @cookie: The cookie that was being looked up
 *
 * Note that some part of the metadata path in the cache doesn't exist and so
 * we can release any waiting readers in the certain knowledge that there's
 * nothing for them to actually read.
 *
 * This function uses no locking and must only be called from the state machine.
 */
void fscache_cookie_lookup_negative(struct fscache_cookie *cookie)
{}
EXPORT_SYMBOL();

/**
 * fscache_resume_after_invalidation - Allow I/O to resume after invalidation
 * @cookie: The cookie that was invalidated
 *
 * Tell fscache that invalidation is sufficiently complete that I/O can be
 * allowed again.
 */
void fscache_resume_after_invalidation(struct fscache_cookie *cookie)
{}
EXPORT_SYMBOL();

/**
 * fscache_caching_failed - Report that a failure stopped caching on a cookie
 * @cookie: The cookie that was affected
 *
 * Tell fscache that caching on a cookie needs to be stopped due to some sort
 * of failure.
 *
 * This function uses no locking and must only be called from the state machine.
 */
void fscache_caching_failed(struct fscache_cookie *cookie)
{}
EXPORT_SYMBOL();

/*
 * Set the index key in a cookie.  The cookie struct has space for a 16-byte
 * key plus length and hash, but if that's not big enough, it's instead a
 * pointer to a buffer containing 3 bytes of hash, 1 byte of length and then
 * the key data.
 */
static int fscache_set_key(struct fscache_cookie *cookie,
			   const void *index_key, size_t index_key_len)
{}

static bool fscache_cookie_same(const struct fscache_cookie *a,
				const struct fscache_cookie *b)
{}

static atomic_t fscache_cookie_debug_id =;

/*
 * Allocate a cookie.
 */
static struct fscache_cookie *fscache_alloc_cookie(
	struct fscache_volume *volume,
	u8 advice,
	const void *index_key, size_t index_key_len,
	const void *aux_data, size_t aux_data_len,
	loff_t object_size)
{}

static inline bool fscache_cookie_is_dropped(struct fscache_cookie *cookie)
{}

static void fscache_wait_on_collision(struct fscache_cookie *candidate,
				      struct fscache_cookie *wait_for)
{}

/*
 * Attempt to insert the new cookie into the hash.  If there's a collision, we
 * wait for the old cookie to complete if it's being relinquished and an error
 * otherwise.
 */
static bool fscache_hash_cookie(struct fscache_cookie *candidate)
{}

/*
 * Request a cookie to represent a data storage object within a volume.
 *
 * We never let on to the netfs about errors.  We may set a negative cookie
 * pointer, but that's okay
 */
struct fscache_cookie *__fscache_acquire_cookie(
	struct fscache_volume *volume,
	u8 advice,
	const void *index_key, size_t index_key_len,
	const void *aux_data, size_t aux_data_len,
	loff_t object_size)
{}
EXPORT_SYMBOL();

/*
 * Prepare a cache object to be written to.
 */
static void fscache_prepare_to_write(struct fscache_cookie *cookie)
{}

/*
 * Look up a cookie in the cache.
 */
static void fscache_perform_lookup(struct fscache_cookie *cookie)
{}

/*
 * Begin the process of looking up a cookie.  We offload the actual process to
 * a worker thread.
 */
static bool fscache_begin_lookup(struct fscache_cookie *cookie, bool will_modify)
{}

/*
 * Start using the cookie for I/O.  This prevents the backing object from being
 * reaped by VM pressure.
 */
void __fscache_use_cookie(struct fscache_cookie *cookie, bool will_modify)
{}
EXPORT_SYMBOL();

static void fscache_unuse_cookie_locked(struct fscache_cookie *cookie)
{}

/*
 * Stop using the cookie for I/O.
 */
void __fscache_unuse_cookie(struct fscache_cookie *cookie,
			    const void *aux_data, const loff_t *object_size)
{}
EXPORT_SYMBOL();

/*
 * Perform work upon the cookie, such as committing its cache state,
 * relinquishing it or withdrawing the backing cache.  We're protected from the
 * cache going away under us as object withdrawal must come through this
 * non-reentrant work item.
 */
static void fscache_cookie_state_machine(struct fscache_cookie *cookie)
{}

static void fscache_cookie_worker(struct work_struct *work)
{}

/*
 * Wait for the object to become inactive.  The cookie's work item will be
 * scheduled when someone transitions n_accesses to 0 - but if someone's
 * already done that, schedule it anyway.
 */
static void __fscache_withdraw_cookie(struct fscache_cookie *cookie)
{}

static void fscache_cookie_lru_do_one(struct fscache_cookie *cookie)
{}

static void fscache_cookie_lru_worker(struct work_struct *work)
{}

static void fscache_cookie_lru_timed_out(struct timer_list *timer)
{}

static void fscache_cookie_drop_from_lru(struct fscache_cookie *cookie)
{}

/*
 * Remove a cookie from the hash table.
 */
static void fscache_unhash_cookie(struct fscache_cookie *cookie)
{}

static void fscache_drop_withdraw_cookie(struct fscache_cookie *cookie)
{}

/**
 * fscache_withdraw_cookie - Mark a cookie for withdrawal
 * @cookie: The cookie to be withdrawn.
 *
 * Allow the cache backend to withdraw the backing for a cookie for its own
 * reasons, even if that cookie is in active use.
 */
void fscache_withdraw_cookie(struct fscache_cookie *cookie)
{}
EXPORT_SYMBOL();

/*
 * Allow the netfs to release a cookie back to the cache.
 * - the object will be marked as recyclable on disk if retire is true
 */
void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
{}
EXPORT_SYMBOL();

/*
 * Drop a reference to a cookie.
 */
void fscache_put_cookie(struct fscache_cookie *cookie,
			enum fscache_cookie_trace where)
{}
EXPORT_SYMBOL();

/*
 * Get a reference to a cookie.
 */
struct fscache_cookie *fscache_get_cookie(struct fscache_cookie *cookie,
					  enum fscache_cookie_trace where)
{}
EXPORT_SYMBOL();

/*
 * Ask the cache to effect invalidation of a cookie.
 */
static void fscache_perform_invalidation(struct fscache_cookie *cookie)
{}

/*
 * Invalidate an object.
 */
void __fscache_invalidate(struct fscache_cookie *cookie,
			  const void *aux_data, loff_t new_size,
			  unsigned int flags)
{}
EXPORT_SYMBOL();

#ifdef CONFIG_PROC_FS
/*
 * Generate a list of extant cookies in /proc/fs/fscache/cookies
 */
static int fscache_cookies_seq_show(struct seq_file *m, void *v)
{}

static void *fscache_cookies_seq_start(struct seq_file *m, loff_t *_pos)
	__acquires(fscache_cookies_lock)
{}

static void *fscache_cookies_seq_next(struct seq_file *m, void *v, loff_t *_pos)
{}

static void fscache_cookies_seq_stop(struct seq_file *m, void *v)
	__releases(rcu)
{}


const struct seq_operations fscache_cookies_seq_ops =;
#endif