Skip to content

Commit d179dd5

Browse files
committed
Auto merge of #134547 - SUPERCILEX:unify-copy, r=<try>
Unify fs::copy and io::copy on Linux Currently, `fs::copy` first tries a regular file copy (via copy_file_range) and then falls back to userspace read/write copying. We should use `io::copy` instead as it tries copy_file_range, sendfile, and splice before falling back to userspace copying. This was discovered here: SUPERCILEX/fuc#40 Perf impact: `fs::copy` will now have two additional statx calls to decide which syscall to use. I wonder if we should get rid of the statx calls and only continue down the next fallback when the relevant syscalls say the FD isn't supported.
2 parents 13170cd + 2b4334e commit d179dd5

File tree

1 file changed

+1
-19
lines changed
  • library/std/src/sys/pal/unix

1 file changed

+1
-19
lines changed

library/std/src/sys/pal/unix/fs.rs

+1-19
Original file line numberDiff line numberDiff line change
@@ -1980,32 +1980,14 @@ fn open_to_and_set_permissions(
19801980
Ok((writer, writer_metadata))
19811981
}
19821982

1983-
#[cfg(not(any(target_os = "linux", target_os = "android", target_vendor = "apple")))]
1983+
#[cfg(not(target_vendor = "apple"))]
19841984
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
19851985
let (mut reader, reader_metadata) = open_from(from)?;
19861986
let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?;
19871987

19881988
io::copy(&mut reader, &mut writer)
19891989
}
19901990

1991-
#[cfg(any(target_os = "linux", target_os = "android"))]
1992-
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
1993-
let (mut reader, reader_metadata) = open_from(from)?;
1994-
let max_len = u64::MAX;
1995-
let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?;
1996-
1997-
use super::kernel_copy::{CopyResult, copy_regular_files};
1998-
1999-
match copy_regular_files(reader.as_raw_fd(), writer.as_raw_fd(), max_len) {
2000-
CopyResult::Ended(bytes) => Ok(bytes),
2001-
CopyResult::Error(e, _) => Err(e),
2002-
CopyResult::Fallback(written) => match io::copy::generic_copy(&mut reader, &mut writer) {
2003-
Ok(bytes) => Ok(bytes + written),
2004-
Err(e) => Err(e),
2005-
},
2006-
}
2007-
}
2008-
20091991
#[cfg(target_vendor = "apple")]
20101992
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
20111993
const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA;

0 commit comments

Comments
 (0)