mirror of
https://github.com/rclone/rclone.git
synced 2024-11-26 18:34:41 +01:00
a492c0fb0e
Before this change rclone didn't use sparse files on Windows. This means that when you downloaded a file with multithread download it wrote the entire file with zeros first on the first write not at the start of the file. This change makes the file be sparse on Windows. Linux/macOS files were already sparse.
52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
//+build linux
|
|
|
|
package local
|
|
|
|
import (
|
|
"os"
|
|
"sync/atomic"
|
|
|
|
"github.com/rclone/rclone/fs"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
var (
|
|
fallocFlags = [...]uint32{
|
|
unix.FALLOC_FL_KEEP_SIZE, // Default
|
|
unix.FALLOC_FL_KEEP_SIZE | unix.FALLOC_FL_PUNCH_HOLE, // for ZFS #3066
|
|
}
|
|
fallocFlagsIndex int32
|
|
)
|
|
|
|
// preAllocate the file for performance reasons
|
|
func preAllocate(size int64, out *os.File) error {
|
|
if size <= 0 {
|
|
return nil
|
|
}
|
|
index := atomic.LoadInt32(&fallocFlagsIndex)
|
|
again:
|
|
if index >= int32(len(fallocFlags)) {
|
|
return nil // Fallocate is disabled
|
|
}
|
|
flags := fallocFlags[index]
|
|
err := unix.Fallocate(int(out.Fd()), flags, 0, size)
|
|
if err == unix.ENOTSUP {
|
|
// Try the next flags combination
|
|
index++
|
|
atomic.StoreInt32(&fallocFlagsIndex, index)
|
|
fs.Debugf(nil, "preAllocate: got error on fallocate, trying combination %d/%d: %v", index, len(fallocFlags), err)
|
|
goto again
|
|
|
|
}
|
|
// FIXME could be doing something here
|
|
// if err == unix.ENOSPC {
|
|
// log.Printf("No space")
|
|
// }
|
|
return err
|
|
}
|
|
|
|
// setSparse makes the file be a sparse file
|
|
func setSparse(out *os.File) error {
|
|
return nil
|
|
}
|