Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 May 2019 16:39:53 +0000 (UTC)
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r348365 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
Message-ID:  <201905291639.x4TGdrO0003120@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Wed May 29 16:39:52 2019
New Revision: 348365
URL: https://svnweb.freebsd.org/changeset/base/348365

Log:
  fusefs: raise protocol level to 7.12
  
  This commit raises the protocol level and adds backwards-compatibility code
  to handle structure size changes.  It doesn't implement any new features.
  The new features added in protocol 7.12 are:
  
  * server-side umask processing (which FreeBSD won't do)
  * asynchronous inode and directory entry invalidation (which I'll do next)
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/sys/fs/fuse/fuse_internal.c
  projects/fuse2/sys/fs/fuse/fuse_kernel.h
  projects/fuse2/sys/fs/fuse/fuse_vnops.c
  projects/fuse2/tests/sys/fs/fusefs/create.cc
  projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc
  projects/fuse2/tests/sys/fs/fusefs/mkdir.cc
  projects/fuse2/tests/sys/fs/fusefs/mknod.cc
  projects/fuse2/tests/sys/fs/fusefs/mockfs.cc
  projects/fuse2/tests/sys/fs/fusefs/mockfs.hh

Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_internal.c	Wed May 29 16:01:34 2019	(r348364)
+++ projects/fuse2/sys/fs/fuse/fuse_internal.c	Wed May 29 16:39:52 2019	(r348365)
@@ -331,12 +331,22 @@ int
 fuse_internal_mknod(struct vnode *dvp, struct vnode **vpp,
 	struct componentname *cnp, struct vattr *vap)
 {
+	struct fuse_data *data;
 	struct fuse_mknod_in fmni;
+	size_t insize;
 
+	data = fuse_get_mpdata(dvp->v_mount);
+
 	fmni.mode = MAKEIMODE(vap->va_type, vap->va_mode);
 	fmni.rdev = vap->va_rdev;
+	if (fuse_libabi_geq(data, 7, 12)) {
+		insize = sizeof(fmni);
+		fmni.umask = curthread->td_proc->p_fd->fd_cmask;
+	} else {
+		insize = FUSE_COMPAT_MKNOD_IN_SIZE;
+	}
 	return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKNOD, &fmni,
-	    sizeof(fmni), vap->va_type));
+	    insize, vap->va_type));
 }
 
 /* readdir */
