OSDN Git Service

fscache: Implement functions add/remove a cache
authorDavid Howells <dhowells@redhat.com>
Wed, 20 Oct 2021 14:00:26 +0000 (15:00 +0100)
committerDavid Howells <dhowells@redhat.com>
Fri, 7 Jan 2022 09:22:19 +0000 (09:22 +0000)
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/
Link: https://lore.kernel.org/r/163906896599.143852.17049208999019262884.stgit@warthog.procyon.org.uk/
Link: https://lore.kernel.org/r/163967097870.1823006.3470041000971522030.stgit@warthog.procyon.org.uk/
Link: https://lore.kernel.org/r/164021505541.640689.1819714759326331054.stgit@warthog.procyon.org.uk/
fs/fscache/cache.c
include/linux/fscache-cache.h

index e867cff..bbd102b 100644 (file)
@@ -210,6 +210,7 @@ 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);
@@ -217,6 +218,48 @@ void fscache_relinquish_cache(struct fscache_cache *cache)
 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
@@ -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";
 
index 6662440..f78add6 100644 (file)
@@ -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,