Skip to content

Add FUSE remap_file_range support for FICLONE/FICLONERANGE#27

Merged
ejc3 merged 1 commit intomainfrom
fuse-remap-support
Dec 26, 2025
Merged

Add FUSE remap_file_range support for FICLONE/FICLONERANGE#27
ejc3 merged 1 commit intomainfrom
fuse-remap-support

Conversation

@ejc3
Copy link
Copy Markdown
Owner

@ejc3 ejc3 commented Dec 26, 2025

Summary

Enables cp --reflink=always and FICLONE/FICLONERANGE ioctls through FUSE by adding remap_file_range support to the full stack.

Note: Continuation of #21 (which was merged then reverted).

Problem: FICLONE fails with EOPNOTSUPP through FUSE because there's no kernel opcode for it.

Solution:

  • Kernel patch adds FUSE_REMAP_FILE_RANGE opcode (54)
  • fuse-pipe protocol extension for RemapFileRange
  • Passthrough implementation using copy_file_range (which handles FICLONE on btrfs)
  • Integration tests that skip gracefully on unpatched kernels

Full Stack Implementation

Layer Component Changes
Kernel kernel/build.sh Inlines FUSE_REMAP_FILE_RANGE patch (opcode 54, struct, handler)
fuser ejc3/fuser:remap-file-range Opcode constant + remap_file_range trait method
fuse-backend-rs ejc3/fuse-backend-rs:remap-file-range PassthroughFs impl using copy_file_range
libfuse ejc3/libfuse:remap-file-range passthrough_ll.c impl for C-based testing
fuse-pipe src/protocol/, src/client/, src/server/ Wire protocol + handler
Tests tests/test_remap_file_range.rs VM end-to-end test
Tests fuse-pipe/tests/test_remap_file_range.rs Host-side FUSE tests
Tests Containerfile.libfuse-remap libfuse container test

Test Behavior

Tests skip gracefully without patched kernel - won't break CI:

Test Skip Condition
test_ficlone_cp_reflink_in_vm No btrfs, or exit code 1/38/95
test_ficlone_whole_file ENOSYS or EOPNOTSUPP from kernel
test_ficlonerange_partial ENOSYS or EOPNOTSUPP from kernel

Verified Working

remap_file_range called ino_in=2 fh_in=2 offset_in=0 ino_out=3 fh_out=3 len=0 remap_flags=0
remap_file_range response response=Written { size: 0 }
[ctr:stdout] FICLONE test passed
✓ Verified: files share physical extents (true reflink)
[REMAP-VM] ✓ ficlone (6.9s)

Test plan

  • cargo build --release passes
  • make test-root passes (tests skip on standard kernel)
  • REMAP_KERNEL=... make test-root FILTER=remap passes with patched kernel
  • libfuse container test passes: FICLONE + FICLONERANGE
  • filefrag confirms shared extents (true reflinks on btrfs)

@ejc3 ejc3 merged commit 0fbb1ce into main Dec 26, 2025
1 of 6 checks passed
ejc3 pushed a commit that referenced this pull request Feb 7, 2026
…tion

- Remove std::env::set_var for writeback cache propagation (#26): pass
  no_writeback_cache flag through mount_vsock_with_options API instead.
  set_var is unsound in multi-threaded Rust programs.
- Bound exec line reader to 1MB (#27): prevents OOM from malicious or
  malformed exec requests sent over vsock.
- Replace bash -c shell injection with direct Command args (#28): TAP
  device verification now uses ip link show directly instead of through
  a shell.
ejc3 pushed a commit that referenced this pull request Feb 7, 2026
…tion

- Remove std::env::set_var for writeback cache propagation (#26): pass
  no_writeback_cache flag through mount_vsock_with_options API instead.
  set_var is unsound in multi-threaded Rust programs.
- Bound exec line reader to 1MB (#27): prevents OOM from malicious or
  malformed exec requests sent over vsock.
- Replace bash -c shell injection with direct Command args (#28): TAP
  device verification now uses ip link show directly instead of through
  a shell.
ejc3 pushed a commit that referenced this pull request Feb 7, 2026
…tion

- Remove std::env::set_var for writeback cache propagation (#26): pass
  no_writeback_cache flag through mount_vsock_with_options API instead.
  set_var is unsound in multi-threaded Rust programs.
- Bound exec line reader to 1MB (#27): prevents OOM from malicious or
  malformed exec requests sent over vsock.
- Replace bash -c shell injection with direct Command args (#28): TAP
  device verification now uses ip link show directly instead of through
  a shell.
ejc3 added a commit that referenced this pull request Mar 2, 2026
…tion

- Remove std::env::set_var for writeback cache propagation (#26): pass
  no_writeback_cache flag through mount_vsock_with_options API instead.
  set_var is unsound in multi-threaded Rust programs.
- Bound exec line reader to 1MB (#27): prevents OOM from malicious or
  malformed exec requests sent over vsock.
- Replace bash -c shell injection with direct Command args (#28): TAP
  device verification now uses ip link show directly instead of through
  a shell.
ejc3 added a commit that referenced this pull request Mar 2, 2026
…tion

- Remove std::env::set_var for writeback cache propagation (#26): pass
  no_writeback_cache flag through mount_vsock_with_options API instead.
  set_var is unsound in multi-threaded Rust programs.
- Bound exec line reader to 1MB (#27): prevents OOM from malicious or
  malformed exec requests sent over vsock.
- Replace bash -c shell injection with direct Command args (#28): TAP
  device verification now uses ip link show directly instead of through
  a shell.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant