Giter Club home page Giter Club logo

Comments (9)

trapexit avatar trapexit commented on August 15, 2024 1

https://github.com/libfuse/libfuse/blob/master/lib/fuse_lowlevel.c#L2739

The return value for unknown messages in the protocol is ENOSYS. So it is reasonable that the error for undefined callbacks would similarly be ENOSYS all things equal.

https://github.com/libfuse/libfuse/blob/master/include/fuse_kernel.h#L159

And the functions you mentioned are not equal. They are late additions to Linux and therefore to FUSE and libfuse. And those functions have well defined values for not implemented by filesystem because they needed them for every kernel FS that didn't / doesn't support them. Often EOPNOTSUPP.

https://www.man7.org/linux/man-pages/man2/copy_file_range.2.html

EOPNOTSUPP (since Linux 5.19) The filesystem does not support this operation.

And lets not forget that FUSE is a multi platform protocol and libfuse a multi platform library. You know what doesn't show up in FreeBSD's manpage or POSIX's definition for link syscalls? EPERM meaning that the function isn't supported. I've not checked but it is possible that EPERM in Linux to mean that could have happened later in the platform's life.

https://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html

https://man.freebsd.org/cgi/man.cgi?query=link&sektion=2

And as I said there is not strong agreement or consistency wrt error codes. There never has been and there never will be. Some syscalls have undocumented errors. syscalls that communicate with other systems that are pluggable (like filesystems) often have inconsistencies. Lots of software don't even differentiate between errnos. For years Apple returned EIO when EXDEV or many other errors were returned by a filesystem in their SMB server. A number of errors overlap meaning. Some are the same underlying value. Some do or don't exist on different platforms.

https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html

Macro: int ENOSYS
“Function not implemented.” This indicates that the function called is not implemented at all, either in the C library itself or in the operating system. When you get this error, you can be sure that this particular function will always fail with ENOSYS unless you install a new version of the C library or the operating system.

Macro: int ENOTSUP
“Not supported.” A function returns this error when certain parameter values are valid, but the functionality they request is not available. This can mean that the function does not implement a particular command or option value or flag bit at all. For functions that operate on some object given in a parameter, such as a file descriptor or a port, it might instead mean that only that specific object (file descriptor, port, etc.) is unable to support the other parameters given; different file descriptors might support different ranges of parameter values. If the entire function is not available at all in the implementation, it returns ENOSYS instead.

Macro: int EOPNOTSUPP
“Operation not supported.” The operation you requested is not supported. Some socket functions don’t make sense for all types of sockets, and others may not be implemented for all communications protocols. On GNU/Hurd systems, this error can happen for many calls when the object does not support the particular operation; it is a generic indication that the server knows nothing to do for that call.

EOPNOTSUPP suggests use only for sockets as it says as much and grouped with other socket oriented errors yet the FS folks use it for numerous new functions as pointed out.

If you want link to return EPERM... just write the function. This argument has taken far more time than someone just adding the less than 10 lines of code to return whatever they wish.

from libfuse.

trapexit avatar trapexit commented on August 15, 2024

No, it is not a bug. This is the behavior of most unimplemented functions.

/*
 * These functions call the relevant filesystem operation, and return
 * the result.
 *
 * If the operation is not defined, they return -ENOSYS, with the
 * exception of fuse_fs_open, fuse_fs_release, fuse_fs_opendir,
 * fuse_fs_releasedir and fuse_fs_statfs, which return 0.
 */

return -ENOSYS;

from libfuse.

spectral54 avatar spectral54 commented on August 15, 2024

Should ENOSYS actually be returned to user-space though? Like if I run ln orig copy, should that really return to userspace that links aren't supported? That's not done by any other filesystem, is it?

I was under the impression that ENOSYS was a special value that libfuse would return to the kernel to say "hey, I don't support this, stop bothering me about it", and the kernel side of fuse would remember "oh, 'LINK' isn't supported by this filesystem, I won't even send this", and will translate to the right error code.

If ENOSYS isn't special in any way like this, the default handler for link, symlink, etc. in libfuse should probably return a value that is actually specified in the man pages.

from libfuse.

trapexit avatar trapexit commented on August 15, 2024

