lkml.org 
[lkml]   [2020]   [Nov]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[RFC PATCH 39/76] cachefiles: Implement new fscache I/O backend API
    From
    Date
    Implement the new fscache I/O backend API in cachefiles.  The
    cachefiles_object struct carries a non-accounted file to the cachefiles
    object (so that it doesn't cause ENFILE).

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

    fs/cachefiles/Makefile | 1 +
    fs/cachefiles/interface.c | 13 +++++++
    fs/cachefiles/internal.h | 19 ++++++++++
    fs/cachefiles/io.c | 85 +++++++++++++++++++++++++++++++++++++++++++++
    fs/cachefiles/namei.c | 3 ++
    5 files changed, 120 insertions(+), 1 deletion(-)
    create mode 100644 fs/cachefiles/io.c

    diff --git a/fs/cachefiles/Makefile b/fs/cachefiles/Makefile
    index 3455d3646547..d894d317d6e7 100644
    --- a/fs/cachefiles/Makefile
    +++ b/fs/cachefiles/Makefile
    @@ -7,6 +7,7 @@ cachefiles-y := \
    bind.o \
    daemon.o \
    interface.o \
    + io.o \
    key.o \
    main.o \
    namei.o \
    diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
    index 3f6d2be690bc..dc8c875223bb 100644
    --- a/fs/cachefiles/interface.c
    +++ b/fs/cachefiles/interface.c
    @@ -453,6 +453,18 @@ static unsigned int cachefiles_get_object_usage(const struct fscache_object *_ob
    return atomic_read(&object->usage);
    }

    +static const struct fscache_op_ops cachefiles_io_ops = {
    + .wait_for_operation = __fscache_wait_for_operation,
    + .end_operation = __fscache_end_operation,
    + .read = cachefiles_read,
    + .write = cachefiles_write,
    +};
    +
    +static void cachefiles_begin_operation(struct fscache_op_resources *opr)
    +{
    + opr->ops = &cachefiles_io_ops;
    +}
    +
    const struct fscache_cache_ops cachefiles_cache_ops = {
    .name = "cachefiles",
    .alloc_object = cachefiles_alloc_object,
    @@ -466,4 +478,5 @@ const struct fscache_cache_ops cachefiles_cache_ops = {
    .put_object = cachefiles_put_object,
    .get_object_usage = cachefiles_get_object_usage,
    .sync_cache = cachefiles_sync_cache,
    + .begin_operation = cachefiles_begin_operation,
    };
    diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
    index 16d15291a629..caa6dfbaf333 100644
    --- a/fs/cachefiles/internal.h
    +++ b/fs/cachefiles/internal.h
    @@ -115,6 +115,22 @@ extern const struct fscache_cache_ops cachefiles_cache_ops;
    extern struct fscache_object *cachefiles_grab_object(struct fscache_object *_object,
    enum fscache_obj_ref_trace why);

    +/*
    + * io.c
    + */
    +extern int cachefiles_read(struct fscache_op_resources *opr,
    + loff_t start_pos,
    + struct iov_iter *iter,
    + bool seek_data,
    + fscache_io_terminated_t term_func,
    + void *term_func_priv);
    +extern int cachefiles_write(struct fscache_op_resources *opr,
    + loff_t start_pos,
    + struct iov_iter *iter,
    + fscache_io_terminated_t term_func,
    + void *term_func_priv);
    +extern bool cachefiles_open_object(struct cachefiles_object *obj);
    +
    /*
    * key.c
    */
    @@ -216,7 +232,8 @@ do { \
    \
    ___cache = container_of((object)->fscache.cache, \
    struct cachefiles_cache, cache); \
    - cachefiles_io_error(___cache, FMT, ##__VA_ARGS__); \
    + cachefiles_io_error(___cache, FMT " [o=%08x]", ##__VA_ARGS__, \
    + object->fscache.debug_id); \
    } while (0)


    diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c
    new file mode 100644
    index 000000000000..f1d5976aa28c
    --- /dev/null
    +++ b/fs/cachefiles/io.c
    @@ -0,0 +1,85 @@
    +// SPDX-License-Identifier: GPL-2.0-or-later
    +/* Data I/O routines
    + *
    + * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
    + * Written by David Howells (dhowells@redhat.com)
    + */
    +
    +#include <linux/mount.h>
    +#include <linux/slab.h>
    +#include <linux/file.h>
    +#include <linux/uio.h>
    +#include <linux/xattr.h>
    +#include "internal.h"
    +#include <trace/events/fscache.h>
    +
    +/*
    + * Initiate a read from the cache.
    + */
    +int cachefiles_read(struct fscache_op_resources *opr,
    + loff_t start_pos,
    + struct iov_iter *iter,
    + bool seek_data,
    + fscache_io_terminated_t term_func,
    + void *term_func_priv)
    +{
    + fscache_wait_for_operation(opr, FSCACHE_WANT_READ);
    + fscache_count_io_operation(opr->object->cookie);
    + if (term_func)
    + term_func(term_func_priv, -ENODATA);
    + return -ENODATA;
    +}
    +
    +/*
    + * Initiate a write to the cache.
    + */
    +int cachefiles_write(struct fscache_op_resources *opr,
    + loff_t start_pos,
    + struct iov_iter *iter,
    + fscache_io_terminated_t term_func,
    + void *term_func_priv)
    +{
    + fscache_wait_for_operation(opr, FSCACHE_WANT_WRITE);
    + fscache_count_io_operation(opr->object->cookie);
    + if (term_func)
    + term_func(term_func_priv, -ENOBUFS);
    + return -ENOBUFS;
    +}
    +
    +/*
    + * Open a cache object.
    + */
    +bool cachefiles_open_object(struct cachefiles_object *object)
    +{
    + struct cachefiles_cache *cache =
    + container_of(object->fscache.cache, struct cachefiles_cache, cache);
    + struct file *file;
    + struct path path;
    +
    + path.mnt = cache->mnt;
    + path.dentry = object->backer;
    +
    + file = open_with_fake_path(&path,
    + O_RDWR | O_LARGEFILE | O_DIRECT,
    + d_backing_inode(object->backer),
    + cache->cache_cred);
    + if (IS_ERR(file))
    + goto error;
    +
    + if (!S_ISREG(file_inode(file)->i_mode))
    + goto error_file;
    +
    + if (unlikely(!file->f_op->read_iter) ||
    + unlikely(!file->f_op->write_iter)) {
    + pr_notice("Cache does not support read_iter and write_iter\n");
    + goto error_file;
    + }
    +
    + object->backing_file = file;
    + return true;
    +
    +error_file:
    + fput(file);
    +error:
    + return false;
    +}
    diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
    index 0a7e2031efa2..4b515054d92e 100644
    --- a/fs/cachefiles/namei.c
    +++ b/fs/cachefiles/namei.c
    @@ -490,6 +490,9 @@ bool cachefiles_walk_to_object(struct cachefiles_object *parent,
    } else {
    BUG(); // TODO: open file in data-class subdir
    }
    +
    + if (!cachefiles_open_object(object))
    + goto check_error;
    }

    if (object->new)

    \
     
     \ /
      Last update: 2020-11-20 16:12    [W:4.095 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site