Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Sep 2019 14:06:45 -0000
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r346141 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
Message-ID:  <201904120015.x3C0FaAv028295@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Fri Apr 12 00:15:36 2019
New Revision: 346141
URL: https://svnweb.freebsd.org/changeset/base/346141

Log:
  fusefs: Handle ENOSYS for all remaining opcodes
  
  For many FUSE opcodes, an error of ENOSYS has special meaning.  fusefs
  already handled some of those; this commit adds handling for the remainder:
  
  * FUSE_FSYNC, FUSE_FSYNCDIR: ENOSYS means "success, and automatically return
    success without calling the daemon from now on"
  * All extattr operations: ENOSYS means "fail EOPNOTSUPP, and automatically
    do it without calling the daemon from now on"
  
  PR:		236557
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/sys/fs/fuse/fuse_internal.c
  projects/fuse2/sys/fs/fuse/fuse_vnops.c
  projects/fuse2/tests/sys/fs/fusefs/fsync.cc
  projects/fuse2/tests/sys/fs/fusefs/fsyncdir.cc
  projects/fuse2/tests/sys/fs/fusefs/xattr.cc

Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_internal.c	Thu Apr 11 23:15:37 2019	(r346140)
+++ projects/fuse2/sys/fs/fuse/fuse_internal.c	Fri Apr 12 00:15:36 2019	(r346141)
@@ -259,6 +259,7 @@ fuse_internal_fsync(struct vnode *vp,
 	struct fuse_dispatcher fdi;
 	struct fuse_filehandle *fufh;
 	struct fuse_vnode_data *fvdat = VTOFUD(vp);
+	struct mount *mp = vnode_mount(vp);
 	int op = FUSE_FSYNC;
 	int err = 0;
 
@@ -269,6 +270,9 @@ fuse_internal_fsync(struct vnode *vp,
 	if (vnode_isdir(vp))
 		op = FUSE_FSYNCDIR;
 
+	if (!fsess_isimpl(mp, op))
+		return 0;
+
 	fdisp_init(&fdi, sizeof(*ffsi));
 	/*
 	 * fsync every open file handle for this file, because we can't be sure
@@ -292,6 +296,12 @@ fuse_internal_fsync(struct vnode *vp,
 			fuse_insert_callback(fdi.tick,
 				fuse_internal_fsync_callback);
 			fuse_insert_message(fdi.tick);
+		}
+		if (err == ENOSYS) {
+			/* ENOSYS means "success, and don't call again" */
+			fsess_set_notimpl(mp, op);
+			err = 0;
+			break;
 		}
 	}
 	fdisp_destroy(&fdi);

Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_vnops.c	Thu Apr 11 23:15:37 2019	(r346140)
+++ projects/fuse2/sys/fs/fuse/fuse_vnops.c	Fri Apr 12 00:15:36 2019	(r346141)
@@ -1893,6 +1893,9 @@ fuse_vnop_getextattr(struct vop_getextattr_args *ap)
 	if (fuse_isdeadfs(vp))
 		return (ENXIO);
 
+	if (!fsess_isimpl(mp, FUSE_GETXATTR))
+		return EOPNOTSUPP;
+
 	err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, VREAD);
 	if (err)
 		return err;
@@ -1927,8 +1930,10 @@ fuse_vnop_getextattr(struct vop_getextattr_args *ap)
 
 	err = fdisp_wait_answ(&fdi);
 	if (err != 0) {
-		if (err == ENOSYS)
+		if (err == ENOSYS) {
 			fsess_set_notimpl(mp, FUSE_GETXATTR);
+			err = EOPNOTSUPP;
+		}
 		goto out;
 	}
 
@@ -1974,12 +1979,23 @@ fuse_vnop_setextattr(struct vop_setextattr_args *ap)
 	if (fuse_isdeadfs(vp))
 		return (ENXIO);
 
+	if (!fsess_isimpl(mp, FUSE_SETXATTR))
+		return EOPNOTSUPP;
+
 	if (vfs_isrdonly(mp))
 		return EROFS;
 
 	/* Deleting xattrs must use VOP_DELETEEXTATTR instead */
