1 // Copyright 2016 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build darwin 16 // +build darwin 17 18 package fileutil 19 20 import ( 21 "os" 22 "syscall" 23 24 "golang.org/x/sys/unix" 25 ) 26 27 func preallocExtend(f *os.File, sizeInBytes int64) error { 28 if err := preallocFixed(f, sizeInBytes); err != nil { 29 return err 30 } 31 return preallocExtendTrunc(f, sizeInBytes) 32 } 33 34 func preallocFixed(f *os.File, sizeInBytes int64) error { 35 // allocate all requested space or no space at all 36 // TODO: allocate contiguous space on disk with F_ALLOCATECONTIG flag 37 fstore := &unix.Fstore_t{ 38 Flags: unix.F_ALLOCATEALL, 39 Posmode: unix.F_PEOFPOSMODE, 40 Length: sizeInBytes, 41 } 42 err := unix.FcntlFstore(f.Fd(), unix.F_PREALLOCATE, fstore) 43 if err == nil || err == unix.ENOTSUP { 44 return nil 45 } 46 47 // wrong argument to fallocate syscall 48 if err == unix.EINVAL { 49 // filesystem "st_blocks" are allocated in the units of 50 // "Allocation Block Size" (run "diskutil info /" command) 51 var stat syscall.Stat_t 52 syscall.Fstat(int(f.Fd()), &stat) 53 54 // syscall.Statfs_t.Bsize is "optimal transfer block size" 55 // and contains matching 4096 value when latest OS X kernel 56 // supports 4,096 KB filesystem block size 57 var statfs syscall.Statfs_t 58 syscall.Fstatfs(int(f.Fd()), &statfs) 59 blockSize := int64(statfs.Bsize) 60 61 if stat.Blocks*blockSize >= sizeInBytes { 62 // enough blocks are already allocated 63 return nil 64 } 65 } 66 return err 67 } 68