Implement functions to allow the cache backend to add or remove a cache.

Signed-off-by: David Howells <dhowe...@redhat.com>cc: linux-cachefs@redhat.com
---

 fs/fscache/cache.c             |   67 ++++++++++++++++++++++++++++++++++++++++
 include/linux/fscache-cache.h  |   14 ++++++++
 include/trace/events/fscache.h |    6 +++-
 3 files changed, 86 insertions(+), 1 deletion(-)

diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c
index 3cde698c5015..bed491c99834 100644
--- a/fs/fscache/cache.c
+++ b/fs/fscache/cache.c
@@ -171,6 +171,48 @@ void fscache_put_cache(struct fscache_cache *cache,
 }
 EXPORT_SYMBOL(fscache_put_cache);
 
+/**
+ * fscache_add_cache - Declare a cache as being open for business
+ * @cache: The record describing 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);
+
 /*
  * Get an increment on a cache's access counter if the cache is live to prevent
  * it from going away whilst we're accessing it.
@@ -208,6 +250,31 @@ 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.
+ */
+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";
 
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index a10f87421438..d2301ec88ff9 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -17,6 +17,7 @@
 #include <linux/fscache.h>
 
 struct fscache_cache;
+struct fscache_cache_ops;
 enum fscache_cache_trace;
 enum fscache_cookie_trace;
 enum fscache_access_trace;
@@ -34,6 +35,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;
@@ -45,6 +47,14 @@ struct fscache_cache {
        char                    *name;
 };
 
+/*
+ * cache operations
+ */
+struct fscache_cache_ops {
+       /* name of cache provider */
+       const char *name;
+};
+
 static inline enum fscache_cache_state fscache_cache_state(const struct 
fscache_cache *cache)
 {
        return smp_load_acquire(&cache->state);
@@ -74,8 +84,12 @@ static inline bool fscache_set_cache_state_maybe(struct 
fscache_cache *cache,
  */
 extern struct rw_semaphore fscache_addremove_sem;
 extern struct fscache_cache *fscache_acquire_cache(const char *name);
+extern int fscache_add_cache(struct fscache_cache *cache,
+                            const struct fscache_cache_ops *ops,
+                            void *cache_priv);
 extern void fscache_put_cache(struct fscache_cache *cache,
                              enum fscache_cache_trace where);
+extern void fscache_withdraw_cache(struct fscache_cache *cache);
 
 extern void fscache_end_volume_access(struct fscache_volume *volume,
                                      enum fscache_access_trace why);
diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
index 132381921be9..c256f30d4dd4 100644
--- a/include/trace/events/fscache.h
+++ b/include/trace/events/fscache.h
@@ -24,7 +24,9 @@ enum fscache_cache_trace {
        fscache_cache_get_acquire,
        fscache_cache_new_acquire,
        fscache_cache_put_alloc_volume,
+       fscache_cache_put_cache,
        fscache_cache_put_volume,
+       fscache_cache_put_withdraw,
 };
 
 enum fscache_volume_trace {
@@ -76,7 +78,9 @@ enum fscache_access_trace {
        EM(fscache_cache_get_acquire,           "GET acq  ")            \
        EM(fscache_cache_new_acquire,           "NEW acq  ")            \
        EM(fscache_cache_put_alloc_volume,      "PUT alvol")            \
-       E_(fscache_cache_put_volume,            "PUT vol  ")
+       EM(fscache_cache_put_cache,             "PUT cache")            \
+       EM(fscache_cache_put_volume,            "PUT vol  ")            \
+       E_(fscache_cache_put_withdraw,          "PUT withd")
 
 #define fscache_volume_traces                                          \
        EM(fscache_volume_collision,            "*COLLIDE*")            \


--
Linux-cachefs mailing list
Linux-cachefs@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-cachefs

Reply via email to