You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
4.2 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package mount
  2. import (
  3. "github.com/chrislusf/seaweedfs/weed/filer"
  4. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  5. "github.com/hanwen/go-fuse/v2/fuse"
  6. "os"
  7. "syscall"
  8. "time"
  9. )
  10. func (wfs *WFS) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *fuse.AttrOut) (code fuse.Status) {
  11. if input.NodeId == 1 {
  12. wfs.setRootAttr(out)
  13. return fuse.OK
  14. }
  15. _, entry, status := wfs.maybeReadEntry(input.NodeId)
  16. if status != fuse.OK {
  17. return status
  18. }
  19. out.AttrValid = 1
  20. wfs.setAttrByPbEntry(&out.Attr, input.NodeId, entry)
  21. return fuse.OK
  22. }
  23. func (wfs *WFS) SetAttr(cancel <-chan struct{}, input *fuse.SetAttrIn, out *fuse.AttrOut) (code fuse.Status) {
  24. // TODO this is only for directory. Filet setAttr involves open files and truncate to a size
  25. path, entry, status := wfs.maybeReadEntry(input.NodeId)
  26. if status != fuse.OK {
  27. return status
  28. }
  29. if mode, ok := input.GetMode(); ok {
  30. entry.Attributes.FileMode = uint32(mode)
  31. }
  32. if uid, ok := input.GetUID(); ok {
  33. entry.Attributes.Uid = uid
  34. }
  35. if gid, ok := input.GetGID(); ok {
  36. entry.Attributes.Gid = gid
  37. }
  38. if mtime, ok := input.GetMTime(); ok {
  39. entry.Attributes.Mtime = mtime.Unix()
  40. }
  41. entry.Attributes.Mtime = time.Now().Unix()
  42. out.AttrValid = 1
  43. wfs.setAttrByPbEntry(&out.Attr, input.NodeId, entry)
  44. return wfs.saveEntry(path, entry)
  45. }
  46. func (wfs *WFS) setRootAttr(out *fuse.AttrOut) {
  47. now := uint64(time.Now().Unix())
  48. out.AttrValid = 119
  49. out.Ino = 1
  50. setBlksize(&out.Attr, blockSize)
  51. out.Uid = wfs.option.MountUid
  52. out.Gid = wfs.option.MountGid
  53. out.Mtime = now
  54. out.Ctime = now
  55. out.Atime = now
  56. out.Mode = toSystemType(os.ModeDir) | uint32(wfs.option.MountMode)
  57. out.Nlink = 1
  58. }
  59. func (wfs *WFS) setAttrByPbEntry(out *fuse.Attr, inode uint64, entry *filer_pb.Entry) {
  60. out.Ino = inode
  61. out.Size = filer.FileSize(entry)
  62. out.Blocks = (out.Size + blockSize - 1) / blockSize
  63. setBlksize(out, blockSize)
  64. out.Mtime = uint64(entry.Attributes.Mtime)
  65. out.Ctime = uint64(entry.Attributes.Mtime)
  66. out.Atime = uint64(entry.Attributes.Mtime)
  67. out.Mode = toSystemMode(os.FileMode(entry.Attributes.FileMode))
  68. if entry.HardLinkCounter > 0 {
  69. out.Nlink = uint32(entry.HardLinkCounter)
  70. } else {
  71. out.Nlink = 1
  72. }
  73. out.Uid = entry.Attributes.Uid
  74. out.Gid = entry.Attributes.Gid
  75. }
  76. func (wfs *WFS) setAttrByFilerEntry(out *fuse.Attr, inode uint64, entry *filer.Entry) {
  77. out.Ino = inode
  78. out.Size = entry.FileSize
  79. out.Blocks = (out.Size + blockSize - 1) / blockSize
  80. setBlksize(out, blockSize)
  81. out.Atime = uint64(entry.Attr.Mtime.Unix())
  82. out.Mtime = uint64(entry.Attr.Mtime.Unix())
  83. out.Ctime = uint64(entry.Attr.Mtime.Unix())
  84. out.Crtime_ = uint64(entry.Attr.Crtime.Unix())
  85. out.Mode = toSystemMode(entry.Attr.Mode)
  86. if entry.HardLinkCounter > 0 {
  87. out.Nlink = uint32(entry.HardLinkCounter)
  88. } else {
  89. out.Nlink = 1
  90. }
  91. out.Uid = entry.Attr.Uid
  92. out.Gid = entry.Attr.Gid
  93. }
  94. func (wfs *WFS) outputPbEntry(out *fuse.EntryOut, inode uint64, entry *filer_pb.Entry) {
  95. out.NodeId = inode
  96. out.Generation = 1
  97. out.EntryValid = 1
  98. out.AttrValid = 1
  99. wfs.setAttrByPbEntry(&out.Attr, inode, entry)
  100. }
  101. func (wfs *WFS) outputFilerEntry(out *fuse.EntryOut, inode uint64, entry *filer.Entry) {
  102. out.NodeId = inode
  103. out.Generation = 1
  104. out.EntryValid = 1
  105. out.AttrValid = 1
  106. wfs.setAttrByFilerEntry(&out.Attr, inode, entry)
  107. }
  108. func toSystemMode(mode os.FileMode) uint32 {
  109. return toSystemType(mode) | uint32(mode)
  110. }
  111. func toSystemType(mode os.FileMode) uint32 {
  112. switch mode & os.ModeType {
  113. case os.ModeDir:
  114. return syscall.S_IFDIR
  115. case os.ModeSymlink:
  116. return syscall.S_IFLNK
  117. case os.ModeNamedPipe:
  118. return syscall.S_IFIFO
  119. case os.ModeSocket:
  120. return syscall.S_IFSOCK
  121. case os.ModeDevice:
  122. return syscall.S_IFBLK
  123. case os.ModeCharDevice:
  124. return syscall.S_IFCHR
  125. default:
  126. return syscall.S_IFREG
  127. }
  128. }
  129. func toFileType(mode uint32) os.FileMode {
  130. switch mode & (syscall.S_IFMT & 0xffff) {
  131. case syscall.S_IFDIR:
  132. return os.ModeDir
  133. case syscall.S_IFLNK:
  134. return os.ModeSymlink
  135. case syscall.S_IFIFO:
  136. return os.ModeNamedPipe
  137. case syscall.S_IFSOCK:
  138. return os.ModeSocket
  139. case syscall.S_IFBLK:
  140. return os.ModeDevice
  141. case syscall.S_IFCHR:
  142. return os.ModeCharDevice
  143. default:
  144. return 0
  145. }
  146. }
  147. func toFileMode(mode uint32) os.FileMode {
  148. return toFileType(mode) | os.FileMode(mode&07777)
  149. }