diff --git a/backend/local/local.go b/backend/local/local.go index 7721d1edf..5e5369e74 100644 --- a/backend/local/local.go +++ b/backend/local/local.go @@ -1068,6 +1068,12 @@ func (f *Fs) OpenWriterAt(ctx context.Context, remote string, size int64) (fs.Wr if err != nil { fs.Debugf(o, "Failed to pre-allocate: %v", err) } + // Set the file to be a sparse file (important on Windows) + err = setSparse(out) + if err != nil { + fs.Debugf(o, "Failed to set sparse: %v", err) + } + return out, nil } diff --git a/backend/local/preallocate_other.go b/backend/local/preallocate_other.go index fb71cad59..5738b485c 100644 --- a/backend/local/preallocate_other.go +++ b/backend/local/preallocate_other.go @@ -8,3 +8,8 @@ import "os" func preAllocate(size int64, out *os.File) error { return nil } + +// setSparse makes the file be a sparse file +func setSparse(out *os.File) error { + return nil +} diff --git a/backend/local/preallocate_unix.go b/backend/local/preallocate_unix.go index 5caf6c1e4..e7472f6a7 100644 --- a/backend/local/preallocate_unix.go +++ b/backend/local/preallocate_unix.go @@ -44,3 +44,8 @@ again: // } return err } + +// setSparse makes the file be a sparse file +func setSparse(out *os.File) error { + return nil +} diff --git a/backend/local/preallocate_windows.go b/backend/local/preallocate_windows.go index dfd88369d..a434272f7 100644 --- a/backend/local/preallocate_windows.go +++ b/backend/local/preallocate_windows.go @@ -77,3 +77,16 @@ func preAllocate(size int64, out *os.File) error { return nil } + +const ( + FSCTL_SET_SPARSE = 0x000900c4 +) + +// setSparse makes the file be a sparse file +func setSparse(out *os.File) error { + err := syscall.DeviceIoControl(syscall.Handle(out.Fd()), FSCTL_SET_SPARSE, nil, 0, nil, 0, nil, nil) + if err != nil { + return errors.Wrap(err, "DeviceIoControl FSCTL_SET_SPARSE") + } + return nil +}