diff mbox series

[v2,2/6] virtiofs: move alloc/free of argbuf into separated helpers

Message ID 20240228144126.2864064-3-houtao@huaweicloud.com (mailing list archive)
State New
Headers show
Series virtiofs: fix the warning for ITER_KVEC dio | expand

Commit Message

Hou Tao Feb. 28, 2024, 2:41 p.m. UTC
From: Hou Tao <houtao1@huawei.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@huawei.com>
---
 fs/fuse/virtio_fs.c | 52 +++++++++++++++++++++++++++------------------
 1 file changed, 31 insertions(+), 21 deletions(-)
diff mbox series

Patch

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) {