From fc85f50a2be9ba8776547de9db02c5373719eb13 Mon Sep 17 00:00:00 2001 From: Daniel Hiltgen Date: Tue, 6 Aug 2024 10:46:31 -0700 Subject: [PATCH] Ensure sparse files on windows during download The file.Truncate call on windows will write the whole file unless you set the sparse flag, leading to heavy I/O at the beginning of download. This should improve our I/O behavior on windows and put less stress on the users disk. --- server/download.go | 3 +++ server/sparse_common.go | 9 +++++++++ server/sparse_windows.go | 16 ++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 server/sparse_common.go create mode 100644 server/sparse_windows.go diff --git a/server/download.go b/server/download.go index a903d96f..38d24a6b 100644 --- a/server/download.go +++ b/server/download.go @@ -216,6 +216,9 @@ func (b *blobDownload) run(ctx context.Context, requestURL *url.URL, opts *regis return err } defer file.Close() + if err := setSparse(file); err != nil { + return err + } _ = file.Truncate(b.Total) diff --git a/server/sparse_common.go b/server/sparse_common.go new file mode 100644 index 00000000..f25627fc --- /dev/null +++ b/server/sparse_common.go @@ -0,0 +1,9 @@ +//go:build !windows + +package server + +import "os" + +func setSparse(file *os.File) error { + return nil +} diff --git a/server/sparse_windows.go b/server/sparse_windows.go new file mode 100644 index 00000000..cdad379e --- /dev/null +++ b/server/sparse_windows.go @@ -0,0 +1,16 @@ +package server + +import ( + "os" + + "golang.org/x/sys/windows" +) + +func setSparse(file *os.File) error { + return windows.DeviceIoControl( + windows.Handle(file.Fd()), windows.FSCTL_SET_SPARSE, + nil, 0, + nil, 0, + nil, nil, + ) +}