summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Koch <nioko1337@gmail.com>2018-05-17 14:10:14 +0200
committerNicolas Koch <nioko1337@gmail.com>2018-05-17 14:10:14 +0200
commit09d03bc245b27728c9cdd4976114506ae20208a7 (patch)
treeba1eda7458aaa0f40f36aba1378edd0f57c60350
parentFix large file copies on 32 bit platforms (diff)
downloadgrust-09d03bc245b27728c9cdd4976114506ae20208a7.tar.gz
grust-09d03bc245b27728c9cdd4976114506ae20208a7.tar.bz2
grust-09d03bc245b27728c9cdd4976114506ae20208a7.tar.xz
Store ENOSYS in a global to avoid unnecessary system calls
-rw-r--r--src/libstd/sys/unix/fs.rs35
1 files changed, 25 insertions, 10 deletions
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index d8739d6532..8412540934 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -781,6 +781,11 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
781#[cfg(any(target_os = "linux", target_os = "android"))] 781#[cfg(any(target_os = "linux", target_os = "android"))]
782pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { 782pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
783 use fs::{File, set_permissions}; 783 use fs::{File, set_permissions};
784 use sync::atomic::{AtomicBool, Ordering};
785
786 // Kernel prior to 4.5 don't have copy_file_range
787 // We store the availability in a global to avoid unneccessary syscalls
788 static HAS_COPY_FILE_RANGE: AtomicBool = AtomicBool::new(true);
784 789
785 unsafe fn copy_file_range( 790 unsafe fn copy_file_range(
786 fd_in: libc::c_int, 791 fd_in: libc::c_int,
@@ -820,16 +825,26 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
820 } else { 825 } else {
821 (len - written) as usize 826 (len - written) as usize
822 }; 827 };
823 let copy_result = unsafe { 828 let copy_result = if HAS_COPY_FILE_RANGE.load(Ordering::Relaxed) {
824 // We actually don't have to adjust the offsets, 829 let copy_result = unsafe {
825 // because copy_file_range adjusts the file offset automatically 830 // We actually don't have to adjust the offsets,
826 cvt(copy_file_range(reader.as_raw_fd(), 831 // because copy_file_range adjusts the file offset automatically
827 ptr::null_mut(), 832 cvt(copy_file_range(reader.as_raw_fd(),
828 writer.as_raw_fd(), 833 ptr::null_mut(),
829 ptr::null_mut(), 834 writer.as_raw_fd(),
830 bytes_to_copy, 835 ptr::null_mut(),
831 0) 836 bytes_to_copy,
832 ) 837 0)
838 )
839 };
840 if let Err(ref copy_err) = copy_result {
841 if let Some(libc::ENOSYS) = copy_err.raw_os_error() {
842 HAS_COPY_FILE_RANGE.store(false, Ordering::Relaxed);
843 }
844 }
845 copy_result
846 } else {
847 Err(io::Error::from_raw_os_error(libc::ENOSYS))
833 }; 848 };
834 match copy_result { 849 match copy_result {
835 Ok(ret) => written += ret as u64, 850 Ok(ret) => written += ret as u64,