@@ -824,6 +834,8 @@ fuse_internal_send_init(struct fuse_data *data, struct
 	 * Unsupported features:
 	 * FUSE_FILE_OPS: No known FUSE server or client supports it
 	 * FUSE_ATOMIC_O_TRUNC: our VFS cannot support it
+	 * FUSE_DONT_MASK: unlike Linux, FreeBSD always applies the umask, even
+	 *	when default ACLs are in use.
 	 */
 	fiii->flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_EXPORT_SUPPORT
 		| FUSE_BIG_WRITES;

Modified: projects/fuse2/sys/fs/fuse/fuse_kernel.h
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_kernel.h	Wed May 29 16:01:34 2019	(r348364)
+++ projects/fuse2/sys/fs/fuse/fuse_kernel.h	Wed May 29 16:39:52 2019	(r348365)
@@ -52,6 +52,11 @@
  *  7.11
  *  - add IOCTL message
  *  - add unsolicited notification support
+ *
+ *  7.12
+ *  - add umask flag to input argument of open, mknod and mkdir
+ *  - add notification messages for invalidation of inodes and
+ *    directory entries
  */
 
 #ifndef _FUSE_FUSE_KERNEL_H
@@ -60,6 +65,7 @@
 #ifndef linux
 #include <sys/types.h>
 #define __u64 uint64_t
+#define __s64 int64_t
 #define __u32 uint32_t
 #define __s32 int32_t
 #else
@@ -70,7 +76,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 11
+#define FUSE_KERNEL_MINOR_VERSION 12
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -146,6 +152,7 @@ struct fuse_file_lock {
  * INIT request/reply flags
  *
  * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
+ * FUSE_DONT_MASK: don't apply umask to file mode on create operations
  */
 #define FUSE_ASYNC_READ		(1 << 0)
 #define FUSE_POSIX_LOCKS	(1 << 1)
@@ -153,6 +160,7 @@ struct fuse_file_lock {
 #define FUSE_ATOMIC_O_TRUNC	(1 << 3)
 #define FUSE_EXPORT_SUPPORT	(1 << 4)
 #define FUSE_BIG_WRITES		(1 << 5)
+#define FUSE_DONT_MASK		(1 << 6)
 
 #ifdef linux
 /**
@@ -262,6 +270,8 @@ enum fuse_opcode {
 
 enum fuse_notify_code {
 	FUSE_NOTIFY_POLL   = 1,
+	FUSE_NOTIFY_INVAL_INODE = 2,
+	FUSE_NOTIFY_INVAL_ENTRY = 3,
 	FUSE_NOTIFY_CODE_MAX,
 };
 
@@ -300,14 +310,18 @@ struct fuse_attr_out {
 	struct fuse_attr attr;
 };
 
+#define FUSE_COMPAT_MKNOD_IN_SIZE 8
+
 struct fuse_mknod_in {
 	__u32	mode;
 	__u32	rdev;
+	__u32	umask;
+	__u32	padding;
 };
 
 struct fuse_mkdir_in {
 	__u32	mode;
-	__u32	padding;
+	__u32	umask;
 };
 
 struct fuse_rename_in {
@@ -339,7 +353,14 @@ struct fuse_setattr_in {
 
 struct fuse_open_in {
 	__u32	flags;
+	__u32	unused;
+};
+
+struct fuse_create_in {
+	__u32	flags;
 	__u32	mode;
+	__u32	umask;
+	__u32	padding;
 };
 
 struct fuse_open_out {
@@ -557,5 +578,17 @@ struct fuse_dirent {
 #define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
 #define FUSE_DIRENT_SIZE(d) \
 	FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
+
+struct fuse_notify_inval_inode_out {
+	__u64	ino;
+	__s64	off;
+	__s64	len;
+};
+
+struct fuse_notify_inval_entry_out {
+	__u64	parent;
+	__u32	namelen;
+	__u32	padding;
+};
 
 #endif /* _FUSE_FUSE_KERNEL_H */

Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_vnops.c	Wed May 29 16:01:34 2019	(r348364)
+++ projects/fuse2/sys/fs/fuse/fuse_vnops.c	Wed May 29 16:39:52 2019	(r348365)
@@ -540,7 +540,8 @@ fuse_vnop_create(struct vop_create_args *ap)
 	struct thread *td = cnp->cn_thread;
 	struct ucred *cred = cnp->cn_cred;
 
-	struct fuse_open_in *foi;
+	struct fuse_data *data;
+	struct fuse_create_in *fci;
 	struct fuse_entry_out *feo;
 	struct fuse_open_out *foo;
 	struct fuse_dispatcher fdi, fdi2;
@@ -550,6 +551,7 @@ fuse_vnop_create(struct vop_create_args *ap)
 	int err;
 
 	struct mount *mp = vnode_mount(dvp);
+	data = fuse_get_mpdata(mp);
 	uint64_t parentnid = VTOFUD(dvp)->nid;
 	mode_t mode = MAKEIMODE(vap->va_type, vap->va_mode);
 	enum fuse_opcode op;
@@ -580,15 +582,24 @@ fuse_vnop_create(struct vop_create_args *ap)
 			cred, mode, &op);
 	} else {
 		/* Use FUSE_CREATE */
+		size_t insize;
+
 		op = FUSE_CREATE;
-		fdisp_init(fdip, sizeof(*foi) + cnp->cn_namelen + 1);
+		fdisp_init(fdip, sizeof(*fci) + cnp->cn_namelen + 1);
 		fdisp_make(fdip, op, vnode_mount(dvp), parentnid, td, cred);
-		foi = fdip->indata;
-		foi->mode = mode;
-		foi->flags = O_CREAT | flags;
-		memcpy((char *)fdip->indata + sizeof(*foi), cnp->cn_nameptr,
+		fci = fdip->indata;
+		fci->mode = mode;
+		fci->flags = O_CREAT | flags;
+		if (fuse_libabi_geq(data, 7, 12)) {
+			insize = sizeof(*fci);
+			fci->umask = td->td_proc->p_fd->fd_cmask;
+		} else {
+			insize = sizeof(struct fuse_open_in);
+		}
+
+		memcpy((char *)fdip->indata + insize, cnp->cn_nameptr,
 		    cnp->cn_namelen);
-		((char *)fdip->indata)[sizeof(*foi) + cnp->cn_namelen] = '\0';
+		((char *)fdip->indata)[insize + cnp->cn_namelen] = '\0';
 	}
 
 	err = fdisp_wait_answ(fdip);
@@ -614,12 +625,13 @@ fuse_vnop_create(struct vop_create_args *ap)
 		foo = (struct fuse_open_out*)(feo + 1);
 	} else {
 		/* Issue a separate FUSE_OPEN */
+		struct fuse_open_in *foi;
+
 		fdip2 = &fdi2;
 		fdisp_init(fdip2, sizeof(*foi));
 		fdisp_make(fdip2, FUSE_OPEN, vnode_mount(dvp), feo->nodeid, td,
 			cred);
 		foi = fdip2->indata;
-		foi->mode = mode;
 		foi->flags = flags;
 		err = fdisp_wait_answ(fdip2);
 		if (err)
@@ -1162,6 +1174,7 @@ fuse_vnop_mkdir(struct vop_mkdir_args *ap)
 		return ENXIO;
 	}
 	fmdi.mode = MAKEIMODE(vap->va_type, vap->va_mode);
+	fmdi.umask = curthread->td_proc->p_fd->fd_cmask;
 
 	return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKDIR, &fmdi,
 	    sizeof(fmdi), VDIR));

