public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: Luis Henriques <luis@igalia.com>
To: Miklos Szeredi <miklos@szeredi.hu>,
	Amir Goldstein <amir73il@gmail.com>,
	Bernd Schubert <bschubert@ddn.com>,
	Bernd Schubert <bernd@bsbernd.com>,
	"Darrick J. Wong" <djwong@kernel.org>,
	Horst Birthelmer <hbirthelmer@ddn.com>,
	Joanne Koong <joannelkoong@gmail.com>, Kevin Chen <kchen@ddn.com>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	Matt Harvey <mharvey@jumptrading.com>,
	kernel-dev@igalia.com, Luis Henriques <luis@igalia.com>
Subject: [RFC PATCH v3 3/8] fuse: store index of the variable length argument
Date: Wed, 25 Feb 2026 11:24:34 +0000	[thread overview]
Message-ID: <20260225112439.27276-4-luis@igalia.com> (raw)
In-Reply-To: <20260225112439.27276-1-luis@igalia.com>

Operations that have a variable length argument assume that it will always
be the last argument on the list.  This patch allows this assumption to be
removed by keeping track of the index of variable length argument.

Signed-off-by: Luis Henriques <luis@igalia.com>
---
 fs/fuse/compound.c  | 1 +
 fs/fuse/cuse.c      | 1 +
 fs/fuse/dev.c       | 4 ++--
 fs/fuse/dir.c       | 1 +
 fs/fuse/file.c      | 1 +
 fs/fuse/fuse_i.h    | 2 ++
 fs/fuse/inode.c     | 1 +
 fs/fuse/ioctl.c     | 1 +
 fs/fuse/virtio_fs.c | 6 +++---
 fs/fuse/xattr.c     | 2 ++
 10 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/fs/fuse/compound.c b/fs/fuse/compound.c
index 1a85209f4e99..2dc024301aad 100644
--- a/fs/fuse/compound.c
+++ b/fs/fuse/compound.c
@@ -153,6 +153,7 @@ ssize_t fuse_compound_send(struct fuse_compound_req *compound)
 		.in_numargs = 2,
 		.out_numargs = 2,
 		.out_argvar = true,
+		.out_argvar_idx = 1,
 	};
 	unsigned int req_count = compound->compound_header.count;
 	size_t total_expected_out_size = 0;
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index dfcb98a654d8..3ce8ee9a4275 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -460,6 +460,7 @@ static int cuse_send_init(struct cuse_conn *cc)
 	ap->args.out_args[0].value = &ia->out;
 	ap->args.out_args[1].size = CUSE_INIT_INFO_MAX;
 	ap->args.out_argvar = true;