-	if (ap->a_uio == NULL)
-		return (EINVAL);
+	if (ap->a_uio == NULL) {
+		/*
+		 * If we got here as fallback from VOP_DELETEEXTATTR, then
+		 * return EOPNOTSUPP.
+		 */
+		if (!fsess_isimpl(mp, FUSE_REMOVEXATTR))
+			return (EOPNOTSUPP);
+		else
+			return (EINVAL);
+	}
 
 	err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td,
 		VWRITE);
@@ -2013,10 +2029,9 @@ fuse_vnop_setextattr(struct vop_setextattr_args *ap)
 
 	err = fdisp_wait_answ(&fdi);
 
-	if (err != 0) {
-		if (err == ENOSYS)
-			fsess_set_notimpl(mp, FUSE_SETXATTR);
-		goto out;
+	if (err == ENOSYS) {
+		fsess_set_notimpl(mp, FUSE_SETXATTR);
+		err = EOPNOTSUPP;
 	}
 
 out:
@@ -2113,6 +2128,9 @@ fuse_vnop_listextattr(struct vop_listextattr_args *ap)
 	if (fuse_isdeadfs(vp))
 		return (ENXIO);
 
+	if (!fsess_isimpl(mp, FUSE_LISTXATTR))
+		return EOPNOTSUPP;
+
 	err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, VREAD);
 	if (err)
 		return err;
@@ -2141,8 +2159,10 @@ fuse_vnop_listextattr(struct vop_listextattr_args *ap)
 
 	err = fdisp_wait_answ(&fdi);
 	if (err != 0) {
-		if (err == ENOSYS)
+		if (err == ENOSYS) {
 			fsess_set_notimpl(mp, FUSE_LISTXATTR);
+			err = EOPNOTSUPP;
+		}
 		goto out;
 	}
 
