@@ -23,33 +23,40 @@ pub(super) fn write_fast_using_splice<R: FdReadable, S: AsRawFd + AsFd>(
2323 handle : & InputHandle < R > ,
2424 write_fd : & S ,
2525) -> CatResult < bool > {
26- use nix:: fcntl:: { FcntlArg , fcntl} ;
27- let ( pipe_rd, pipe_wr) = pipe ( ) ?;
28- // improve performance
29- let _ = fcntl (
30- write_fd,
31- FcntlArg :: F_SETPIPE_SZ ( MAX_ROOTLESS_PIPE_SIZE as i32 ) ,
32- ) ;
33-
34- loop {
35- match splice ( & handle. reader , & pipe_wr, MAX_ROOTLESS_PIPE_SIZE ) {
36- Ok ( n) => {
37- if n == 0 {
38- return Ok ( false ) ;
26+ const FIRST_PIPE_SIZE : usize = 64 * 1024 ;
27+ if splice ( & handle. reader , & write_fd, FIRST_PIPE_SIZE ) . is_ok ( ) {
28+ // fcntl improves performance for large file which is large overhead for small files
29+ let _ = rustix:: pipe:: fcntl_setpipe_size ( write_fd, MAX_ROOTLESS_PIPE_SIZE ) ;
30+ loop {
31+ match splice ( & handle. reader , & write_fd, MAX_ROOTLESS_PIPE_SIZE ) {
32+ Ok ( 1 ..) => { }
33+ Ok ( 0 ) => return Ok ( false ) ,
34+ Err ( _) => return Ok ( true ) ,
35+ }
36+ }
37+ } else {
38+ // output is not pipe. Needs broker to use splice() which is high cost for small files
39+ let ( pipe_rd, pipe_wr) = pipe ( ) ?;
40+ loop {
41+ match splice ( & handle. reader , & pipe_wr, MAX_ROOTLESS_PIPE_SIZE ) {
42+ Ok ( n) => {
43+ if n == 0 {
44+ return Ok ( false ) ;
45+ }
46+ if splice_exact ( & pipe_rd, write_fd, n) . is_err ( ) {
47+ // If the first splice manages to copy to the intermediate
48+ // pipe, but the second splice to stdout fails for some reason
49+ // we can recover by copying the data that we have from the
50+ // intermediate pipe to stdout using normal read/write. Then
51+ // we tell the caller to fall back.
52+ copy_exact ( & pipe_rd, write_fd, n) ?;
53+ return Ok ( true ) ;
54+ }
3955 }
40- if splice_exact ( & pipe_rd, write_fd, n) . is_err ( ) {
41- // If the first splice manages to copy to the intermediate
42- // pipe, but the second splice to stdout fails for some reason
43- // we can recover by copying the data that we have from the
44- // intermediate pipe to stdout using normal read/write. Then
45- // we tell the caller to fall back.
46- copy_exact ( & pipe_rd, write_fd, n) ?;
56+ Err ( _) => {
4757 return Ok ( true ) ;
4858 }
4959 }
50- Err ( _) => {
51- return Ok ( true ) ;
52- }
5360 }
5461 }
5562}
0 commit comments