lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 28 Feb 2024 22:41:22 +0800
From: Hou Tao <houtao@...weicloud.com>
To: linux-fsdevel@...r.kernel.org
Cc: Miklos Szeredi <miklos@...redi.hu>,
	Vivek Goyal <vgoyal@...hat.com>,
	Stefan Hajnoczi <stefanha@...hat.com>,
	Bernd Schubert <bernd.schubert@...tmail.fm>,
	"Michael S . Tsirkin" <mst@...hat.com>,
	Matthew Wilcox <willy@...radead.org>,
	Benjamin Coddington <bcodding@...hat.com>,
	linux-kernel@...r.kernel.org,
	virtualization@...ts.linux.dev,
	houtao1@...wei.com
Subject: [PATCH v2 2/6] virtiofs: move alloc/free of argbuf into separated helpers

From: Hou Tao <houtao1@...wei.com>

The bounce buffer for fuse args in virtiofs will be extended to support
scatterd pages later. Therefore, move the allocation and the free of
argbuf out of the copy procedures and factor them into
virtio_fs_argbuf_{new|free}() helpers.

Signed-off-by: Hou Tao <houtao1@...wei.com>
---
 fs/fuse/virtio_fs.c | 52 +++++++++++++++++++++++++++------------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index 5f1be1da92ce9..cd1330506daba 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -404,6 +404,24 @@ static void virtio_fs_request_dispatch_work(struct work_struct *work)
 	}
 }
 
+static void virtio_fs_argbuf_free(void *argbuf)
+{
+	kfree(argbuf);
+}
+
+static void *virtio_fs_argbuf_new(struct fuse_args *args, gfp_t gfp)
+{
+	unsigned int numargs;
+	unsigned int len;
+
+	numargs = args->in_numargs - args->in_pages;
+	len = fuse_len_args(numargs, (struct fuse_arg *) args->in_args);
+	numargs = args->out_numargs - args->out_pages;
+	len += fuse_len_args(numargs, args->out_args);
+
+	return kmalloc(len, gfp);
+}
+
 /*
  * Returns 1 if queue is full and sender should wait a bit before sending
  * next request, 0 otherwise.
@@ -487,36 +505,24 @@ static void virtio_fs_hiprio_dispatch_work(struct work_struct *work)
 	}
 }
 
-/* Allocate and copy args into req->argbuf */
-static int copy_args_to_argbuf(struct fuse_req *req)
+/* Copy args into req->argbuf */
+static void copy_args_to_argbuf(struct fuse_req *req)
 {
 	struct fuse_args *args = req->args;
 	unsigned int offset = 0;
 	unsigned int num_in;
-	unsigned int num_out;
-	unsigned int len;
 	unsigned int i;
 
 	num_in = args->in_numargs - args->in_pages;
-	num_out = args->out_numargs - args->out_pages;
-	len = fuse_len_args(num_in, (struct fuse_arg *) args->in_args) +
-	      fuse_len_args(num_out, args->out_args);
-
-	req->argbuf = kmalloc(len, GFP_ATOMIC);
-	if (!req->argbuf)
-		return -ENOMEM;
-
 	for (i = 0; i < num_in; i++) {
 		memcpy(req->argbuf + offset,
 		       args->in_args[i].value,
 		       args->in_args[i].size);
 		offset += args->in_args[i].size;
 	}
-
-	return 0;
 }
 
-/* Copy args out of and free req->argbuf */
+/* Copy args out of req->argbuf */
 static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
 {
 	unsigned int remaining;
@@ -549,9 +555,6 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
 	/* Store the actual size of the variable-length arg */
 	if (args->out_argvar)
 		args->out_args[args->out_numargs - 1].size = remaining;
-
-	kfree(req->argbuf);
-	req->argbuf = NULL;
 }
 
 /* Work function for request completion */
@@ -571,6 +574,9 @@ static void virtio_fs_request_complete(struct fuse_req *req,
 	args = req->args;
 	copy_args_from_argbuf(args, req);
 
+	virtio_fs_argbuf_free(req->argbuf);
+	req->argbuf = NULL;
+
 	if (args->out_pages && args->page_zeroing) {
 		len = args->out_args[args->out_numargs - 1].size;
 		ap = container_of(args, typeof(*ap), args);
@@ -1149,9 +1155,13 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
 	}
 
 	/* Use a bounce buffer since stack args cannot be mapped */
-	ret = copy_args_to_argbuf(req);
-	if (ret < 0)
+	req->argbuf = virtio_fs_argbuf_new(args, GFP_ATOMIC);
+	if (!req->argbuf) {
+		ret = -ENOMEM;
 		goto out;
+	}
+
+	copy_args_to_argbuf(req);
 
 	/* Request elements */
 	sg_init_one(&sg[out_sgs++], &req->in.h, sizeof(req->in.h));
@@ -1210,7 +1220,7 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
 
 out:
 	if (ret < 0 && req->argbuf) {
-		kfree(req->argbuf);
+		virtio_fs_argbuf_free(req->argbuf);
 		req->argbuf = NULL;
 	}
 	if (sgs != stack_sgs) {
-- 
2.29.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