Skip to content

fast_io.rs: use sendfile or splice if copy_file_range is not supported - #459

Open
Franklin-Qi wants to merge 1 commit into
uutils:mainfrom
Franklin-Qi:fix-#443-use-sendfile-or-splice-if-copy-file-range-is-not-supported
Open

fast_io.rs: use sendfile or splice if copy_file_range is not supported#459
Franklin-Qi wants to merge 1 commit into
uutils:mainfrom
Franklin-Qi:fix-#443-use-sendfile-or-splice-if-copy-file-range-is-not-supported

Conversation

@Franklin-Qi

@Franklin-Qi Franklin-Qi commented Jun 5, 2026

Copy link
Copy Markdown
Contributor
  • Use splice (via rustix) and attempt to expand the pipe size when necessary.
  • Modify reliable_copy_file_range() to try copy_file_rangesplicewrite.
  • Add Linux-based unit tests.

Closes: #443

@codecov

codecov Bot commented Jun 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.57746% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.17%. Comparing base (618a3f7) to head (1889db5).

Files with missing lines Patch % Lines
src/sed/fast_io.rs 79.57% 28 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #459      +/-   ##
==========================================
- Coverage   83.27%   83.17%   -0.10%     
==========================================
  Files          13       13              
  Lines        6994     7119     +125     
  Branches      397      401       +4     
==========================================
+ Hits         5824     5921      +97     
- Misses       1167     1194      +27     
- Partials        3        4       +1     
Flag Coverage Δ
macos_latest 83.90% <87.50%> (-0.02%) ⬇️
ubuntu_latest 84.01% <80.14%> (-0.11%) ⬇️
windows_latest 0.00% <0.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Franklin-Qi
Franklin-Qi force-pushed the fix-#443-use-sendfile-or-splice-if-copy-file-range-is-not-supported branch from cee18ce to 581e725 Compare June 5, 2026 07:57
@oech3

oech3 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

sendfile is internally splice. So no worth to try it. splice with middler pipe is faster.

@oech3

oech3 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Please use rustix instead of unsafe libc.

Comment thread src/sed/fast_io.rs Outdated
Comment thread src/sed/fast_io.rs Outdated
Comment thread src/sed/fast_io.rs Outdated
Comment thread src/sed/fast_io.rs Outdated
Comment thread src/sed/fast_io.rs Outdated
Comment thread src/sed/fast_io.rs Outdated
@sylvestre

Copy link
Copy Markdown
Contributor

@Franklin-Qi sorry, it needs to be rebased

@Franklin-Qi
Franklin-Qi force-pushed the fix-#443-use-sendfile-or-splice-if-copy-file-range-is-not-supported branch from 581e725 to bd5b0e2 Compare August 12, 2026 00:35
@codspeed-hq

codspeed-hq Bot commented Aug 12, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 0.97%

⚡ 2 improved benchmarks
❌ 2 regressed benchmarks
✅ 7 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
access_log_subst 2.4 s 2.5 s -6.22%
number_fix 1.4 s 1.5 s -5.76%
no_op_short 2.4 s 2.3 s +5.15%
access_log_no_op 1.8 s 1.7 s +3.51%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing Franklin-Qi:fix-#443-use-sendfile-or-splice-if-copy-file-range-is-not-supported (1889db5) with main (618a3f7)

Open in CodSpeed

@Franklin-Qi
Franklin-Qi force-pushed the fix-#443-use-sendfile-or-splice-if-copy-file-range-is-not-supported branch 4 times, most recently from 6bb25e7 to 7551756 Compare August 12, 2026 01:17
- Use `splice` and attempt to expand the pipe size when necessary.
- Modify the `reliable_copy_file_range()` function to sequentially attempt `copy_file_range` → `splice` → `sendfile` → `write`.
- Add Linux-based unit tests.

Closes: uutils#443
@Franklin-Qi
Franklin-Qi force-pushed the fix-#443-use-sendfile-or-splice-if-copy-file-range-is-not-supported branch from 7551756 to 1889db5 Compare August 12, 2026 01:34
Comment thread src/sed/fast_io.rs
struct FastCopy {
fd: i32, // Raw file descriptor
is_regular: bool, // True if this is a regular file
is_fifo: bool, // True if this is a pipe/FIFO (splice-capable)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to check that input or output is pipe if middler pipe is used. Also splice fails if both of in/output are not pipe. So that bool should be unnecessary.

Comment thread src/sed/fast_io.rs
#[cfg(target_os = "linux")]
use rustix::fs::copy_file_range as rustix_copy_file_range;

#[cfg(all(target_os = "linux", target_env = "gnu"))]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[cfg(all(target_os = "linux", target_env = "gnu"))]
#[cfg(target_os = "linux")]

Same for others.

Comment thread src/sed/fast_io.rs

/// Best-effort pipe capacity bump. Larger size is optional, so failures are ignored.
#[cfg(all(target_os = "linux", target_env = "gnu"))]
fn set_pipe_size(fd: impl AsFd, size: usize) -> Result<(), ()> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to wrap this even we just ignore the error?

Comment thread src/sed/fast_io.rs
out_fd: BorrowedFd<'_>,
len: usize,
) -> std::io::Result<Option<usize>> {
match splice(in_fd, Some(in_off), out_fd, None, len, SpliceFlags::MORE) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think MORE is useful at here.

Comment thread src/sed/fast_io.rs
/// Falls back to write(2) if splice is not supported.
#[cfg(all(target_os = "linux", target_env = "gnu"))]
fn reliable_splice(
in_ptr: *const u8,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed (with unsafe code)?

Comment thread src/sed/fast_io.rs
// Spawn a reader that drains slowly
thread::spawn(move || {
let mut buf = [0u8; 1024];
loop {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while let Ok(1..) = reader.read(&mut buf) {...}

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.

fast_io.rs: use sendfile or splice if copy_file_range is not supported

3 participants