@@ -2221,6 +2241,9 @@ fuse_vnop_deleteextattr(struct vop_deleteextattr_args 
 	if (fuse_isdeadfs(vp))
 		return (ENXIO);
 
+	if (!fsess_isimpl(mp, FUSE_REMOVEXATTR))
+		return EOPNOTSUPP;
+
 	if (vfs_isrdonly(mp))
 		return EROFS;
 
@@ -2246,9 +2269,9 @@ fuse_vnop_deleteextattr(struct vop_deleteextattr_args 
 	    ap->a_name);
 
 	err = fdisp_wait_answ(&fdi);
-	if (err != 0) {
-		if (err == ENOSYS)
-			fsess_set_notimpl(mp, FUSE_REMOVEXATTR);
+	if (err == ENOSYS) {
+		fsess_set_notimpl(mp, FUSE_REMOVEXATTR);
+		err = EOPNOTSUPP;
 	}
 
 	fdisp_destroy(&fdi);

Modified: projects/fuse2/tests/sys/fs/fusefs/fsync.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/fsync.cc	Thu Apr 11 23:15:37 2019	(r346140)
+++ projects/fuse2/tests/sys/fs/fusefs/fsync.cc	Fri Apr 12 00:15:36 2019	(r346141)
@@ -179,8 +179,7 @@ TEST_F(Fsync, eio)
  * subsequent calls to VOP_FSYNC will succeed automatically without being sent
  * to the filesystem daemon
  */
-/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236557 */
-TEST_F(Fsync, DISABLED_enosys)
+TEST_F(Fsync, enosys)
 {
 	const char FULLPATH[] = "mountpoint/some_file.txt";
 	const char RELPATH[] = "some_file.txt";

Modified: projects/fuse2/tests/sys/fs/fusefs/fsyncdir.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/fsyncdir.cc	Thu Apr 11 23:15:37 2019	(r346140)
+++ projects/fuse2/tests/sys/fs/fusefs/fsyncdir.cc	Fri Apr 12 00:15:36 2019	(r346141)
@@ -124,8 +124,7 @@ TEST_F(FsyncDir, eio)
  * subsequent calls to VOP_FSYNC will succeed automatically without being sent
  * to the filesystem daemon
  */
-/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236557 */
-TEST_F(FsyncDir, DISABLED_enosys)
+TEST_F(FsyncDir, enosys)
 {
 	const char FULLPATH[] = "mountpoint/some_dir";
 	const char RELPATH[] = "some_dir";
@@ -134,7 +133,7 @@ TEST_F(FsyncDir, DISABLED_enosys)
 
 	expect_lookup(RELPATH, ino);
 	expect_opendir(ino);
-	expect_fsyncdir(ino, FUSE_FSYNC_FDATASYNC, ENOSYS);
+	expect_fsyncdir(ino, 0, ENOSYS);
 
 	fd = open(FULLPATH, O_DIRECTORY);
 	ASSERT_LE(0, fd) << strerror(errno);

Modified: projects/fuse2/tests/sys/fs/fusefs/xattr.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/xattr.cc	Thu Apr 11 23:15:37 2019	(r346140)
+++ projects/fuse2/tests/sys/fs/fusefs/xattr.cc	Fri Apr 12 00:15:36 2019	(r346141)
@@ -141,15 +141,14 @@ TEST_F(Getxattr, enoattr)
  * failure and all future VOP_GETEXTATTR calls will fail with EOPNOTSUPP
  * without querying the filesystem daemon
  */
-/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236557 */
-TEST_F(Getxattr, DISABLED_enosys)
+TEST_F(Getxattr, enosys)
 {
 	char data[80];
 	uint64_t ino = 42;
 	int ns = EXTATTR_NAMESPACE_USER;
 	ssize_t r;
 
-	expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1);
+	expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2);
 	expect_getxattr(ino, "user.foo", ReturnErrno(ENOSYS));
 
 	r = extattr_get_file(FULLPATH, ns, "foo", data, sizeof(data));
@@ -265,13 +264,12 @@ TEST_F(Getxattr, user)
  * failure and all future VOP_LISTEXTATTR calls will fail with EOPNOTSUPP
  * without querying the filesystem daemon
  */
-/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236557 */
-TEST_F(Listxattr, DISABLED_enosys)
+TEST_F(Listxattr, enosys)
 {
 	uint64_t ino = 42;
 	int ns = EXTATTR_NAMESPACE_USER;
 
-	expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1);
+	expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2);
 	expect_listxattr(ino, 0, ReturnErrno(ENOSYS));
 
 	ASSERT_EQ(-1, extattr_list_file(FULLPATH, ns, NULL, 0));
@@ -485,13 +483,12 @@ TEST_F(Removexattr, enoattr)
  * failure and all future VOP_DELETEEXTATTR calls will fail with EOPNOTSUPP
  * without querying the filesystem daemon
  */
-/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236557 */
-TEST_F(Removexattr, DISABLED_enosys)
+TEST_F(Removexattr, enosys)
 {
 	uint64_t ino = 42;
 	int ns = EXTATTR_NAMESPACE_USER;
 
-	expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1);
+	expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2);
 	expect_removexattr(ino, "user.foo", ENOSYS);
 
 	ASSERT_EQ(-1, extattr_delete_file(FULLPATH, ns, "foo"));
@@ -533,8 +530,7 @@ TEST_F(Removexattr, system)
  * failure and all future VOP_SETEXTATTR calls will fail with EOPNOTSUPP
  * without querying the filesystem daemon
  */
-/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236557 */
-TEST_F(Setxattr, DISABLED_enosys)
+TEST_F(Setxattr, enosys)
 {
 	uint64_t ino = 42;
 	const char value[] = "whatever";
@@ -542,7 +538,7 @@ TEST_F(Setxattr, DISABLED_enosys)
 	int ns = EXTATTR_NAMESPACE_USER;
 	ssize_t r;
 
-	expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1);
+	expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2);
 	expect_setxattr(ino, "user.foo", value, ReturnErrno(ENOSYS));
 
 	r = extattr_set_file(FULLPATH, ns, "foo", (void*)value, value_len);





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