lkml.org 
[lkml]   [2021]   [Oct]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH v2 16/53] fscache: Provide and use cache methods to lookup/create/free a volume
    From
    Date
    Add cache methods to lookup, create and remove a volume.

    Looking up or creating the volume requires the cache pinning for access;
    freeing the volume requires the volume pinning for access.

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

    fs/fscache/volume.c | 66 ++++++++++++++++++++++++++++++++++++++--
    include/linux/fscache-cache.h | 6 ++++
    include/trace/events/fscache.h | 11 ++++++-
    3 files changed, 79 insertions(+), 4 deletions(-)

    diff --git a/fs/fscache/volume.c b/fs/fscache/volume.c
    index d539d6ec2664..d1e57ce95b72 100644
    --- a/fs/fscache/volume.c
    +++ b/fs/fscache/volume.c
    @@ -15,6 +15,8 @@ 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)
    {
    @@ -179,7 +181,7 @@ static struct fscache_volume *fscache_alloc_volume(const char *volume_key,
    volume->cache = cache;
    volume->coherency = coherency_data;
    INIT_LIST_HEAD(&volume->proc_link);
    - INIT_WORK(&volume->work, NULL /* PLACEHOLDER */);
    + INIT_WORK(&volume->work, fscache_create_volume_work);
    refcount_set(&volume->ref, 1);
    spin_lock_init(&volume->lock);

    @@ -216,6 +218,58 @@ static struct fscache_volume *fscache_alloc_volume(const char *volume_key,
    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_bit_unlock(FSCACHE_VOLUME_CREATING, &volume->flags);
    + wake_up_bit(&volume->flags, FSCACHE_VOLUME_CREATING);
    + 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.
    */
    @@ -234,7 +288,7 @@ struct fscache_volume *__fscache_acquire_volume(const char *volume_key,
    return NULL;
    }

    - // PLACEHOLDER: Create the volume if we have a cache available
    + fscache_create_volume(volume, false);
    return volume;
    }
    EXPORT_SYMBOL(__fscache_acquire_volume);
    @@ -281,7 +335,13 @@ static void fscache_free_volume(struct fscache_volume *volume)
    struct fscache_cache *cache = volume->cache;

    if (volume->cache_priv) {
    - // PLACEHOLDER: Detach any attached cache
    + __fscache_begin_volume_access(volume, fscache_access_relinquish_volume);
    + if (volume->cache_priv) {
    + const struct fscache_cache_ops *ops = cache->ops;
    + if (ops->free_volume)
    + ops->free_volume(volume);
    + }
    + fscache_end_volume_access(volume, fscache_access_relinquish_volume_end);
    }

    down_write(&fscache_addremove_sem);
    diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
    index d2301ec88ff9..558d4bbbe486 100644
    --- a/include/linux/fscache-cache.h
    +++ b/include/linux/fscache-cache.h
    @@ -53,6 +53,12 @@ struct fscache_cache {
    struct fscache_cache_ops {
    /* name of cache provider */
    const char *name;
    +
    + /* Acquire a volume */
    + void (*acquire_volume)(struct fscache_volume *volume);
    +
    + /* Free the cache's data attached to a volume */
    + void (*free_volume)(struct fscache_volume *volume);
    };

    static inline enum fscache_cache_state fscache_cache_state(const struct fscache_cache *cache)
    diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
    index c256f30d4dd4..3476cc7fdb25 100644
    --- a/include/trace/events/fscache.h
    +++ b/include/trace/events/fscache.h
    @@ -63,8 +63,12 @@ enum fscache_cookie_trace {
    };

    enum fscache_access_trace {
    + fscache_access_acquire_volume,
    + fscache_access_acquire_volume_end,
    fscache_access_cache_pin,
    fscache_access_cache_unpin,
    + fscache_access_relinquish_volume,
    + fscache_access_relinquish_volume_end,
    fscache_access_unlive,
    };

    @@ -94,7 +98,8 @@ enum fscache_access_trace {
    EM(fscache_volume_put_hash_collision, "PUT hcoll") \
    EM(fscache_volume_put_relinquish, "PUT relnq") \
    EM(fscache_volume_see_create_work, "SEE creat") \
    - E_(fscache_volume_see_hash_wake, "SEE hwake")
    + EM(fscache_volume_see_hash_wake, "SEE hwake") \
    + E_(fscache_volume_wait_create_work, "WAIT crea")

    #define fscache_cookie_traces \
    EM(fscache_cookie_collision, "*COLLIDE*") \
    @@ -113,8 +118,12 @@ enum fscache_access_trace {
    E_(fscache_cookie_see_work, "- work ")

    #define fscache_access_traces \
    + EM(fscache_access_acquire_volume, "BEGIN acq_vol") \
    + EM(fscache_access_acquire_volume_end, "END acq_vol") \
    EM(fscache_access_cache_pin, "PIN cache ") \
    EM(fscache_access_cache_unpin, "UNPIN cache ") \
    + EM(fscache_access_relinquish_volume, "BEGIN rlq_vol") \
    + EM(fscache_access_relinquish_volume_end,"END rlq_vol") \
    E_(fscache_access_unlive, "END unlive ")

    /*

    \
     
     \ /
      Last update: 2021-10-22 21:04    [W:4.097 / U:0.644 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site