git: c7b4932df66d - stable/13 - fusefs: fix FUSE_CREATE with file handles and fuse protocol < 7.9

From: Alan Somers <asomers_at_FreeBSD.org>
Date: Thu, 12 May 2022 20:44:08 UTC
The branch stable/13 has been updated by asomers:

URL: https://cgit.FreeBSD.org/src/commit/?id=c7b4932df66d8a5cd299898a2c477ba7d7248654

commit c7b4932df66d8a5cd299898a2c477ba7d7248654
Author:     Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2022-04-28 21:13:09 +0000
Commit:     Alan Somers <asomers@FreeBSD.org>
CommitDate: 2022-05-12 20:43:22 +0000

    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>
    
    (cherry picked from commit 45825a12f9851213e627cf41398706bacb793f83)
---
 sys/fs/fuse/fuse_vnops.c      |  6 +++++-
 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 e34cebe15772..d59d4e8de3aa 100644
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -1043,7 +1043,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)