github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/lib/file/preallocate_unix.go (about) 1 //+build linux 2 3 package file 4 5 import ( 6 "os" 7 "sync/atomic" 8 9 "github.com/rclone/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 // PreallocateImplemented is a constant indicating whether the 22 // implementation of Preallocate actually does anything. 23 const PreallocateImplemented = true 24 25 // PreAllocate the file for performance reasons 26 func PreAllocate(size int64, out *os.File) error { 27 if size <= 0 { 28 return nil 29 } 30 index := atomic.LoadInt32(&fallocFlagsIndex) 31 again: 32 if index >= int32(len(fallocFlags)) { 33 return nil // Fallocate is disabled 34 } 35 flags := fallocFlags[index] 36 err := unix.Fallocate(int(out.Fd()), flags, 0, size) 37 if err == unix.ENOTSUP { 38 // Try the next flags combination 39 index++ 40 atomic.StoreInt32(&fallocFlagsIndex, index) 41 fs.Debugf(nil, "preAllocate: got error on fallocate, trying combination %d/%d: %v", index, len(fallocFlags), err) 42 goto again 43 44 } 45 // FIXME could be doing something here 46 // if err == unix.ENOSPC { 47 // log.Printf("No space") 48 // } 49 return err 50 } 51 52 // SetSparseImplemented is a constant indicating whether the 53 // implementation of SetSparse actually does anything. 54 const SetSparseImplemented = false 55 56 // SetSparse makes the file be a sparse file 57 func SetSparse(out *os.File) error { 58 return nil 59 }