Modified: projects/fuse2/tests/sys/fs/fusefs/create.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/create.cc	Wed May 29 16:01:34 2019	(r348364)
+++ projects/fuse2/tests/sys/fs/fusefs/create.cc	Wed May 29 16:39:52 2019	(r348365)
@@ -42,12 +42,16 @@ class Create: public FuseTest { (public)
 
 void expect_create(const char *relpath, mode_t mode, ProcessMockerT r)
 {
+	mode_t mask = umask(0);
+	(void)umask(mask);
+
 	EXPECT_CALL(*m_mock, process(
 		ResultOf([=](auto in) {
 			const char *name = (const char*)in.body.bytes +
-				sizeof(fuse_open_in);
+				sizeof(fuse_create_in);
 			return (in.header.opcode == FUSE_CREATE &&
-				in.body.open.mode == mode &&
+				in.body.create.mode == mode &&
+				in.body.create.umask == mask &&
 				(0 == strcmp(relpath, name)));
 		}, Eq(true)),
 		_)
@@ -63,9 +67,48 @@ virtual void SetUp() {
 	m_kernel_minor_version = 8;
 	Create::SetUp();
 }
+
+void expect_create(const char *relpath, mode_t mode, ProcessMockerT r)
+{
+	EXPECT_CALL(*m_mock, process(
+		ResultOf([=](auto in) {
+			const char *name = (const char*)in.body.bytes +
+				sizeof(fuse_open_in);
+			return (in.header.opcode == FUSE_CREATE &&
+				in.body.create.mode == mode &&
+				(0 == strcmp(relpath, name)));
+		}, Eq(true)),
+		_)
+	).WillOnce(Invoke(r));
+}
+
 };
 
+/* FUSE_CREATE operations for a server built at protocol <= 7.11 */
+class Create_7_11: public FuseTest {
+public:
+virtual void SetUp() {
+	m_kernel_minor_version = 11;
+	FuseTest::SetUp();
+}
 
+void expect_create(const char *relpath, mode_t mode, ProcessMockerT r)
+{
+	EXPECT_CALL(*m_mock, process(
+		ResultOf([=](auto in) {
+			const char *name = (const char*)in.body.bytes +
+				sizeof(fuse_open_in);
+			return (in.header.opcode == FUSE_CREATE &&
+				in.body.create.mode == mode &&
+				(0 == strcmp(relpath, name)));
+		}, Eq(true)),
+		_)
+	).WillOnce(Invoke(r));
+}
+
+};
+
+
 /*
  * If FUSE_CREATE sets attr_valid, then subsequent GETATTRs should use the
  * attribute cache
@@ -372,4 +415,25 @@ TEST_F(Create_7_8, ok)
 	/* Deliberately leak fd.  close(2) will be tested in release.cc */
 }
 
+TEST_F(Create_7_11, ok)
+{
+	const char FULLPATH[] = "mountpoint/some_file.txt";
+	const char RELPATH[] = "some_file.txt";
+	mode_t mode = S_IFREG | 0755;
+	uint64_t ino = 42;
+	int fd;
 
+	EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT)));
+	expect_create(RELPATH, mode,
+		ReturnImmediate([=](auto in __unused, auto& out) {
+		SET_OUT_HEADER_LEN(out, create);
+		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;
+	}));
+
+	fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
+	EXPECT_LE(0, fd) << strerror(errno);
+	/* Deliberately leak fd.  close(2) will be tested in release.cc */
+}