+	ap->args.out_argvar_idx = 1;
 	ap->args.out_pages = true;
 	ap->num_folios = 1;
 	ap->folios = &ia->folio;
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 0b0241f47170..5b02724f4377 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -694,7 +694,7 @@ ssize_t __fuse_simple_request(struct mnt_idmap *idmap,
 	ret = req->out.h.error;
 	if (!ret && args->out_argvar) {
 		BUG_ON(args->out_numargs == 0);
-		ret = args->out_args[args->out_numargs - 1].size;
+		ret = args->out_args[args->out_argvar_idx].size;
 	}
 	fuse_put_request(req);
 
@@ -2157,7 +2157,7 @@ int fuse_copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
 	if (reqsize < nbytes || (reqsize > nbytes && !args->out_argvar))
 		return -EINVAL;
 	else if (reqsize > nbytes) {
-		struct fuse_arg *lastarg = &args->out_args[args->out_numargs-1];
+		struct fuse_arg *lastarg = &args->out_args[args->out_argvar_idx];
 		unsigned diffsize = reqsize - nbytes;
 
 		if (diffsize > lastarg->size)
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index f5eacea44896..a1121feb63ee 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1835,6 +1835,7 @@ static int fuse_readlink_folio(struct inode *inode, struct folio *folio)
 	ap.args.nodeid = get_node_id(inode);
 	ap.args.out_pages = true;
 	ap.args.out_argvar = true;
+	ap.args.out_argvar_idx = 0;
 	ap.args.page_zeroing = true;
 	ap.args.out_numargs = 1;
 	ap.args.out_args[0].size = desc.length;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 49c21498230d..1045d74dd95f 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -682,6 +682,7 @@ void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos,
 	args->in_args[0].size = sizeof(ia->read.in);
 	args->in_args[0].value = &ia->read.in;
 	args->out_argvar = true;
+	args->out_argvar_idx = 0;
 	args->out_numargs = 1;
 	args->out_args[0].size = count;
 }
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 135027efec7a..04f09e2ccfd0 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -331,6 +331,8 @@ struct fuse_args {
 	uint32_t opcode;
 	uint8_t in_numargs;
 	uint8_t out_numargs;
+	/* The index of the variable length out arg */
+	uint8_t out_argvar_idx;
 	uint8_t ext_idx;
 	bool force:1;
 	bool noreply:1;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 8231c207abea..006436a3ad06 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1540,6 +1540,7 @@ static struct fuse_init_args *fuse_new_init(struct fuse_mount *fm)
 	   with interface version < 7.5.  Rest of init_out is zeroed
 	   by do_get_request(), so a short reply is not a problem */
 	ia->args.out_argvar = true;
+	ia->args.out_argvar_idx = 0;
 	ia->args.out_args[0].size = sizeof(ia->out);
 	ia->args.out_args[0].value = &ia->out;
 	ia->args.force = true;
diff --git a/fs/fuse/ioctl.c b/fs/fuse/ioctl.c
index 07a02e47b2c3..7eb8d7a59edc 100644
--- a/fs/fuse/ioctl.c
+++ b/fs/fuse/ioctl.c
@@ -337,6 +337,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
 	ap.args.out_args[1].size = out_size;
 	ap.args.out_pages = true;
 	ap.args.out_argvar = true;
+	ap.args.out_argvar_idx = 1;
 
 	transferred = fuse_send_ioctl(fm, &ap.args, &outarg);
 	err = transferred;
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index 057e65b51b99..dd681bc672b8 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -738,7 +738,7 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
 		unsigned int argsize = args->out_args[i].size;
 
 		if (args->out_argvar &&
-		    i == args->out_numargs - 1 &&
+		    i == args->out_argvar_idx &&
 		    argsize > remaining) {
 			argsize = remaining;
 		}
@@ -746,13 +746,13 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
 		memcpy(args->out_args[i].value, req->argbuf + offset, argsize);
 		offset += argsize;
 
-		if (i != args->out_numargs - 1)
+		if (i != args->out_argvar_idx)
 			remaining -= argsize;
 	}
 
 	/* Store the actual size of the variable-length arg */
 	if (args->out_argvar)
-		args->out_args[args->out_numargs - 1].size = remaining;
+		args->out_args[args->out_argvar_idx].size = remaining;
 
 	kfree(req->argbuf);
 	req->argbuf = NULL;
diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c
index 93dfb06b6cea..f123446fe537 100644
--- a/fs/fuse/xattr.c
+++ b/fs/fuse/xattr.c
@@ -73,6 +73,7 @@ ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value,
 	args.out_numargs = 1;
 	if (size) {
 		args.out_argvar = true;
+		args.out_argvar_idx = 0;
 		args.out_args[0].size = size;
 		args.out_args[0].value = value;
 	} else {
@@ -135,6 +136,7 @@ ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
 	args.out_numargs = 1;
 	if (size) {
 		args.out_argvar = true;
+		args.out_argvar_idx = 0;
 		args.out_args[0].size = size;
 		args.out_args[0].value = list;
 	} else {

  parent reply	other threads:[~2026-02-25 11:25 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-25 11:24 [RFC PATCH v3 0/8] fuse: LOOKUP_HANDLE operation Luis Henriques
2026-02-25 11:24 ` [RFC PATCH v3 1/8] fuse: simplify fuse_lookup_name() interface Luis Henriques
2026-02-27 15:46   ` Miklos Szeredi
2026-02-28 14:42     ` Luis Henriques
2026-02-25 11:24 ` [RFC PATCH v3 2/8] fuse: export extend_arg() and factor out fuse_ext_size() Luis Henriques
2026-02-25 11:24 ` Luis Henriques [this message]
2026-02-27 15:41   ` [RFC PATCH v3 3/8] fuse: store index of the variable length argument Miklos Szeredi
2026-02-28 14:50     ` Luis Henriques
2026-02-25 11:24 ` [RFC PATCH v3 4/8] fuse: drop unnecessary argument from fuse_lookup_init() Luis Henriques
2026-02-27 15:57   ` Miklos Szeredi
2026-02-25 11:24 ` [RFC PATCH v3 5/8] fuse: extract helper functions from fuse_do_statx() Luis Henriques
2026-02-25 11:24 ` [RFC PATCH v3 6/8] fuse: implementation of lookup_handle+statx compound operation Luis Henriques
2026-02-25 18:06   ` Amir Goldstein
2026-02-26  9:54     ` Luis Henriques
2026-02-26 10:08       ` Amir Goldstein
2026-02-26 10:29         ` Miklos Szeredi
2026-02-26 15:06           ` Luis Henriques
2026-02-26 15:44             ` Miklos Szeredi
2026-02-26 16:17               ` Luis Henriques
2026-02-26 10:33         ` Luis Henriques
2026-02-25 11:24 ` [RFC PATCH v3 7/8] fuse: export fuse_open_args_fill() helper function Luis Henriques
2026-02-25 11:24 ` [RFC PATCH v3 8/8] fuse: implementation of mkobj_handle+statx+open compound operation Luis Henriques
2026-02-25 15:08   ` Horst Birthelmer
2026-02-25 17:26     ` Luis Henriques
2026-02-25 15:14 ` [RFC PATCH v3 0/8] fuse: LOOKUP_HANDLE operation Horst Birthelmer
2026-02-25 17:06   ` Luis Henriques

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=20260225112439.27276-4-luis@igalia.com \
    --to=luis@igalia.com \
    --cc=amir73il@gmail.com \
    --cc=bernd@bsbernd.com \
    --cc=bschubert@ddn.com \
    --cc=djwong@kernel.org \
    --cc=hbirthelmer@ddn.com \
    --cc=joannelkoong@gmail.com \
    --cc=kchen@ddn.com \
    --cc=kernel-dev@igalia.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mharvey@jumptrading.com \
    --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