[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <159465803035.1376674.12906653212889524200.stgit@warthog.procyon.org.uk>
Date: Mon, 13 Jul 2020 17:33:50 +0100
From: David Howells <dhowells@...hat.com>
To: Trond Myklebust <trondmy@...merspace.com>,
Anna Schumaker <anna.schumaker@...app.com>,
Steve French <sfrench@...ba.org>,
Alexander Viro <viro@...iv.linux.org.uk>,
Matthew Wilcox <willy@...radead.org>
Cc: Jeff Layton <jlayton@...hat.com>,
Dave Wysochanski <dwysocha@...hat.com>, dhowells@...hat.com,
linux-cachefs@...hat.com, linux-afs@...ts.infradead.org,
linux-nfs@...r.kernel.org, linux-cifs@...r.kernel.org,
ceph-devel@...r.kernel.org, v9fs-developer@...ts.sourceforge.net,
linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH 17/32] cachefiles: Implement new fscache I/O backend API
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@...hat.com>
---
fs/cachefiles/Makefile | 1 +
fs/cachefiles/interface.c | 3 ++
fs/cachefiles/internal.h | 13 +++++++
fs/cachefiles/io.c | 87 +++++++++++++++++++++++++++++++++++++++++++++
fs/cachefiles/namei.c | 3 ++
5 files changed, 107 insertions(+)
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 56ed6f203e1c..4ce7ab5c75db 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -465,4 +465,7 @@ 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,
+ .shape_request = cachefiles_shape_request,
+ .read = cachefiles_read,
+ .write = cachefiles_write,
};
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index 16d15291a629..b82e7f8b00bd 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -115,6 +115,19 @@ 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 void cachefiles_shape_request(struct fscache_object *object,
+ struct fscache_request_shape *shape);
+extern int cachefiles_read(struct fscache_object *object,
+ struct fscache_io_request *req,
+ struct iov_iter *iter);
+extern int cachefiles_write(struct fscache_object *object,
+ struct fscache_io_request *req,
+ struct iov_iter *iter);
+extern bool cachefiles_open_object(struct cachefiles_object *obj);
+
/*
* key.c
*/
diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c
new file mode 100644
index 000000000000..89fd4a24e613
--- /dev/null
+++ b/fs/cachefiles/io.c
@@ -0,0 +1,87 @@
+// 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@...hat.com)
+ */
+
+#include <linux/mount.h>
+#include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/uio.h>
+#include <linux/xattr.h>
+#include "internal.h"
+
+/*
+ * Determine the size of a data extent in a cache object. This must be written
+ * as a whole unit, but can be read piecemeal.
+ */
+void cachefiles_shape_request(struct fscache_object *object,
+ struct fscache_request_shape *shape)
+{
+ return 0;
+}
+
+/*
+ * Initiate a read from the cache.
+ */
+int cachefiles_read(struct fscache_object *object,
+ struct fscache_io_request *req,
+ struct iov_iter *iter)
+{
+ req->error = -ENODATA;
+ if (req->io_done)
+ req->io_done(req);
+ return -ENODATA;
+}
+
+/*
+ * Initiate a write to the cache.
+ */
+int cachefiles_write(struct fscache_object *object,
+ struct fscache_io_request *req,
+ struct iov_iter *iter)
+{
+ req->error = -ENOBUFS;
+ if (req->io_done)
+ req->io_done(req);
+ 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 d1c8828ebbbb..d9c9a7d7eb8a 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -492,6 +492,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)
Powered by blists - more mailing lists