Modified: projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc	Wed May 29 16:01:34 2019	(r348364)
+++ projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc	Wed May 29 16:39:52 2019	(r348365)
@@ -92,7 +92,7 @@ void expect_create(const char *relpath, uint64_t ino)
 	EXPECT_CALL(*m_mock, process(
 		ResultOf([=](auto in) {
 			const char *name = (const char*)in.body.bytes +
-				sizeof(fuse_open_in);
+				sizeof(fuse_create_in);
 			return (in.header.opcode == FUSE_CREATE &&
 				(0 == strcmp(relpath, name)));
 		}, Eq(true)),

Modified: projects/fuse2/tests/sys/fs/fusefs/mkdir.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/mkdir.cc	Wed May 29 16:01:34 2019	(r348364)
+++ projects/fuse2/tests/sys/fs/fusefs/mkdir.cc	Wed May 29 16:39:52 2019	(r348365)
@@ -159,7 +159,11 @@ TEST_F(Mkdir, ok)
 	const char RELPATH[] = "some_dir";
 	mode_t mode = 0755;
 	uint64_t ino = 42;
+	mode_t mask;
 
+	mask = umask(0);
+	(void)umask(mask);
+
 	EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT)));
 
 	EXPECT_CALL(*m_mock, process(
@@ -168,6 +172,7 @@ TEST_F(Mkdir, ok)
 				sizeof(fuse_mkdir_in);
 			return (in.header.opcode == FUSE_MKDIR &&
 				in.body.mkdir.mode == (S_IFDIR | mode) &&
+				in.body.mkdir.umask == mask &&
 				(0 == strcmp(RELPATH, name)));
 		}, Eq(true)),
 		_)

