fuse integration: require an external mount to be a FUSE filesystem

A device-ID boundary alone does not prove FUSE: a tmpfs mount would pass mountedAt and report its results as FUSE compliance. Check the filesystem type (statfs magic on linux, fstypename on the BSDs); platforms without a check keep the mount and write verification.
This commit is contained in:
Chris Lu committed 2026-10-22 08:14:33 -07:00
1 parent 6d62bf517d
commit 8342499e35
6 files changed
+71 -1

No files matched your search

+5
View File
@@ -108,6 +108,11 @@ func (f *FuseTestFramework) Setup(config *TestConfig) error {
if !mountedAt(existingMount) {
return fmt.Errorf("mount point %s is not a mounted filesystem", existingMount)
}
// So can a non-FUSE mount like tmpfs: a device boundary alone does
// not make the results FUSE compliance
if !fuseFilesystem(existingMount) {
return fmt.Errorf("mount point %s is not a FUSE filesystem", existingMount)
}
// Run inside a private work dir so test files do not pile up in
// the shared mount root and cleanup can remove only what it made
+25
View File
@@ -0,0 +1,25 @@
//go:build darwin || freebsd
package fuse
import (
"strings"
"syscall"
)
// fuseFilesystem reports whether path sits on a FUSE mount; macFUSE, osxfuse
// and fusefs all carry "fuse" in the filesystem type name.
func fuseFilesystem(path string) bool {
var st syscall.Statfs_t
if err := syscall.Statfs(path, &st); err != nil {
return false
}
name := make([]byte, 0, len(st.Fstypename))
for _, c := range st.Fstypename {
if c == 0 {
break
}
name = append(name, byte(c))
}
return strings.Contains(string(name), "fuse")
}
+17
View File
@@ -0,0 +1,17 @@
//go:build linux
package fuse
import "syscall"
// fuseSuperMagic is statfs f_type for fuse and fuseblk mounts.
const fuseSuperMagic = 0x65735546
// fuseFilesystem reports whether path sits on a FUSE mount.
func fuseFilesystem(path string) bool {
var st syscall.Statfs_t
if err := syscall.Statfs(path, &st); err != nil {
return false
}
return st.Type == fuseSuperMagic
}
@@ -0,0 +1,9 @@
//go:build (unix && !linux && !darwin && !freebsd) || (!unix && !windows)
package fuse
// fuseFilesystem has no portable check on these platforms; the mount check
// and write verification in Setup stay the only gates.
func fuseFilesystem(path string) bool {
return true
}
@@ -1,4 +1,4 @@
//go:build unix
//go:build linux
package fuse
@@ -17,3 +17,11 @@ func TestMountedAt(t *testing.T) {
}
}
}
func TestFuseFilesystem(t *testing.T) {
for _, p := range []string{"/proc", t.TempDir()} {
if fuseFilesystem(p) {
t.Errorf("fuseFilesystem(%q) = true, want false", p)
}
}
}
+6
View File
@@ -32,3 +32,9 @@ func mountedAt(path string) bool {
data, ok := info.Sys().(*syscall.Win32FileAttributeData)
return ok && data.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0
}
// fuseFilesystem is covered by the WinFsp checks in mountedAt: WinFsp is the
// only FUSE provider on the platform.
func fuseFilesystem(path string) bool {
return true
}