linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hou Tao <houtao@huaweicloud.com>
To: linux-fsdevel@vger.kernel.org
Cc: Miklos Szeredi <miklos@szeredi.hu>,
	Vivek Goyal <vgoyal@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	Bernd Schubert <bernd.schubert@fastmail.fm>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	Matthew Wilcox <willy@infradead.org>,
	Benjamin Coddington <bcodding@redhat.com>,
	linux-kernel@vger.kernel.org, virtualization@lists.linux.dev,
	houtao1@huawei.com
Subject: [PATCH v2 3/6] virtiofs: factor out more common methods for argbuf
Date: Wed, 28 Feb 2024 22:41:23 +0800	[thread overview]
Message-ID: <20240228144126.2864064-4-houtao@huaweicloud.com> (raw)
In-Reply-To: <20240228144126.2864064-1-houtao@huaweicloud.com>

From: Hou Tao <houtao1@huawei.com>

Factor out more common methods for bounce buffer of fuse args:

1) virtio_fs_argbuf_setup_sg: set-up sgs for bounce buffer
2) virtio_fs_argbuf_copy_from_in_arg: copy each in-arg to bounce buffer
3) virtio_fs_argbuf_out_args_offset: calc the start offset of out-arg
4) virtio_fs_argbuf_copy_to_out_arg: copy bounce buffer to each out-arg

These methods will be used to implement bounce buffer backed by
scattered pages which are allocated separatedly.

Signed-off-by: Hou Tao <houtao1@huawei.com>
---
 fs/fuse/virtio_fs.c | 77 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 17 deletions(-)

diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index cd1330506daba..f10fff7f23a0f 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -86,6 +86,10 @@ struct virtio_fs_req_work {
 	struct work_struct done_work;
 };
 
+struct virtio_fs_argbuf {
+	DECLARE_FLEX_ARRAY(u8, buf);
+};
+
 static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
 				 struct fuse_req *req, bool in_flight);
 
@@ -404,13 +408,15 @@ static void virtio_fs_request_dispatch_work(struct work_struct *work)
 	}
 }
 
-static void virtio_fs_argbuf_free(void *argbuf)
+static void virtio_fs_argbuf_free(struct virtio_fs_argbuf *argbuf)
 {
 	kfree(argbuf);
 }
 
-static void *virtio_fs_argbuf_new(struct fuse_args *args, gfp_t gfp)
+static struct virtio_fs_argbuf *virtio_fs_argbuf_new(struct fuse_args *args,
+						     gfp_t gfp)
 {
+	struct virtio_fs_argbuf *argbuf;
 	unsigned int numargs;
 	unsigned int len;
 
@@ -419,7 +425,41 @@ static void *virtio_fs_argbuf_new(struct fuse_args *args, gfp_t gfp)
 	numargs = args->out_numargs - args->out_pages;
 	len += fuse_len_args(numargs, args->out_args);
 
-	return kmalloc(len, gfp);
+	argbuf = kmalloc(struct_size(argbuf, buf, len), gfp);
+
+	return argbuf;
+}
+
+static unsigned int virtio_fs_argbuf_setup_sg(struct virtio_fs_argbuf *argbuf,
+					      unsigned int offset,
+					      unsigned int len,
+					      struct scatterlist *sg)
+{
+	sg_init_one(sg, argbuf->buf + offset, len);
+	return 1;
+}
+
+static void virtio_fs_argbuf_copy_from_in_arg(struct virtio_fs_argbuf *argbuf,
+					      unsigned int offset,
+					      const void *src, unsigned int len)
+{
+	memcpy(argbuf->buf + offset, src, len);
+}
+
+static unsigned int
+virtio_fs_argbuf_out_args_offset(struct virtio_fs_argbuf *argbuf,
+				 const struct fuse_args *args)
+{
+	unsigned int num_in = args->in_numargs - args->in_pages;
+
+	return fuse_len_args(num_in, (struct fuse_arg *)args->in_args);
+}
+
+static void virtio_fs_argbuf_copy_to_out_arg(struct virtio_fs_argbuf *argbuf,
+					     unsigned int offset, void *dst,
+					     unsigned int len)
+{
+	memcpy(dst, argbuf->buf + offset, len);
 }
 
 /*
@@ -515,9 +555,9 @@ static void copy_args_to_argbuf(struct fuse_req *req)
 
 	num_in = args->in_numargs - args->in_pages;
 	for (i = 0; i < num_in; i++) {
-		memcpy(req->argbuf + offset,
-		       args->in_args[i].value,
-		       args->in_args[i].size);
+		virtio_fs_argbuf_copy_from_in_arg(req->argbuf, offset,
+						  args->in_args[i].value,
+						  args->in_args[i].size);
 		offset += args->in_args[i].size;
 	}
 }
@@ -525,17 +565,19 @@ static void copy_args_to_argbuf(struct fuse_req *req)
 /* Copy args out of req->argbuf */
 static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
 {
+	struct virtio_fs_argbuf *argbuf;
 	unsigned int remaining;
 	unsigned int offset;
-	unsigned int num_in;
 	unsigned int num_out;
 	unsigned int i;
 
 	remaining = req->out.h.len - sizeof(req->out.h);
-	num_in = args->in_numargs - args->in_pages;
 	num_out = args->out_numargs - args->out_pages;
-	offset = fuse_len_args(num_in, (struct fuse_arg *)args->in_args);
+	if (!num_out)
+		goto out;
 
+	argbuf = req->argbuf;
+	offset = virtio_fs_argbuf_out_args_offset(argbuf, args);
 	for (i = 0; i < num_out; i++) {
 		unsigned int argsize = args->out_args[i].size;
 
@@ -545,13 +587,16 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
 			argsize = remaining;
 		}
 
-		memcpy(args->out_args[i].value, req->argbuf + offset, argsize);
+		virtio_fs_argbuf_copy_to_out_arg(argbuf, offset,
+						 args->out_args[i].value,
+						 argsize);
 		offset += argsize;
 
 		if (i != args->out_numargs - 1)
 			remaining -= argsize;
 	}
 