Modified: projects/fuse2/tests/sys/fs/fusefs/mknod.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/mknod.cc	Wed May 29 16:01:34 2019	(r348364)
+++ projects/fuse2/tests/sys/fs/fusefs/mknod.cc	Wed May 29 16:39:52 2019	(r348365)
@@ -48,16 +48,69 @@ const char RELPATH[] = "some_file.txt";
 
 class Mknod: public FuseTest {
 
+mode_t m_oldmask;
+const static mode_t c_umask = 022;
+
 public:
 
 virtual void SetUp() {
+	m_oldmask = umask(c_umask);
+	printf("m_oldmask=%#o\n", m_oldmask);
+	if (geteuid() != 0) {
+		GTEST_SKIP() << "Only root may use most mknod(2) variations";
+	}
 	FuseTest::SetUp();
+}
 
+virtual void TearDown() {
+	FuseTest::TearDown();
+	(void)umask(m_oldmask);
+}
+
+/* Test an OK creation of a file with the given mode and device number */
+void expect_mknod(mode_t mode, dev_t dev) {
+	uint64_t ino = 42;
+
+	EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT)));
+
+	EXPECT_CALL(*m_mock, process(
+		ResultOf([=](auto in) {
+			const char *name = (const char*)in.body.bytes +
+				sizeof(fuse_mknod_in);
+			return (in.header.opcode == FUSE_MKNOD &&
+				in.body.mknod.mode == mode &&
+				in.body.mknod.rdev == (uint32_t)dev &&
+				in.body.mknod.umask == c_umask &&
+				(0 == strcmp(RELPATH, name)));
+		}, Eq(true)),
+		_)
+	).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) {
+		SET_OUT_HEADER_LEN(out, entry);
+		out.body.entry.attr.mode = mode;
+		out.body.entry.nodeid = ino;
+		out.body.entry.entry_valid = UINT64_MAX;
+		out.body.entry.attr_valid = UINT64_MAX;
+		out.body.entry.attr.rdev = dev;
+	})));
+}
+
+};
+
+class Mknod_7_11: public FuseTest {
+public:
+virtual void SetUp() {
+	m_kernel_minor_version = 11;
 	if (geteuid() != 0) {
 		GTEST_SKIP() << "Only root may use most mknod(2) variations";
 	}
+	FuseTest::SetUp();
 }
 
+void expect_lookup(const char *relpath, uint64_t ino, uint64_t size)
+{
+	FuseTest::expect_lookup_7_8(relpath, ino, S_IFREG | 0644, size, 1);
+}
+
 /* Test an OK creation of a file with the given mode and device number */
 void expect_mknod(mode_t mode, dev_t dev) {
 	uint64_t ino = 42;
@@ -67,7 +120,7 @@ void expect_mknod(mode_t mode, dev_t dev) {
 	EXPECT_CALL(*m_mock, process(
 		ResultOf([=](auto in) {
 			const char *name = (const char*)in.body.bytes +
-				sizeof(fuse_mknod_in);
+				FUSE_COMPAT_MKNOD_IN_SIZE;
 			return (in.header.opcode == FUSE_MKNOD &&
 				in.body.mknod.mode == mode &&
 				in.body.mknod.rdev == (uint32_t)dev &&
@@ -171,4 +224,13 @@ TEST_F(Mknod, DISABLED_whiteout)
 	dev_t rdev = VNOVAL;	/* whiteouts don't have device numbers */
 	expect_mknod(mode, rdev);
 	EXPECT_EQ(0, mknod(FULLPATH, mode, 0)) << strerror(errno);
+}
+
+/* A server built at protocol version 7.11 or earlier can still use mknod */
+TEST_F(Mknod_7_11, fifo)
+{
+	mode_t mode = S_IFIFO | 0755;
+	dev_t rdev = VNOVAL;
+	expect_mknod(mode, rdev);
+	EXPECT_EQ(0, mkfifo(FULLPATH, mode)) << strerror(errno);
 }

Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc	Wed May 29 16:01:34 2019	(r348364)
+++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc	Wed May 29 16:39:52 2019	(r348365)
@@ -153,7 +153,7 @@ void sigint_handler(int __unused sig) {
 	// Don't do anything except interrupt the daemon's read(2) call
 }
 
-void debug_fuseop(const mockfs_buf_in &in)
+void MockFS::debug_fuseop(const mockfs_buf_in &in)
 {
 	printf("%-11s ino=%2" PRIu64, opcode2opname(in.header.opcode),
 		in.header.nodeid);
@@ -169,8 +169,12 @@ void debug_fuseop(const mockfs_buf_in &in)
 			printf(" mask=%#x", in.body.access.mask);
 			break;
 		case FUSE_CREATE:
-			name = (const char*)in.body.bytes +
-				sizeof(fuse_open_in);
+			if (m_kernel_minor_version >= 12)
+				name = (const char*)in.body.bytes +
+					sizeof(fuse_create_in);
+			else
+				name = (const char*)in.body.bytes +
+					sizeof(fuse_open_in);
 			printf(" flags=%#x name=%s",
 				in.body.open.flags, name);
 			break;
@@ -200,19 +204,25 @@ void debug_fuseop(const mockfs_buf_in &in)
 		case FUSE_MKDIR:
 			name = (const char*)in.body.bytes +
 				sizeof(fuse_mkdir_in);
-			printf(" name=%s mode=%#o", name, in.body.mkdir.mode);
+			printf(" name=%s mode=%#o umask=%#o", name,
+				in.body.mkdir.mode, in.body.mkdir.umask);
 			break;
 		case FUSE_MKNOD:
-			printf(" mode=%#o rdev=%x", in.body.mknod.mode,
-				in.body.mknod.rdev);
+			if (m_kernel_minor_version >= 12)
+				name = (const char*)in.body.bytes +
+					sizeof(fuse_mknod_in);
+			else
+				name = (const char*)in.body.bytes +
+					FUSE_COMPAT_MKNOD_IN_SIZE;
+			printf(" mode=%#o rdev=%x umask=%#o name=%s",
+				in.body.mknod.mode, in.body.mknod.rdev,
+				in.body.mknod.umask, name);
 			break;
 		case FUSE_OPEN:
-			printf(" flags=%#x mode=%#o",
-				in.body.open.flags, in.body.open.mode);
+			printf(" flags=%#x", in.body.open.flags);
 			break;
 		case FUSE_OPENDIR:
-			printf(" flags=%#x mode=%#o",
-				in.body.opendir.flags, in.body.opendir.mode);
+			printf(" flags=%#x", in.body.opendir.flags);
 			break;
 		case FUSE_READ:
 			printf(" offset=%" PRIu64 " size=%u",

Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.hh
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/mockfs.hh	Wed May 29 16:01:34 2019	(r348364)
+++ projects/fuse2/tests/sys/fs/fusefs/mockfs.hh	Wed May 29 16:39:52 2019	(r348365)
@@ -126,6 +126,7 @@ union fuse_payloads_in {
 	fuse_access_in	access;
 	/* value is from fuse_kern_chan.c in fusefs-libs */
 	uint8_t		bytes[0x21000 - sizeof(struct fuse_in_header)];
+	fuse_create_in	create;
 	fuse_flush_in	flush;
 	fuse_fsync_in	fsync;
 	fuse_fsync_in	fsyncdir;
@@ -256,6 +257,8 @@ class MockFS {
 
 	/* Method the daemon should use for I/O to and from /dev/fuse */
 	enum poll_method m_pm;
+
+	void debug_fuseop(const mockfs_buf_in&);
 
 	/* Initialize a session after mounting */
 	void init(uint32_t flags);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905291639.x4TGdrO0003120>