Skip to content

Commit 01d69c9

Browse files
committed
Eliminate redundant statx syscalls
1 parent 73b41fb commit 01d69c9

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

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

+8-5
Original file line numberDiff line numberDiff line change
@@ -1944,7 +1944,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)>
19441944
#[cfg(target_os = "espidf")]
19451945
fn open_to_and_set_permissions(
19461946
to: &Path,
1947-
_reader_metadata: crate::fs::Metadata,
1947+
_reader_metadata: &crate::fs::Metadata,
19481948
) -> io::Result<(crate::fs::File, crate::fs::Metadata)> {
19491949
use crate::fs::OpenOptions;
19501950
let writer = OpenOptions::new().open(to)?;
@@ -1955,7 +1955,7 @@ fn open_to_and_set_permissions(
19551955
#[cfg(not(target_os = "espidf"))]
19561956
fn open_to_and_set_permissions(
19571957
to: &Path,
1958-
reader_metadata: crate::fs::Metadata,
1958+
reader_metadata: &crate::fs::Metadata,
19591959
) -> io::Result<(crate::fs::File, crate::fs::Metadata)> {
19601960
use crate::fs::OpenOptions;
19611961
use crate::os::unix::fs::{OpenOptionsExt, PermissionsExt};
@@ -1982,10 +1982,13 @@ fn open_to_and_set_permissions(
19821982

19831983
#[cfg(not(target_vendor = "apple"))]
19841984
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
1985-
let (mut reader, reader_metadata) = open_from(from)?;
1986-
let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?;
1985+
let (reader, reader_metadata) = open_from(from)?;
1986+
let (writer, writer_metadata) = open_to_and_set_permissions(to, &reader_metadata)?;
19871987

1988-
io::copy(&mut reader, &mut writer)
1988+
io::copy(
1989+
&mut crate::sys::kernel_copy::CachedFileMetadata(reader, reader_metadata),
1990+
&mut crate::sys::kernel_copy::CachedFileMetadata(writer, writer_metadata),
1991+
)
19891992
}
19901993

19911994
#[cfg(target_vendor = "apple")]

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

+55-3
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ use crate::cmp::min;
5252
use crate::fs::{File, Metadata};
5353
use crate::io::copy::generic_copy;
5454
use crate::io::{
55-
BufRead, BufReader, BufWriter, Error, Read, Result, StderrLock, StdinLock, StdoutLock, Take,
56-
Write,
55+
BorrowedCursor, BufRead, BufReader, BufWriter, Error, IoSlice, IoSliceMut, Read, Result,
56+
StderrLock, StdinLock, StdoutLock, Take, Write,
5757
};
5858
use crate::mem::ManuallyDrop;
5959
use crate::net::TcpStream;
@@ -192,7 +192,7 @@ impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<'_, '_, R, W> {
192192
let w_cfg = writer.properties();
193193

194194
// before direct operations on file descriptors ensure that all source and sink buffers are empty
195-
let mut flush = || -> crate::io::Result<u64> {
195+
let mut flush = || -> Result<u64> {
196196
let bytes = reader.drain_to(writer, u64::MAX)?;
197197
// BufWriter buffered bytes have already been accounted for in earlier write() calls
198198
writer.flush()?;
@@ -537,6 +537,58 @@ impl<T: ?Sized + CopyWrite> CopyWrite for BufWriter<T> {
537537
}
538538
}
539539

540+
pub(crate) struct CachedFileMetadata(pub File, pub Metadata);
541+
542+
impl Read for CachedFileMetadata {
543+
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
544+
self.0.read(buf)
545+
}
546+
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
547+
self.0.read_vectored(bufs)
548+
}
549+
fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> {
550+
self.0.read_buf(cursor)
551+
}
552+
#[inline]
553+
fn is_read_vectored(&self) -> bool {
554+
self.0.is_read_vectored()
555+
}
556+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
557+
self.0.read_to_end(buf)
558+
}
559+
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
560+
self.0.read_to_string(buf)
561+
}
562+
}
563+
impl Write for CachedFileMetadata {
564+
fn write(&mut self, buf: &[u8]) -> Result<usize> {
565+
self.0.write(buf)
566+
}
567+
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
568+
self.0.write_vectored(bufs)
569+
}
570+
#[inline]
571+
fn is_write_vectored(&self) -> bool {
572+
self.0.is_write_vectored()
573+
}
574+
#[inline]
575+
fn flush(&mut self) -> Result<()> {
576+
self.0.flush()
577+
}
578+
}
579+
580+
impl CopyRead for CachedFileMetadata {
581+
fn properties(&self) -> CopyParams {
582+
CopyParams(FdMeta::Metadata(self.1.clone()), Some(self.0.as_raw_fd()))
583+
}
584+
}
585+
586+
impl CopyWrite for CachedFileMetadata {
587+
fn properties(&self) -> CopyParams {
588+
CopyParams(FdMeta::Metadata(self.1.clone()), Some(self.0.as_raw_fd()))
589+
}
590+
}
591+
540592
fn fd_to_meta<T: AsRawFd>(fd: &T) -> FdMeta {
541593
let fd = fd.as_raw_fd();
542594
let file: ManuallyDrop<File> = ManuallyDrop::new(unsafe { File::from_raw_fd(fd) });

0 commit comments

Comments
 (0)