+out:
 	/* Store the actual size of the variable-length arg */
 	if (args->out_argvar)
 		args->out_args[args->out_numargs - 1].size = remaining;
@@ -1100,7 +1145,6 @@ static unsigned int sg_init_fuse_args(struct scatterlist *sg,
 				      struct fuse_arg *args,
 				      unsigned int numargs,
 				      bool argpages,
-				      void *argbuf,
 				      unsigned int *len_used)
 {
 	struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
@@ -1109,7 +1153,8 @@ static unsigned int sg_init_fuse_args(struct scatterlist *sg,
 
 	len = fuse_len_args(numargs - argpages, args);
 	if (len)
-		sg_init_one(&sg[total_sgs++], argbuf, len);
+		total_sgs += virtio_fs_argbuf_setup_sg(req->argbuf, *len_used,
+						       len, &sg[total_sgs]);
 
 	if (argpages)
 		total_sgs += sg_init_fuse_pages(&sg[total_sgs],
@@ -1117,8 +1162,7 @@ static unsigned int sg_init_fuse_args(struct scatterlist *sg,
 						ap->num_pages,
 						args[numargs - 1].size);
 
-	if (len_used)
-		*len_used = len;
+	*len_used = len;
 
 	return total_sgs;
 }
@@ -1168,7 +1212,7 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
 	out_sgs += sg_init_fuse_args(&sg[out_sgs], req,
 				     (struct fuse_arg *)args->in_args,
 				     args->in_numargs, args->in_pages,
-				     req->argbuf, &argbuf_used);
+				     &argbuf_used);
 
 	/* Reply elements */
 	if (test_bit(FR_ISREPLY, &req->flags)) {
@@ -1176,8 +1220,7 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
 			    &req->out.h, sizeof(req->out.h));
 		in_sgs += sg_init_fuse_args(&sg[out_sgs + in_sgs], req,
 					    args->out_args, args->out_numargs,
-					    args->out_pages,
-					    req->argbuf + argbuf_used, NULL);
+					    args->out_pages, &argbuf_used);
 	}
 
 	WARN_ON(out_sgs + in_sgs != total_sgs);
-- 
2.29.2


  parent reply	other threads:[~2024-02-28 14:40 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-28 14:41 [PATCH v2 0/6] virtiofs: fix the warning for ITER_KVEC dio Hou Tao
2024-02-28 14:41 ` [PATCH v2 1/6] fuse: limit the length of ITER_KVEC dio by max_pages Hou Tao
2024-03-01 13:42   ` Miklos Szeredi
2024-03-09  4:26     ` Hou Tao
2024-03-13 23:02       ` Bernd Schubert
2024-02-28 14:41 ` [PATCH v2 2/6] virtiofs: move alloc/free of argbuf into separated helpers Hou Tao
2024-02-28 14:41 ` Hou Tao [this message]
2024-03-01 14:24   ` [PATCH v2 3/6] virtiofs: factor out more common methods for argbuf Miklos Szeredi
2024-03-09  4:27     ` Hou Tao
2024-02-28 14:41 ` [PATCH v2 4/6] virtiofs: support bounce buffer backed by scattered pages Hou Tao
2024-02-29 15:01   ` Brian Foster
2024-03-09  4:14     ` Hou Tao
2024-03-13 12:14       ` Brian Foster
2024-02-28 14:41 ` [PATCH v2 5/6] virtiofs: use scattered bounce buffer for ITER_KVEC dio Hou Tao
2024-02-28 14:41 ` [PATCH v2 6/6] virtiofs: use GFP_NOFS when enqueuing request through kworker Hou Tao
2024-04-08  7:45 ` [PATCH v2 0/6] virtiofs: fix the warning for ITER_KVEC dio Michael S. Tsirkin
2024-04-09  1:48   ` Hou Tao
2024-04-22 20:06     ` Michael S. Tsirkin
2024-04-22 21:11       ` Bernd Schubert
2024-04-23 13:25       ` Hou Tao

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=20240228144126.2864064-4-houtao@huaweicloud.com \
    --to=houtao@huaweicloud.com \
    --cc=bcodding@redhat.com \
    --cc=bernd.schubert@fastmail.fm \
    --cc=houtao1@huawei.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=mst@redhat.com \
    --cc=stefanha@redhat.com \
    --cc=vgoyal@redhat.com \
    --cc=virtualization@lists.linux.dev \
    --cc=willy@infradead.org \
    /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).