Skip to content

Conversation

@wdcui
Copy link
Member

@wdcui wdcui commented Feb 2, 2026

Summary

This PR implements the fallocate(2) Linux syscall which allows applications to manipulate file space allocation.

Changes

Core litebox crate

  • Added FallocMode enum for generic operation modes in litebox/src/fs/mod.rs
  • Added FallocateError enum in litebox/src/fs/errors.rs
  • Implemented FileSystem::fallocate() trait method with implementations for:
    • in_mem.rs: Full implementation of all modes
    • devices.rs: Returns NotSupported for device files
    • layered.rs: Delegates to appropriate layer with migration support
    • nine_p.rs: Placeholder (todo)
    • tar_ro.rs: Returns appropriate errors for read-only filesystem

litebox_common_linux crate

  • Added FallocateMode bitflags for Linux-specific mode flags
    • Includes is_valid() for flag validation
    • Includes to_falloc_mode() for conversion to generic enum
  • Added FallocateError to Errno conversion

litebox_shim_linux crate

  • Added Fallocate variant to SyscallRequest enum
  • Added syscall parsing for Sysno::fallocate
  • Added dispatch case in do_syscall
  • Implemented sys_fallocate() handler with proper validation

Supported Modes

Mode Description
Allocate Preallocate space, extending file if needed
AllocateKeepSize Preallocate without extending file size
AllocateUnshareRange Make shared data private (COW)
PunchHoleKeepSize Deallocate space (create hole)
ZeroRange Zero out range, potentially extending file
ZeroRangeKeepSize Zero out range without extending
CollapseRange Remove range and shift data down
InsertRange Insert hole and shift data up

Testing

Added 10 comprehensive unit tests:

  • test_fallocate_basic_allocation
  • test_fallocate_keep_size
  • test_fallocate_punch_hole
  • test_fallocate_zero_range
  • test_fallocate_collapse_range
  • test_fallocate_insert_range
  • test_fallocate_invalid_mode
  • test_fallocate_invalid_parameters
  • test_fallocate_bad_fd
  • test_fallocate_read_only_file

All tests pass locally on x86_64 Linux.

Checklist

  • cargo fmt applied
  • cargo clippy --all-targets --all-features passes
  • All existing tests pass
  • New unit tests added and passing

wdcui added 2 commits February 2, 2026 03:04
This commit adds support for the fallocate(2) syscall which allows
applications to manipulate file space allocation.

Changes:
- Added FallocateMode bitflags in litebox_common_linux for Linux-specific
  mode flags (KEEP_SIZE, PUNCH_HOLE, COLLAPSE_RANGE, ZERO_RANGE,
  INSERT_RANGE, UNSHARE_RANGE)
- Added FallocMode enum in litebox for generic operation modes
- Added FallocateError enum for fallocate-specific errors
- Implemented FileSystem::fallocate() trait method with implementations
  for all filesystem backends (in_mem, devices, layered, nine_p, tar_ro)
- Added syscall parsing and dispatch for Sysno::fallocate
- Added sys_fallocate() handler with proper validation
- Added 10 comprehensive unit tests covering all modes and error cases

Supported modes:
- Allocate: Preallocate space, extending file if needed
- AllocateKeepSize: Preallocate without extending file size
- AllocateUnshareRange: Make shared data private (COW)
- PunchHoleKeepSize: Deallocate space (create hole)
- ZeroRange: Zero out range, potentially extending file
- ZeroRangeKeepSize: Zero out range without extending
- CollapseRange: Remove range and shift data down
- InsertRange: Insert hole and shift data up

Tested on x86_64 Linux.
- Fix memory exhaustion vulnerability by adding MAX_FILE_SIZE limit
- Fix integer truncation on 32-bit by using try_from for safe conversion
- Fix CollapseRange boundary check (>= instead of >) per Linux man page
- Fix InsertRange boundary check (>= instead of >) per Linux man page
- Add AllocateUnshareRangeKeepSize variant to preserve KEEP_SIZE semantics
- Add 3 new boundary condition tests:
  - test_fallocate_collapse_range_boundary
  - test_fallocate_insert_range_boundary
  - test_fallocate_empty_file_edge_cases

