2020-02-26 20:48:05 +00:00
|
|
|
//go:build !windows
|
|
|
|
// +build !windows
|
|
|
|
|
|
|
|
package restorer
|
|
|
|
|
2022-09-04 08:39:16 +00:00
|
|
|
import (
|
|
|
|
"github.com/restic/restic/internal/restic"
|
|
|
|
)
|
2020-02-26 20:48:05 +00:00
|
|
|
|
|
|
|
// WriteAt writes p to f.File at offset. It tries to do a sparse write
|
|
|
|
// and updates f.size.
|
|
|
|
func (f *partialFile) WriteAt(p []byte, offset int64) (n int, err error) {
|
2022-08-07 15:26:46 +00:00
|
|
|
if !f.sparse {
|
|
|
|
return f.File.WriteAt(p, offset)
|
|
|
|
}
|
|
|
|
|
2020-02-26 20:48:05 +00:00
|
|
|
n = len(p)
|
|
|
|
|
|
|
|
// Skip the longest all-zero prefix of p.
|
|
|
|
// If it's long enough, we can punch a hole in the file.
|
2022-09-04 08:39:16 +00:00
|
|
|
skipped := restic.ZeroPrefixLen(p)
|
2020-02-26 20:48:05 +00:00
|
|
|
p = p[skipped:]
|
|
|
|
offset += int64(skipped)
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case len(p) == 0:
|
|
|
|
// All zeros, file already big enough. A previous WriteAt or
|
|
|
|
// Truncate will have produced the zeros in f.File.
|
|
|
|
|
|
|
|
default:
|
2022-08-07 15:56:14 +00:00
|
|
|
var n2 int
|
|
|
|
n2, err = f.File.WriteAt(p, offset)
|
|
|
|
n = skipped + n2
|
2020-02-26 20:48:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return n, err
|
|
|
|
}
|