btrfs_linux.go 1.6 KB

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