From 0be4dfbc199c75183bdd10d1e1dbb10184d5608e Mon Sep 17 00:00:00 2001 From: Wei Fu Date: Fri, 9 Jun 2023 14:00:54 +0800 Subject: [PATCH] fs: use io.Copy because go supports CopyFileRange REF: https://github.com/golang/go/commit/7be3f09deb2dc1d57cfc18b18e12192be3544794 Signed-off-by: Wei Fu --- fs/copy.go | 17 ++++++++++++++++- fs/copy_linux.go | 46 ---------------------------------------------- fs/copy_unix.go | 9 --------- fs/copy_windows.go | 8 -------- 4 files changed, 16 insertions(+), 64 deletions(-) diff --git a/fs/copy.go b/fs/copy.go index a1cae0f9..c4ba8c52 100644 --- a/fs/copy.go +++ b/fs/copy.go @@ -18,8 +18,10 @@ package fs import ( "fmt" + "io" "os" "path/filepath" + "runtime" "sync" "github.com/sirupsen/logrus" @@ -199,5 +201,18 @@ func openAndCopyFile(target, source string) error { } defer tgt.Close() - return copyFileContent(tgt, src) + var tgtWriter io.Writer = tgt + if runtime.GOOS != "linux" { + tgtWriter = onlyWriter{tgt} + } + + buf := bufferPool.Get().(*[]byte) + _, err = io.CopyBuffer(tgtWriter, src, *buf) + bufferPool.Put(buf) + + return err +} + +type onlyWriter struct { + io.Writer } diff --git a/fs/copy_linux.go b/fs/copy_linux.go index 1906e5e0..48ac3fbd 100644 --- a/fs/copy_linux.go +++ b/fs/copy_linux.go @@ -18,7 +18,6 @@ package fs import ( "fmt" - "io" "os" "syscall" @@ -62,51 +61,6 @@ func copyFileInfo(fi os.FileInfo, src, name string) error { return nil } -const maxSSizeT = int64(^uint(0) >> 1) - -func copyFileContent(dst, src *os.File) error { - st, err := src.Stat() - if err != nil { - return fmt.Errorf("unable to stat source: %w", err) - } - - size := st.Size() - first := true - srcFd := int(src.Fd()) - dstFd := int(dst.Fd()) - - for size > 0 { - // Ensure that we are never trying to copy more than SSIZE_MAX at a - // time and at the same time avoids overflows when the file is larger - // than 4GB on 32-bit systems. - var copySize int - if size > maxSSizeT { - copySize = int(maxSSizeT) - } else { - copySize = int(size) - } - n, err := unix.CopyFileRange(srcFd, nil, dstFd, nil, copySize, 0) - if err != nil { - if (err != unix.ENOSYS && err != unix.EXDEV) || !first { - return fmt.Errorf("copy file range failed: %w", err) - } - - buf := bufferPool.Get().(*[]byte) - _, err = io.CopyBuffer(dst, src, *buf) - bufferPool.Put(buf) - if err != nil { - return fmt.Errorf("userspace copy failed: %w", err) - } - return nil - } - - first = false - size -= int64(n) - } - - return nil -} - func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error { xattrKeys, err := sysx.LListxattr(src) if err != nil { diff --git a/fs/copy_unix.go b/fs/copy_unix.go index dd957872..1311250e 100644 --- a/fs/copy_unix.go +++ b/fs/copy_unix.go @@ -21,7 +21,6 @@ package fs import ( "fmt" - "io" "os" "runtime" "syscall" @@ -61,14 +60,6 @@ func copyFileInfo(fi os.FileInfo, src, name string) error { return nil } -func copyFileContent(dst, src *os.File) error { - buf := bufferPool.Get().(*[]byte) - _, err := io.CopyBuffer(dst, src, *buf) - bufferPool.Put(buf) - - return err -} - func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error { xattrKeys, err := sysx.LListxattr(src) if err != nil { diff --git a/fs/copy_windows.go b/fs/copy_windows.go index 6ec13b98..1fad4c3a 100644 --- a/fs/copy_windows.go +++ b/fs/copy_windows.go @@ -19,7 +19,6 @@ package fs import ( "errors" "fmt" - "io" "os" winio "github.com/Microsoft/go-winio" @@ -72,13 +71,6 @@ func copyFileInfo(fi os.FileInfo, src, name string) error { return nil } -func copyFileContent(dst, src *os.File) error { - buf := bufferPool.Get().(*[]byte) - _, err := io.CopyBuffer(dst, src, *buf) - bufferPool.Put(buf) - return err -} - func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error { return nil }