Skip to content

Commit 7ccd86b

Browse files
bsberndMiklos Szeredi
authored andcommitted
fuse: make args->in_args[0] to be always the header
This change sets up FUSE operations to always have headers in args.in_args[0], even for opcodes without an actual header. This step prepares for a clean separation of payload from headers, initially it is used by fuse-over-io-uring. For opcodes without a header, we use a zero-sized struct as a placeholder. This approach: - Keeps things consistent across all FUSE operations - Will help with payload alignment later - Avoids future issues when header sizes change Op codes that already have an op code specific header do not need modification. Op codes that have neither payload nor op code headers are not modified either (FUSE_READLINK and FUSE_DESTROY). FUSE_BATCH_FORGET already has the header in the right place, but is not using fuse_copy_args - as -over-uring is currently not handling forgets it does not matter for now, but header separation will later need special attention for that op code. Correct the struct fuse_args->in_args array max size. Signed-off-by: Bernd Schubert <[email protected]> Reviewed-by: Joanne Koong <[email protected]> Reviewed-by: Luis Henriques <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent a7040a0 commit 7ccd86b

File tree

5 files changed

+47
-27
lines changed

5 files changed

+47
-27
lines changed

fs/fuse/dax.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,12 @@ static int fuse_send_removemapping(struct inode *inode,
240240

241241
args.opcode = FUSE_REMOVEMAPPING;
242242
args.nodeid = fi->nodeid;
243-
args.in_numargs = 2;
244-
args.in_args[0].size = sizeof(*inargp);
245-
args.in_args[0].value = inargp;
246-
args.in_args[1].size = inargp->count * sizeof(*remove_one);
247-
args.in_args[1].value = remove_one;
243+
args.in_numargs = 3;
244+
fuse_set_zero_arg0(&args);
245+
args.in_args[1].size = sizeof(*inargp);
246+
args.in_args[1].value = inargp;
247+
args.in_args[2].size = inargp->count * sizeof(*remove_one);
248+
args.in_args[2].value = remove_one;
248249
return fuse_simple_request(fm, &args);
249250
}
250251

fs/fuse/dev.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,7 +1746,7 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
17461746
args = &ap->args;
17471747
args->nodeid = outarg->nodeid;
17481748
args->opcode = FUSE_NOTIFY_REPLY;
1749-
args->in_numargs = 2;
1749+
args->in_numargs = 3;
17501750
args->in_pages = true;
17511751
args->end = fuse_retrieve_end;
17521752

@@ -1774,9 +1774,10 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
17741774
}
17751775
ra->inarg.offset = outarg->offset;
17761776
ra->inarg.size = total_len;
1777-
args->in_args[0].size = sizeof(ra->inarg);
1778-
args->in_args[0].value = &ra->inarg;
1779-
args->in_args[1].size = total_len;
1777+
fuse_set_zero_arg0(args);
1778+
args->in_args[1].size = sizeof(ra->inarg);
1779+
args->in_args[1].value = &ra->inarg;
1780+
args->in_args[2].size = total_len;
17801781

17811782
err = fuse_simple_notify_reply(fm, args, outarg->notify_unique);
17821783
if (err)

fs/fuse/dir.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,10 @@ static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
175175
memset(outarg, 0, sizeof(struct fuse_entry_out));
176176
args->opcode = FUSE_LOOKUP;
177177
args->nodeid = nodeid;
178-
args->in_numargs = 1;
179-
args->in_args[0].size = name->len + 1;
180-
args->in_args[0].value = name->name;
178+
args->in_numargs = 2;
179+
fuse_set_zero_arg0(args);
180+
args->in_args[1].size = name->len + 1;
181+
args->in_args[1].value = name->name;
181182
args->out_numargs = 1;
182183
args->out_args[0].size = sizeof(struct fuse_entry_out);
183184
args->out_args[0].value = outarg;
@@ -928,11 +929,12 @@ static int fuse_symlink(struct mnt_idmap *idmap, struct inode *dir,
928929
FUSE_ARGS(args);
929930

930931
args.opcode = FUSE_SYMLINK;
931-
args.in_numargs = 2;
932-
args.in_args[0].size = entry->d_name.len + 1;
933-
args.in_args[0].value = entry->d_name.name;
934-
args.in_args[1].size = len;
935-
args.in_args[1].value = link;
932+
args.in_numargs = 3;
933+
fuse_set_zero_arg0(&args);
934+
args.in_args[1].size = entry->d_name.len + 1;
935+
args.in_args[1].value = entry->d_name.name;
936+
args.in_args[2].size = len;
937+
args.in_args[2].value = link;
936938
return create_new_entry(idmap, fm, &args, dir, entry, S_IFLNK);
937939
}
938940