Security fixes based on code review:
1. Memory exhaustion: fallocate() now rejects requests that would exceed
   isize::MAX bytes, preventing trivial DoS attacks via massive allocations.
2. Integer truncation: Using usize::try_from() instead of direct casts to
   safely handle 32-bit platforms and large i64 values.

Correctness fixes based on code review:
1. CollapseRange: Changed boundary check from '>' to '>=' to match Linux
   semantics where offset+len 'reaching' EOF is an error.
2. InsertRange: Changed boundary check from '>' to '>=' to match Linux
   semantics where offset 'equal to' EOF is an error.

API fix based on code review:
1. Added AllocateUnshareRangeKeepSize variant so UNSHARE_RANGE|KEEP_SIZE
   doesn't lose the KEEP_SIZE semantics during conversion.
@github-actions
Copy link

github-actions bot commented Feb 2, 2026

🤖 SemverChecks 🤖 ⚠️ Potential breaking API changes detected ⚠️

Click for details
--- failure enum_no_repr_variant_discriminant_changed: enum variant had its discriminant change value ---

Description:
The enum's variant had its discriminant value change. This breaks downstream code that used its value via a numeric cast like `as isize`.
        ref: https://doc.rust-lang.org/reference/items/enumerations.html#assigning-discriminant-values
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.46.0/src/lints/enum_no_repr_variant_discriminant_changed.ron

Failed in:
  variant SyscallRequest::Unlinkat 56 -> 57 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2264
  variant SyscallRequest::Newfstatat 57 -> 58 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2270
  variant SyscallRequest::Eventfd2 58 -> 59 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2283
  variant SyscallRequest::Pipe2 59 -> 60 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2287
  variant SyscallRequest::Clone 60 -> 61 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2291
  variant SyscallRequest::Clone3 61 -> 62 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2294
  variant SyscallRequest::SetThreadArea 62 -> 63 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2299
  variant SyscallRequest::ClockGettime 63 -> 64 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2302
  variant SyscallRequest::ClockGetres 64 -> 65 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2306
  variant SyscallRequest::ClockNanosleep 65 -> 66 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2310
  variant SyscallRequest::Gettimeofday 66 -> 67 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2316
  variant SyscallRequest::Time 67 -> 68 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2320
  variant SyscallRequest::Getrlimit 68 -> 69 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2323
  variant SyscallRequest::Setrlimit 69 -> 70 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2327
  variant SyscallRequest::Prlimit 70 -> 71 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2331
  variant SyscallRequest::SetTidAddress 71 -> 72 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2342
  variant SyscallRequest::Gettid 72 -> 73 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2345
  variant SyscallRequest::SetRobustList 73 -> 74 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2346
  variant SyscallRequest::GetRobustList 74 -> 75 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2349
  variant SyscallRequest::GetRandom 75 -> 76 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2354
  variant SyscallRequest::Getpid 76 -> 77 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2359
  variant SyscallRequest::Getppid 77 -> 78 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2360
  variant SyscallRequest::Getuid 78 -> 79 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2361
  variant SyscallRequest::Geteuid 79 -> 80 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2362
  variant SyscallRequest::Getgid 80 -> 81 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2363
  variant SyscallRequest::Getegid 81 -> 82 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2364
  variant SyscallRequest::Sysinfo 82 -> 83 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2365
  variant SyscallRequest::CapGet 83 -> 84 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2368
  variant SyscallRequest::GetDirent64 84 -> 85 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2372
  variant SyscallRequest::SchedGetAffinity 85 -> 86 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2377
  variant SyscallRequest::SchedYield 86 -> 87 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2382
  variant SyscallRequest::Futex 87 -> 88 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2383
  variant SyscallRequest::Execve 88 -> 89 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2386
  variant SyscallRequest::Umask 89 -> 90 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2391
  variant SyscallRequest::Prctl 90 -> 91 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2394
  variant SyscallRequest::Alarm 91 -> 92 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2397
  variant SyscallRequest::SetITimer 92 -> 93 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2400

@wdcui wdcui closed this Feb 2, 2026
@wdcui wdcui deleted the wdcui/fallocate branch February 2, 2026 22:53
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.

2 participants