fscache: Implement functions add/remove a cache
Implement functions to allow the cache backend to add or remove a cache: (1) Declare a cache to be live: int fscache_add_cache(struct fscache_cache *cache, const struct fscache_cache_ops *ops, void *cache_priv); Take a previously acquired cache cookie, set the operations table and private data and mark the cache open for access. (2) Withdraw a cache from service: void fscache_withdraw_cache(struct fscache_cache *cache); This marks the cache as withdrawn and thus prevents further cache-level and volume-level accesses. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> cc: linux-cachefs@redhat.com Link: https://lore.kernel.org/r/163819596022.215744.8799712491432238827.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/163906896599.143852.17049208999019262884.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/163967097870.1823006.3470041000971522030.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/164021505541.640689.1819714759326331054.stgit@warthog.procyon.org.uk/ # v4
This commit is contained in:
parent
a7733fb632
commit
2e0c76aee2
@ -210,12 +210,55 @@ void fscache_relinquish_cache(struct fscache_cache *cache)
|
||||
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
|
||||
@ -278,6 +321,33 @@ void fscache_end_cache_access(struct fscache_cache *cache, enum fscache_access_t
|
||||
wake_up_var(&cache->n_accesses);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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";
|
||||
|
||||
|
@ -33,6 +33,7 @@ enum fscache_cache_state {
|
||||
* Cache cookie.
|
||||
*/
|
||||
struct fscache_cache {
|
||||
const struct fscache_cache_ops *ops;
|
||||
struct list_head cache_link; /* Link in cache list */
|
||||
void *cache_priv; /* Private cache data (or NULL) */
|
||||
refcount_t ref;
|
||||
@ -44,6 +45,14 @@ struct fscache_cache {
|
||||
char *name;
|
||||
};
|
||||
|
||||
/*
|
||||
* cache operations
|
||||
*/
|
||||
struct fscache_cache_ops {
|
||||
/* name of cache provider */
|
||||
const char *name;
|
||||
};
|
||||
|
||||
extern struct workqueue_struct *fscache_wq;
|
||||
|
||||
/*
|
||||
@ -52,6 +61,10 @@ extern struct workqueue_struct *fscache_wq;
|
||||
extern struct rw_semaphore fscache_addremove_sem;
|
||||
extern struct fscache_cache *fscache_acquire_cache(const char *name);
|
||||
extern void fscache_relinquish_cache(struct fscache_cache *cache);
|
||||
extern int fscache_add_cache(struct fscache_cache *cache,
|
||||
const struct fscache_cache_ops *ops,
|
||||
void *cache_priv);
|
||||
extern void fscache_withdraw_cache(struct fscache_cache *cache);
|
||||
|
||||
extern void fscache_end_volume_access(struct fscache_volume *volume,
|
||||
struct fscache_cookie *cookie,
|
||||
|
Loading…
Reference in New Issue
Block a user