diff options
author | Alan Somers <asomers@FreeBSD.org> | 2022-04-28 21:13:09 +0000 |
---|---|---|
committer | Alan Somers <asomers@FreeBSD.org> | 2022-04-28 21:13:09 +0000 |
commit | 45825a12f9851213e627cf41398706bacb793f83 (patch) | |
tree | b3f4b8424899a6a6d1a69585bf887dc51c8619d3 | |
parent | 1a50bf77af90e0ee7a80f268b2c0bf2a44e38ef2 (diff) |
fusefs: fix FUSE_CREATE with file handles and fuse protocol < 7.9
Prior to fuse protocol version 7.9, the fuse_entry_out structure had a
smaller size. But fuse_vnop_create did not take that into account when
working with servers that use older protocols. The bug does not matter
for servers which don't use file handles or open flags (the only fields
affected).
PR: 263625
Submitted by: Ali Abdallah <ali.abdallah@suse.com>
MFC after: 2 weeks
-rw-r--r-- | sys/fs/fuse/fuse_vnops.c | 6 | ||||
-rw-r--r-- | tests/sys/fs/fusefs/create.cc | 13 |
2 files changed, 13 insertions, 6 deletions
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c index 4374c854a5be..9ffc8f32c048 100644 --- a/sys/fs/fuse/fuse_vnops.c +++ b/sys/fs/fuse/fuse_vnops.c @@ -1042,7 +1042,11 @@ fuse_vnop_create(struct vop_create_args *ap) } if (op == FUSE_CREATE) { - foo = (struct fuse_open_out*)(feo + 1); + if (fuse_libabi_geq(data, 7, 9)) + foo = (struct fuse_open_out*)(feo + 1); + else + foo = (struct fuse_open_out*)((char*)feo + + FUSE_COMPAT_ENTRY_OUT_SIZE); } else { /* Issue a separate FUSE_OPEN */ struct fuse_open_in *foi; diff --git a/tests/sys/fs/fusefs/create.cc b/tests/sys/fs/fusefs/create.cc index 0797a3ff9e34..df3225ed1837 100644 --- a/tests/sys/fs/fusefs/create.cc +++ b/tests/sys/fs/fusefs/create.cc @@ -415,15 +415,18 @@ TEST_F(Create_7_8, ok) expect_create(RELPATH, mode, ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create_7_8); - out.body.create.entry.attr.mode = mode; - out.body.create.entry.nodeid = ino; - out.body.create.entry.entry_valid = UINT64_MAX; - out.body.create.entry.attr_valid = UINT64_MAX; + out.body.create_7_8.entry.attr.mode = mode; + out.body.create_7_8.entry.nodeid = ino; + out.body.create_7_8.entry.entry_valid = UINT64_MAX; + out.body.create_7_8.entry.attr_valid = UINT64_MAX; + out.body.create_7_8.open.fh = FH; })); + expect_flush(ino, 1, ReturnErrno(0)); + expect_release(ino, FH); fd = open(FULLPATH, O_CREAT | O_EXCL, mode); ASSERT_LE(0, fd) << strerror(errno); - leak(fd); + close(fd); } TEST_F(Create_7_11, ok) |