github.com/ghodss/etcd@v0.3.1-0.20140417172404-cc329bfa55cb/pkg/btrfs/btrfs.go (about) 1 package btrfs 2 3 import ( 4 "fmt" 5 "os" 6 "runtime" 7 "syscall" 8 "unsafe" 9 10 "github.com/coreos/etcd/log" 11 ) 12 13 const ( 14 // from Linux/include/uapi/linux/magic.h 15 BTRFS_SUPER_MAGIC = 0x9123683E 16 17 // from Linux/include/uapi/linux/fs.h 18 FS_NOCOW_FL = 0x00800000 19 FS_IOC_GETFLAGS = 0x80086601 20 FS_IOC_SETFLAGS = 0x40086602 21 ) 22 23 // IsBtrfs checks whether the file is in btrfs 24 func IsBtrfs(path string) bool { 25 // btrfs is linux-only filesystem 26 // exit on other platforms 27 if runtime.GOOS != "linux" { 28 return false 29 } 30 var buf syscall.Statfs_t 31 if err := syscall.Statfs(path, &buf); err != nil { 32 log.Warnf("Failed to statfs: %v", err) 33 return false 34 } 35 log.Debugf("The type of path %v is %v", path, buf.Type) 36 if buf.Type != BTRFS_SUPER_MAGIC { 37 return false 38 } 39 log.Infof("The path %v is in btrfs", path) 40 return true 41 } 42 43 // SetNOCOWFile sets NOCOW flag for file 44 func SetNOCOWFile(path string) error { 45 file, err := os.Open(path) 46 if err != nil { 47 return err 48 } 49 defer file.Close() 50 51 fileinfo, err := file.Stat() 52 if err != nil { 53 return err 54 } 55 if fileinfo.IsDir() { 56 return fmt.Errorf("skip directory") 57 } 58 if fileinfo.Size() != 0 { 59 return fmt.Errorf("skip nonempty file") 60 } 61 62 var attr int 63 if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, file.Fd(), FS_IOC_GETFLAGS, uintptr(unsafe.Pointer(&attr))); errno != 0 { 64 return errno 65 } 66 attr |= FS_NOCOW_FL 67 if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, file.Fd(), FS_IOC_SETFLAGS, uintptr(unsafe.Pointer(&attr))); errno != 0 { 68 return errno 69 } 70 log.Infof("Set NOCOW to path %v succeeded", path) 71 return nil 72 }