svn commit: r346141 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
Alan Somers
asomers at FreeBSD.org
Tue Sep 3 14:06:45 UTC 2019
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);
More information about the svn-src-projects
mailing list