Commit Graph

1 Commits

Author SHA1 Message Date
Levi Neely 0c0c6855c1
Migrate to FUSE 3.x API (#350)
* Migrate to FUSE 3.x API

- Update FUSE_USE_VERSION from 26 to 30
- Replace fuse_mount/fuse_unmount with fuse_session_mount/fuse_session_unmount
- Update fuse_new() to take args first, remove channel parameter
- Add flags parameter to readdir handler (enum fuse_readdir_flags)
- Add flags parameter to rename handler (for renameat2 support)
- Update filler function calls to include FUSE_FILL_DIR_PLUS flag
- Merge ftruncate into truncate handler (FUSE 3 combines them)
- Update fuse_loop_mt to fuse_loop_mt_31 with loop config
- Link against libfuse3 instead of libfuse
- Remove fuse_chan usage (deprecated in FUSE 3)

Addresses #342

* Remove deprecated FUSE options nonempty and hard_remove

- nonempty: Removed in FUSE 3.0, mounting on non-empty directories is now default behavior
- hard_remove: High-level API option not available in FUSE 3, immediate unlink is standard

These options are no longer recognized by FUSE 3 and cause mount errors.

* Fix init handler signature for FUSE 3

FUSE 3 init handler requires struct fuse_config* parameter.
This parameter provides access to high-level API configuration
options that can be modified during initialization.

Without this parameter, the init handler signature is incompatible
with FUSE 3, causing filesystem operations to fail.

* Add FUSE 2/3 backward compatibility

Automatically detects and builds against either FUSE 2 or FUSE 3:
- detect_fuse.sh script checks for fuse3 or fuse pkg-config
- Makefile dynamically sets FUSE_USE_VERSION, CFLAGS, and LDFLAGS
- Conditional compilation (#if FUSE_USE_VERSION >= 30) for API differences:
  * init handler signature (fuse_config parameter)
  * readdir handler signature (flags parameter)
  * rename handler signature (flags parameter)
  * truncate handler signature (fuse_file_info parameter)
  * filler function calls (flags parameter)
  * fuse_loop_mt vs fuse_loop_mt_31
  * mount/unmount sequence (fuse_session_mount vs fuse_mount)
  * ftruncate operations struct member

Maintains full compatibility with both FUSE 2.x (Debian Bookworm) and
FUSE 3.x (Debian Testing+) without requiring separate code branches.

* Add FORCE_FUSE build option and fix hardcoded version

- Remove hardcoded FUSE_USE_VERSION defines from source files
- Add FORCE_FUSE=2 or FORCE_FUSE=3 Makefile option to override detection
- Fix FUSE 2 channel tracking (psync_fuse_channel variable)
- Properly store and use channel in mount/unmount for FUSE 2

Usage:
  make                  # Auto-detect (prefers FUSE 3)
  make FORCE_FUSE=2     # Force FUSE 2 build
  make FORCE_FUSE=3     # Force FUSE 3 build

Verified both FUSE 2 and FUSE 3 builds work correctly.

* Fix CI/CD: Add fallback for systems without pkg-config

- detect_fuse.sh now checks for pkg-config availability first
- Falls back to checking for header files in standard locations
- Makefile provides default CFLAGS when pkg-config unavailable
- Fixes build on minimal CI/CD environments

Fallback locations checked:
- /usr/include/fuse3/fuse.h (FUSE 3)
- /usr/local/include/fuse3/fuse.h (FUSE 3)
- /usr/include/fuse/fuse.h (FUSE 2)
- /usr/local/include/fuse/fuse.h (FUSE 2)

* Enhance FUSE detection for non-standard locations

Multi-stage detection strategy:
1. Try pkg-config (fastest, most reliable)
2. Search common header locations:
   - /usr/include, /usr/local/include
   - /opt/local/include, /opt/include
3. Compiler test as last resort:
   - Attempts to preprocess #include <fuse.h>
   - Tests both FUSE 3 and FUSE 2 versions

This handles:
- Minimal CI/CD environments (no pkg-config)
- Non-standard install locations (Homebrew, custom builds)
- Distro-specific paths (BSD, macOS, custom Linux)

The compiler test ensures detection works even when headers
are in unusual locations that gcc can find via its search paths.

* Support FUSE 3.12+ API

- Use fuse_loop_mt_312 for FUSE 3.12+, fuse_loop_mt_31 for 3.0-3.11
- Conditionally add fuse_file_info param to getattr/chmod/chown/utimens
- Replace fuse_session_mount/unmount with fuse_mount/unmount
- Tested with FUSE 3.18 on Debian forky

* Fix pcl-1ib: correct FUSE 3.x handler signatures and loop_mt call

- Replace FUSE_MINOR_VERSION >= 12 checks with FUSE_USE_VERSION >= 30
  for getattr/chmod/chown/utimens handler signatures; FUSE 3.x always
  requires the extra struct fuse_file_info* parameter — the wrong
  signature caused type mismatches and "Transport endpoint is not
  connected" failures
- Replace non-existent fuse_loop_mt_312 extern with correct conditional:
  FUSE_USE_VERSION >= 32 uses fuse_loop_mt(f, &config), else
  fuse_loop_mt_31(f, clone_fd)
- Fix inverted return logic in is_fuse3_installed_on_system(): was
  returning 0 on success (when fusermount3 found), now correctly
  returns non-zero

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Remove unused is_fuse3_installed_on_system() from pfs.c

The function was static and had no remaining call sites after the
-ononempty/-ohard_remove args block was cleaned up, producing a
-Wunused-function warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Restore shutdown_requested definition removed during rebase conflict resolution

The variable is declared extern in pfs.h and referenced in both
pfs.c (psync_signal_handler) and control_tools.cpp; the definition
must exist in pfs.c.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix pfs_creat: missing canmodify assignment causes EACCES on write

pfs_creat called pfs_create_file() but never set of->canmodify, leaving
it zero-initialized. pfs_write and pfs_ftruncate both check canmodify
and return -EACCES if false, making all writes to newly created files
fail with Permission denied.

All five open paths in pfs_open set canmodify correctly (added in #326),
but pfs_creat was missed. Fix by applying the same pattern immediately
after psql_unlock(), while fpath is still in scope.

Caught during FUSE 2/3 regression testing (Phase 2 write test).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Extend CI matrix: add FUSE 2, FUSE 3 legacy/current/forky build jobs

Replaces single build job with four jobs covering all tested FUSE configs:
- fuse2: debian:trixie + libfuse-dev (FUSE_USE_VERSION=26)
- fuse3-legacy: ubuntu:20.04 + libfuse3-dev 3.9.x (fuse_loop_mt_31 path)
- fuse3-current: ubuntu:22.04 + libfuse3-dev 3.12.x
- fuse3-forky: debian:forky + libfuse3-dev 3.18.1

Each job verifies correct symbol linkage after build. Runtime mount tests
are outside CI scope (require privileged containers with /dev/fuse).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* CI: replace Ubuntu 20.04/22.04 with ubuntu:24.04 for FUSE3 job

ubuntu:20.04 has old compiler (g++-9) and mbedTLS 2.x.
ubuntu:22.04 ships mbedTLS 2.28.x; incompatible with our mbedTLS 3.x-only code.
ubuntu:24.04 has mbedTLS 3.x and libfuse3 3.16.x, covering the 3.12-3.17 range.
FUSE3 < 3.12 is verified locally but not representable in CI without fighting
old toolchains.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* CI: add archlinux:latest job for rolling-release compatibility

Arch Linux is a rolling distro shipping latest fuse3, mbedtls 3.x, and
gcc — useful as an early-warning canary for future API breakage. Also
directly covers the maintained Arch package.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* CI: add fedora:41 and fedora:latest jobs with mbedtls3-devel

Fedora ships both mbedtls 2.x and 3.x; explicitly install mbedtls3-devel
to match our mbedTLS 3.x-only requirement. fedora:41 pins a known-good
release; fedora:latest tracks current as a rolling canary alongside Arch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* README: add compatibility matrix with CI badge references

Documents the 6-distro build matrix tested in CI, mbedTLS 3.x requirement,
and notes on manual runtime mount testing coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix CI package names; clean up README compatibility matrix

- Fedora 41: mbedtls3-devel -> mbedtls3.6-devel (correct versioned name)
- Fedora latest (43): mbedtls3-devel -> mbedtls-devel (now ships 3.6.5)
- Ubuntu 24.04: replaced with debian:trixie FORCE_FUSE=3 (Ubuntu has no
  mbedTLS 3.x in standard repos; trixie has both libfuse3-dev and mbedTLS 3.x)
- README: remove CI badge links from compatibility matrix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 21:51:00 +01:00