//!build +unix package cowutils import ( "errors" "os" "golang.org/x/sys/unix" ) // reflink performs the actual reflink action without worrying about fallback func reflink(dst, src *os.File) error { srcFd := int(src.Fd()) dstFd := int(dst.Fd()) err := unix.IoctlFileClone(dstFd, srcFd) if err != nil && errors.Is(err, unix.ENOTSUP) { return ErrNotSupported } return err } func reflinkRange(dst, src *os.File, dstOffset, srcOffset, n int64) error { srcFd := int(src.Fd()) dstFd := int(dst.Fd()) req := &unix.FileCloneRange{ Src_fd: int64(srcFd), Src_offset: uint64(srcOffset), Src_length: uint64(n), Dest_offset: uint64(dstOffset), } err := unix.IoctlFileCloneRange(dstFd, req) if err != nil && errors.Is(err, unix.ENOTSUP) { return ErrNotSupported } return err } func copyFileRange(dst, src *os.File, dstOffset, srcOffset, n int64) (int64, error) { srcFd := int(src.Fd()) dstFd := int(dst.Fd()) resN, err := unix.CopyFileRange(srcFd, &srcOffset, dstFd, &dstOffset, int(n), 0) return int64(resN), err }