From: Bernd Schubert <bschubert@ddn.com>
To: linux-fsdevel@vger.kernel.org
Cc: Dharmendra Singh <dsingh@ddn.com>,
Bernd Schubert <bschubert@ddn.com>,
Miklos Szeredi <miklos@szeredi.hu>,
Amir Goldstein <amir73il@gmail.com>,
fuse-devel@lists.sourceforge.net
Subject: [PATCH 11/13] fuse: Add support to copy from/to the ring buffer
Date: Tue, 21 Mar 2023 02:10:45 +0100 [thread overview]
Message-ID: <20230321011047.3425786-12-bschubert@ddn.com> (raw)
In-Reply-To: <20230321011047.3425786-1-bschubert@ddn.com>
This adds support to existing fuse copy code to copy
from/to the ring buffer. The ring buffer is here mmaped
shared between kernel and userspace.
This also fuse_ prefixes the copy_out_args function
Signed-off-by: Bernd Schubert <bschubert@ddn.com>
cc: Miklos Szeredi <miklos@szeredi.hu>
cc: linux-fsdevel@vger.kernel.org
cc: Amir Goldstein <amir73il@gmail.com>
cc: fuse-devel@lists.sourceforge.net
---
fs/fuse/dev.c | 60 ++++++++++++++++++++++++++------------------
fs/fuse/fuse_dev_i.h | 35 ++++++++++++++++++++++++++
2 files changed, 70 insertions(+), 25 deletions(-)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 4e79cdba540c..de9193f66c8b 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -628,21 +628,7 @@ static int unlock_request(struct fuse_req *req)
return err;
}
-struct fuse_copy_state {
- int write;
- struct fuse_req *req;
- struct iov_iter *iter;
- struct pipe_buffer *pipebufs;
- struct pipe_buffer *currbuf;
- struct pipe_inode_info *pipe;
- unsigned long nr_segs;
- struct page *pg;
- unsigned len;
- unsigned offset;
- unsigned move_pages:1;
-};
-
-static void fuse_copy_init(struct fuse_copy_state *cs, int write,
+void fuse_copy_init(struct fuse_copy_state *cs, int write,
struct iov_iter *iter)
{
memset(cs, 0, sizeof(*cs));
@@ -653,6 +639,7 @@ static void fuse_copy_init(struct fuse_copy_state *cs, int write,
/* Unmap and put previous page of userspace buffer */
static void fuse_copy_finish(struct fuse_copy_state *cs)
{
+
if (cs->currbuf) {
struct pipe_buffer *buf = cs->currbuf;
@@ -717,6 +704,10 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
cs->pipebufs++;
cs->nr_segs++;
}
+ } else if (cs->is_uring) {
+ if (cs->ring.offset > cs->ring.buf_sz)
+ return -ERANGE;
+ cs->len = cs->ring.buf_sz - cs->ring.offset;
} else {
size_t off;
err = iov_iter_get_pages2(cs->iter, &page, PAGE_SIZE, 1, &off);
@@ -735,21 +726,35 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
{
unsigned ncpy = min(*size, cs->len);
+
if (val) {
- void *pgaddr = kmap_local_page(cs->pg);
- void *buf = pgaddr + cs->offset;
+
+ void *pgaddr;
+ void *buf;
+
+ if (cs->is_uring) {
+ buf = cs->ring.buf + cs->ring.offset;
+ cs->ring.offset += ncpy;
+
+ } else {
+ pgaddr = kmap_local_page(cs->pg);
+ buf = pgaddr + cs->offset;
+ }
if (cs->write)
memcpy(buf, *val, ncpy);
else
memcpy(*val, buf, ncpy);
- kunmap_local(pgaddr);
+ if (pgaddr)
+ kunmap_local(pgaddr);
+
*val += ncpy;
}
*size -= ncpy;
cs->len -= ncpy;
cs->offset += ncpy;
+
return ncpy;
}
@@ -997,9 +1002,9 @@ static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
}
/* Copy request arguments to/from userspace buffer */
-static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
- unsigned argpages, struct fuse_arg *args,
- int zeroing)
+int fuse_copy_args(struct fuse_copy_state *cs, unsigned int numargs,
+ unsigned int argpages, struct fuse_arg *args,
+ int zeroing)
{
int err = 0;
unsigned i;
@@ -1806,10 +1811,15 @@ static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique)
return NULL;
}
-static int copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
- unsigned nbytes)
+int fuse_copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
+ unsigned int nbytes)
{
- unsigned reqsize = sizeof(struct fuse_out_header);
+
+ unsigned int reqsize = 0;
+
+ /* Uring has the out header outside of args */
+ if (!cs->is_uring)
+ reqsize = sizeof(struct fuse_out_header);
reqsize += fuse_len_args(args->out_numargs, args->out_args);
@@ -1909,7 +1919,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
if (oh.error)
err = nbytes != sizeof(oh) ? -EINVAL : 0;
else
- err = copy_out_args(cs, req->args, nbytes);
+ err = fuse_copy_out_args(cs, req->args, nbytes);
fuse_copy_finish(cs);
spin_lock(&fpq->lock);
diff --git a/fs/fuse/fuse_dev_i.h b/fs/fuse/fuse_dev_i.h
index aea1f3f7aa5d..ccd128f81628 100644
--- a/fs/fuse/fuse_dev_i.h
+++ b/fs/fuse/fuse_dev_i.h
@@ -11,6 +11,33 @@
#define FUSE_INT_REQ_BIT (1ULL << 0)
#define FUSE_REQ_ID_STEP (1ULL << 1)
+struct fuse_copy_state {
+ int write;
+ struct fuse_req *req;
+ struct iov_iter *iter;
+ struct pipe_buffer *pipebufs;
+ struct pipe_buffer *currbuf;
+ struct pipe_inode_info *pipe;
+ unsigned long nr_segs;
+ struct page *pg;
+ unsigned int len;
+ unsigned int offset;
+ unsigned int move_pages:1, is_uring:1;
+ struct {
+ /* pointer into the ring buffer */
+ char *buf;
+
+ /* for copy to the ring request buffer, the buffer size - must
+ * not be exceeded, for copy from the ring request buffer,
+ * the size filled in by user space
+ */
+ unsigned int buf_sz;
+
+ /* offset within buf while it is copying from/to the buf */
+ unsigned int offset;
+ } ring;
+};
+
static inline struct fuse_dev *fuse_get_dev(struct file *file)
{
/*
@@ -22,6 +49,14 @@ static inline struct fuse_dev *fuse_get_dev(struct file *file)
void fuse_dev_end_requests(struct list_head *head);
+void fuse_copy_init(struct fuse_copy_state *cs, int write,
+ struct iov_iter *iter);
+int fuse_copy_args(struct fuse_copy_state *cs, unsigned int numargs,
+ unsigned int argpages, struct fuse_arg *args,
+ int zeroing);
+int fuse_copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
+ unsigned int nbytes);
+
#endif
--
2.37.2
next prev parent reply other threads:[~2023-03-21 1:15 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-21 1:10 [RFC PATCH 00/13] fuse uring communication Bernd Schubert
2023-03-21 1:10 ` [PATCH 01/13] fuse: Add uring data structures and documentation Bernd Schubert
2023-03-21 1:10 ` [PATCH 02/13] fuse: rename to fuse_dev_end_requests and make non-static Bernd Schubert
2023-03-21 1:10 ` [PATCH 03/13] fuse: Move fuse_get_dev to header file Bernd Schubert
2023-03-21 1:10 ` [PATCH 04/13] Add a vmalloc_node_user function Bernd Schubert
2023-03-21 21:21 ` Andrew Morton
2023-03-21 1:10 ` [PATCH 05/13] fuse: Add a uring config ioctl and ring destruction Bernd Schubert
2023-03-21 1:10 ` [PATCH 06/13] fuse: Add an interval ring stop worker/monitor Bernd Schubert
2023-03-23 10:27 ` Miklos Szeredi
2023-03-23 11:04 ` Bernd Schubert
2023-03-23 12:35 ` Miklos Szeredi
2023-03-23 13:18 ` Bernd Schubert
2023-03-23 20:51 ` Bernd Schubert
2023-03-27 13:22 ` Pavel Begunkov
2023-03-27 14:02 ` Bernd Schubert
2023-03-23 13:26 ` Ming Lei
2023-03-21 1:10 ` [PATCH 07/13] fuse: Add uring mmap method Bernd Schubert
2023-03-21 1:10 ` [PATCH 08/13] fuse: Move request bits Bernd Schubert
2023-03-21 1:10 ` [PATCH 09/13] fuse: Add wait stop ioctl support to the ring Bernd Schubert
2023-03-21 1:10 ` [PATCH 10/13] fuse: Handle SQEs - register commands Bernd Schubert
2023-03-21 1:10 ` Bernd Schubert [this message]
2023-03-21 1:10 ` [PATCH 12/13] fuse: Add uring sqe commit and fetch support Bernd Schubert
2023-03-21 1:10 ` [PATCH 13/13] fuse: Allow to queue to the ring Bernd Schubert
2023-03-21 1:26 ` [RFC PATCH 00/13] fuse uring communication Bernd Schubert
2023-03-21 9:35 ` Amir Goldstein
2023-03-23 11:18 ` Bernd Schubert
2023-03-23 11:55 ` Amir Goldstein
2023-06-07 14:20 ` Miklos Szeredi
2023-06-08 21:31 ` Bernd Schubert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230321011047.3425786-12-bschubert@ddn.com \
--to=bschubert@ddn.com \
--cc=amir73il@gmail.com \
--cc=dsingh@ddn.com \
--cc=fuse-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=miklos@szeredi.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).