github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/backend/local/preallocate_unix.go (about) 1 //+build linux 2 3 package local 4 5 import ( 6 "os" 7 "sync/atomic" 8 9 "github.com/ncw/rclone/fs" 10 "golang.org/x/sys/unix" 11 ) 12 13 var ( 14 fallocFlags = [...]uint32{ 15 unix.FALLOC_FL_KEEP_SIZE, // Default 16 unix.FALLOC_FL_KEEP_SIZE | unix.FALLOC_FL_PUNCH_HOLE, // for ZFS #3066 17 } 18 fallocFlagsIndex int32 19 ) 20 21 // preAllocate the file for performance reasons 22 func preAllocate(size int64, out *os.File) error { 23 if size <= 0 { 24 return nil 25 } 26 index := atomic.LoadInt32(&fallocFlagsIndex) 27 again: 28 if index >= int32(len(fallocFlags)) { 29 return nil // Fallocate is disabled 30 } 31 flags := fallocFlags[index] 32 err := unix.Fallocate(int(out.Fd()), flags, 0, size) 33 if err == unix.ENOTSUP { 34 // Try the next flags combination 35 index++ 36 atomic.StoreInt32(&fallocFlagsIndex, index) 37 fs.Debugf(nil, "preAllocate: got error on fallocate, trying combination %d/%d: %v", index, len(fallocFlags), err) 38 goto again 39 40 } 41 // FIXME could be doing something here 42 // if err == unix.ENOSPC { 43 // log.Printf("No space") 44 // } 45 return err 46 }