@@ -992,9 +994,10 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
992994

993995
args.opcode = FUSE_UNLINK;
994996
args.nodeid = get_node_id(dir);
995-
args.in_numargs = 1;
996-
args.in_args[0].size = entry->d_name.len + 1;
997-
args.in_args[0].value = entry->d_name.name;
997+
args.in_numargs = 2;
998+
fuse_set_zero_arg0(&args);
999+
args.in_args[1].size = entry->d_name.len + 1;
1000+
args.in_args[1].value = entry->d_name.name;
9981001
err = fuse_simple_request(fm, &args);
9991002
if (!err) {
10001003
fuse_dir_changed(dir);
@@ -1015,9 +1018,10 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
10151018

10161019
args.opcode = FUSE_RMDIR;
10171020
args.nodeid = get_node_id(dir);
1018-
args.in_numargs = 1;
1019-
args.in_args[0].size = entry->d_name.len + 1;
1020-
args.in_args[0].value = entry->d_name.name;
1021+
args.in_numargs = 2;
1022+
fuse_set_zero_arg0(&args);
1023+
args.in_args[1].size = entry->d_name.len + 1;
1024+
args.in_args[1].value = entry->d_name.name;
10211025
err = fuse_simple_request(fm, &args);
10221026
if (!err) {
10231027
fuse_dir_changed(dir);

fs/fuse/fuse_i.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ struct fuse_args {
310310
bool is_ext:1;
311311
bool is_pinned:1;
312312
bool invalidate_vmap:1;
313-
struct fuse_in_arg in_args[3];
313+
struct fuse_in_arg in_args[4];
314314
struct fuse_arg out_args[2];
315315
void (*end)(struct fuse_mount *fm, struct fuse_args *args, int error);
316316
/* Used for kvec iter backed by vmalloc address */
@@ -947,6 +947,19 @@ struct fuse_mount {
947947
struct rcu_head rcu;
948948
};
949949

950+
/*
951+
* Empty header for FUSE opcodes without specific header needs.
952+
* Used as a placeholder in args->in_args[0] for consistency
953+
* across all FUSE operations, simplifying request handling.
954+
*/
955+
struct fuse_zero_header {};
956+
957+
static inline void fuse_set_zero_arg0(struct fuse_args *args)
958+
{
959+
args->in_args[0].size = sizeof(struct fuse_zero_header);
960+
args->in_args[0].value = NULL;
961+
}
962+
950963
static inline struct fuse_mount *get_fuse_mount_super(struct super_block *sb)
951964
{
952965
return sb->s_fs_info;

fs/fuse/xattr.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ int fuse_removexattr(struct inode *inode, const char *name)
164164

165165
args.opcode = FUSE_REMOVEXATTR;
166166
args.nodeid = get_node_id(inode);
167-
args.in_numargs = 1;
168-
args.in_args[0].size = strlen(name) + 1;
169-
args.in_args[0].value = name;
167+
args.in_numargs = 2;
168+
fuse_set_zero_arg0(&args);
169+
args.in_args[1].size = strlen(name) + 1;
170+
args.in_args[1].value = name;
170171
err = fuse_simple_request(fm, &args);
171172
if (err == -ENOSYS) {
172173
fm->fc->no_removexattr = 1;

0 commit comments

Comments
 (0)