When a program calls pathconf(path, _PC_MIN_HOLE_SIZE) on a fusefs file system, if the kernel doesn't already know whether the file system supports FUSE_LSEEK, it must issue a FUSE_LSEEK operation to find out. It sends that operation to the provided path. BUT, the current implementation neglects to ensure that a fuse file handle is open. That's a bug. We never noticed it before because the test suite only uses fpathconf, not pathconf. Steps to Reproduce ================== 1) Mount a file system that is known to support FUSE_LSEEK 2) Without doing any open(), stat(), access(), or similar, try pathconf("/mountpoint/hello.txt", _PC_MIN_HOLE_SIZE) 3) It ought to return 1, but it will instead fail with EINVAL
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=6efba04df3f8c77b9b12f1df3e5124a7249b82fc commit 6efba04df3f8c77b9b12f1df3e5124a7249b82fc Author: Alan Somers <asomers@FreeBSD.org> AuthorDate: 2024-04-03 19:57:44 +0000 Commit: Alan Somers <asomers@FreeBSD.org> CommitDate: 2024-06-24 16:02:02 +0000 fusefs: fix two bugs regarding _PC_MIN_HOLE_SIZE Background: If a user does pathconf(_, _PC_MIN_HOLE_SIZE) on a fusefs file system, the kernel must actually issue a FUSE_LSEEK operation in order to determine whether the server supports it. We cache that result, so we only have to send FUSE_LSEEK the first time that _PC_MIN_HOLE_SIZE is requested on any given mountpoint. Problem 1: Unlike fpathconf, pathconf operates on files that may not be open. But FUSE_LSEEK requires the file to be open. As described in PR 278135, FUSE_LSEEK cannot be sent for unopened files, causing _PC_MIN_HOLE_size to wrongly report EINVAL. We never noticed that before because the fusefs test suite only uses fpathconf, not pathconf. Fix this bug by opening the file if necessary. Problem 2: On a completely sparse file, with no data blocks at all, FUSE_LSEEK with SEEK_DATA would fail to ENXIO. That's correct behavior, but fuse_vnop_pathconf wrongly interpreted that as "FUSE_LSEEK not supported". Fix the interpretation. PR: 278135 MFC after: 1 week Sponsored by: Axcient Differential Revision: https://reviews.freebsd.org/D44618 sys/fs/fuse/fuse_vnops.c | 48 ++++++++++++---- tests/sys/fs/fusefs/lseek.cc | 129 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 10 deletions(-)
A commit in branch stable/13 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=7f936b0cba08315c0127c425692369d0c162fbcf commit 7f936b0cba08315c0127c425692369d0c162fbcf Author: Alan Somers <asomers@FreeBSD.org> AuthorDate: 2024-04-03 19:57:44 +0000 Commit: Alan Somers <asomers@FreeBSD.org> CommitDate: 2024-07-08 20:27:54 +0000 fusefs: fix two bugs regarding _PC_MIN_HOLE_SIZE Background: If a user does pathconf(_, _PC_MIN_HOLE_SIZE) on a fusefs file system, the kernel must actually issue a FUSE_LSEEK operation in order to determine whether the server supports it. We cache that result, so we only have to send FUSE_LSEEK the first time that _PC_MIN_HOLE_SIZE is requested on any given mountpoint. Problem 1: Unlike fpathconf, pathconf operates on files that may not be open. But FUSE_LSEEK requires the file to be open. As described in PR 278135, FUSE_LSEEK cannot be sent for unopened files, causing _PC_MIN_HOLE_size to wrongly report EINVAL. We never noticed that before because the fusefs test suite only uses fpathconf, not pathconf. Fix this bug by opening the file if necessary. Problem 2: On a completely sparse file, with no data blocks at all, FUSE_LSEEK with SEEK_DATA would fail to ENXIO. That's correct behavior, but fuse_vnop_pathconf wrongly interpreted that as "FUSE_LSEEK not supported". Fix the interpretation. PR: 278135 Sponsored by: Axcient Differential Revision: https://reviews.freebsd.org/D44618 (cherry picked from commit 6efba04df3f8c77b9b12f1df3e5124a7249b82fc) sys/fs/fuse/fuse_vnops.c | 48 ++++++++++++---- tests/sys/fs/fusefs/lseek.cc | 129 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 10 deletions(-)
A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=4bb8e26c262c03757dd1db8d7964bc44ccc83d6a commit 4bb8e26c262c03757dd1db8d7964bc44ccc83d6a Author: Alan Somers <asomers@FreeBSD.org> AuthorDate: 2024-04-03 19:57:44 +0000 Commit: Alan Somers <asomers@FreeBSD.org> CommitDate: 2024-09-19 20:27:41 +0000 fusefs: fix two bugs regarding _PC_MIN_HOLE_SIZE Background: If a user does pathconf(_, _PC_MIN_HOLE_SIZE) on a fusefs file system, the kernel must actually issue a FUSE_LSEEK operation in order to determine whether the server supports it. We cache that result, so we only have to send FUSE_LSEEK the first time that _PC_MIN_HOLE_SIZE is requested on any given mountpoint. Problem 1: Unlike fpathconf, pathconf operates on files that may not be open. But FUSE_LSEEK requires the file to be open. As described in PR 278135, FUSE_LSEEK cannot be sent for unopened files, causing _PC_MIN_HOLE_size to wrongly report EINVAL. We never noticed that before because the fusefs test suite only uses fpathconf, not pathconf. Fix this bug by opening the file if necessary. Problem 2: On a completely sparse file, with no data blocks at all, FUSE_LSEEK with SEEK_DATA would fail to ENXIO. That's correct behavior, but fuse_vnop_pathconf wrongly interpreted that as "FUSE_LSEEK not supported". Fix the interpretation. PR: 278135 Sponsored by: Axcient Differential Revision: https://reviews.freebsd.org/D44618 (cherry picked from commit 6efba04df3f8c77b9b12f1df3e5124a7249b82fc) sys/fs/fuse/fuse_vnops.c | 48 ++++++++++++---- tests/sys/fs/fusefs/lseek.cc | 129 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 10 deletions(-)