No, it doesn't mean that for every function. Regardless, ENOSYS means "function not implemented". That is the most appropriate error for a function that you've not implemented. If you want something different then you should define it. No existing error for a particular function would make sense everywhere as it does. Those are errors for the function. Not about the function. FUSE is for building your own filesystem. Not a filesystem itself. It is for you to choose what you want. ENOSYS makes sense in that regard. Not all functions have a definition of EPERM meaning the FS doesn't support it. Nor does it make much sense. EPERM means "fs can't do something" and "you don't have proper perms to do something"? errno's are not exact sciences and pretty much every filesystem returns errors out of line with something. It is far from an exact science.

Besides... these values have been used since the beginning of the software. No one is going to change them.

from libfuse.

trapexit avatar trapexit commented on August 15, 2024

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/fuse/fuse_i.h?h=v6.9-rc3#n732

No no_link

from libfuse.

spectral54 avatar spectral54 commented on August 15, 2024

Returning ENOSYS from the function to the kernel makes sense. Returning ENOSYS from the kernel to the userland doesn't, because it shouldn't be up to the userland code to handle FUSE differently from every other filesystem. The kernel code for fuse should translate ENOSYS to EPERM for link, just like it translates ENOSYS in these other cases:

  • xattr family of functions: stop sending, return EOPNOTSUPP
  • ioctl: ENOTIFY (wat?), which has a lovely comment of "/* Translate ENOSYS, which shouldn't be returned from fs */"
  • flush: stop sending, translate to 0 here
  • fsync: stop sending, translate to 0 here
  • bmap: stop sending, translate to 0 here
  • poll: stop sending, translate to DEFAULT_POLLMASK here
  • copy_file_range: stop sending, translate to EOPNOTSUPP here
  • fallocate: stop sending, translate to EOPNOTSUPP here
  • tmpfile: stop sending, translate to EOPNOTSUPP here
  • sync_fs: stop sending, translate to 0 here

Sure, not all of them do translation, but the number of cases that do translate, especially with a comment like "Translate ENOSYS, which shouldn't be returned from fs", imply that ENOSYS isn't expected to escape the kernel<->libfuse communication, and the fact that it does for link is likely an oversight.

Besides... these values have been used since the beginning of the software. No one is going to change them.

The amount of inertia here is a fair point, and the risk of breaking things is pretty small, but non-zero, and there's an easy workaround, so I agree it's probably not going to be changed. That doesn't mean that the current behavior is correct, it's obviously not. It's just that fixing it is not worth the potential costs.

from libfuse.

bsbernd avatar bsbernd commented on August 15, 2024

At best that would need to be translated by fuse-kernel side, but obviously server (userspace) / client (fuse-kernel) agreement is that ENOSYS is used for not implemented methods.

from libfuse.

trapexit avatar trapexit commented on August 15, 2024

ioctl: ENOTIFY (wat?), which has a lovely comment of "/* Translate ENOSYS, which shouldn't be returned from fs */"

https://man.freebsd.org/cgi/man.cgi?ioctl

https://man7.org/linux/man-pages/man2/ioctl.2.html

https://pubs.opengroup.org/onlinepubs/009604599/functions/ioctl.html

https://man.openbsd.org/ioctl.2

https://software.cfht.hawaii.edu/man/solaris/ioctl(2)

https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/ioctl.2.html

ENOTTY is pretty common for "not supported" for ioctl

from libfuse.

spectral54 avatar spectral54 commented on August 15, 2024

I feel like we're saying different things.

I'm fine with the protocol between the kernel and the FUSE daemon involving ENOSYS. That's fine, let's stop arguing about that because there's no disagreement there.

There are many functions where the Linux kernel receives ENOSYS from the FUSE daemon and translates it to something else when forwarding it to what I apparently confusingly called "userland": ls, ln, vi, whatever. link doesn't do that in the Linux kernel, and that's a bug, or a missing feature (depending on how pedantic you want to be). For convenience, I'm going to call it like I see it: a bug in the Linux kernel's implementation of the FUSE protocol.

That bug in the Linux kernel probably won't be/shouldn't be fixed, due to the many years of history of it NOT correcting the error code, and the simplicity of returning EPERM from the FUSE daemon.

I think we can end the discussion here. Yes, it's a bug/missing feature. No, it won't be changed. There's a very simple workaround. Let's move on.

ioctl: ENOTIFY (wat?)

I misread it when I was looking at the source code, ENOTTY makes a lot more sense than ENOTIFY (which I don't think exists, at least not on Linux) for ioctl.

from libfuse.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.