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.

211 lines
5.3 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/glog"
  5. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  6. "github.com/hanwen/go-fuse/v2/fuse"
  7. "os"
  8. "syscall"
  9. "time"
  10. )
  11. func (wfs *WFS) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *fuse.AttrOut) (code fuse.Status) {
  12. if input.NodeId == 1 {
  13. wfs.setRootAttr(out)
  14. return fuse.OK
  15. }
  16. _, _, entry, status := wfs.maybeReadEntry(input.NodeId)
  17. if status != fuse.OK {
  18. return status
  19. }
  20. out.AttrValid = 1
  21. wfs.setAttrByPbEntry(&out.Attr, input.NodeId, entry)
  22. return fuse.OK
  23. }
  24. func (wfs *WFS) SetAttr(cancel <-chan struct{}, input *fuse.SetAttrIn, out *fuse.AttrOut) (code fuse.Status) {
  25. path, fh, entry, status := wfs.maybeReadEntry(input.NodeId)
  26. if status != fuse.OK {
  27. return status
  28. }
  29. if size, ok := input.GetSize(); ok {
  30. glog.V(4).Infof("%v setattr set size=%v chunks=%d", path, size, len(entry.Chunks))
  31. if size < filer.FileSize(entry) {
  32. // fmt.Printf("truncate %v \n", fullPath)
  33. var chunks []*filer_pb.FileChunk
  34. var truncatedChunks []*filer_pb.FileChunk
  35. for _, chunk := range entry.Chunks {
  36. int64Size := int64(chunk.Size)
  37. if chunk.Offset+int64Size > int64(size) {
  38. // this chunk is truncated
  39. int64Size = int64(size) - chunk.Offset
  40. if int64Size > 0 {
  41. chunks = append(chunks, chunk)
  42. glog.V(4).Infof("truncated chunk %+v from %d to %d\n", chunk.GetFileIdString(), chunk.Size, int64Size)
  43. chunk.Size = uint64(int64Size)
  44. } else {
  45. glog.V(4).Infof("truncated whole chunk %+v\n", chunk.GetFileIdString())
  46. truncatedChunks = append(truncatedChunks, chunk)
  47. }
  48. }
  49. }
  50. // set the new chunks and reset entry cache
  51. entry.Chunks = chunks
  52. if fh != nil {
  53. fh.entryViewCache = nil
  54. }
  55. }
  56. entry.Attributes.Mtime = time.Now().Unix()
  57. entry.Attributes.FileSize = size
  58. }
  59. if mode, ok := input.GetMode(); ok {
  60. entry.Attributes.FileMode = mode & 07777
  61. }
  62. if uid, ok := input.GetUID(); ok {
  63. entry.Attributes.Uid = uid
  64. }
  65. if gid, ok := input.GetGID(); ok {
  66. entry.Attributes.Gid = gid
  67. }
  68. if mtime, ok := input.GetMTime(); ok {
  69. entry.Attributes.Mtime = mtime.Unix()
  70. }
  71. if atime, ok := input.GetATime(); ok {
  72. entry.Attributes.Mtime = atime.Unix()
  73. }
  74. entry.Attributes.Mtime = time.Now().Unix()
  75. out.AttrValid = 1
  76. wfs.setAttrByPbEntry(&out.Attr, input.NodeId, entry)
  77. if fh != nil {
  78. fh.dirtyMetadata = true
  79. return fuse.OK
  80. }
  81. return wfs.saveEntry(path, entry)
  82. }
  83. func (wfs *WFS) setRootAttr(out *fuse.AttrOut) {
  84. now := uint64(time.Now().Unix())
  85. out.AttrValid = 119
  86. out.Ino = 1
  87. setBlksize(&out.Attr, blockSize)
  88. out.Uid = wfs.option.MountUid
  89. out.Gid = wfs.option.MountGid
  90. out.Mtime = now
  91. out.Ctime = now
  92. out.Atime = now
  93. out.Mode = toSystemType(os.ModeDir) | uint32(wfs.option.MountMode)
  94. out.Nlink = 1
  95. }
  96. func (wfs *WFS) setAttrByPbEntry(out *fuse.Attr, inode uint64, entry *filer_pb.Entry) {
  97. out.Ino = inode
  98. out.Size = filer.FileSize(entry)
  99. out.Blocks = (out.Size + blockSize - 1) / blockSize
  100. setBlksize(out, blockSize)
  101. out.Mtime = uint64(entry.Attributes.Mtime)
  102. out.Ctime = uint64(entry.Attributes.Mtime)
  103. out.Atime = uint64(entry.Attributes.Mtime)
  104. out.Mode = toSystemMode(os.FileMode(entry.Attributes.FileMode))
  105. if entry.HardLinkCounter > 0 {
  106. out.Nlink = uint32(entry.HardLinkCounter)
  107. } else {
  108. out.Nlink = 1
  109. }
  110. out.Uid = entry.Attributes.Uid
  111. out.Gid = entry.Attributes.Gid
  112. }
  113. func (wfs *WFS) setAttrByFilerEntry(out *fuse.Attr, inode uint64, entry *filer.Entry) {
  114. out.Ino = inode
  115. out.Size = entry.FileSize
  116. out.Blocks = (out.Size + blockSize - 1) / blockSize
  117. setBlksize(out, blockSize)
  118. out.Atime = uint64(entry.Attr.Mtime.Unix())
  119. out.Mtime = uint64(entry.Attr.Mtime.Unix())
  120. out.Ctime = uint64(entry.Attr.Mtime.Unix())
  121. out.Mode = toSystemMode(entry.Attr.Mode)
  122. if entry.HardLinkCounter > 0 {
  123. out.Nlink = uint32(entry.HardLinkCounter)
  124. } else {
  125. out.Nlink = 1
  126. }
  127. out.Uid = entry.Attr.Uid
  128. out.Gid = entry.Attr.Gid
  129. }
  130. func (wfs *WFS) outputPbEntry(out *fuse.EntryOut, inode uint64, entry *filer_pb.Entry) {
  131. out.NodeId = inode
  132. out.Generation = 1
  133. out.EntryValid = 1
  134. out.AttrValid = 1
  135. wfs.setAttrByPbEntry(&out.Attr, inode, entry)
  136. }
  137. func (wfs *WFS) outputFilerEntry(out *fuse.EntryOut, inode uint64, entry *filer.Entry) {
  138. out.NodeId = inode
  139. out.Generation = 1
  140. out.EntryValid = 1
  141. out.AttrValid = 1
  142. wfs.setAttrByFilerEntry(&out.Attr, inode, entry)
  143. }
  144. func toSystemMode(mode os.FileMode) uint32 {
  145. return toSystemType(mode) | uint32(mode)
  146. }
  147. func toSystemType(mode os.FileMode) uint32 {
  148. switch mode & os.ModeType {
  149. case os.ModeDir:
  150. return syscall.S_IFDIR
  151. case os.ModeSymlink:
  152. return syscall.S_IFLNK
  153. case os.ModeNamedPipe:
  154. return syscall.S_IFIFO
  155. case os.ModeSocket:
  156. return syscall.S_IFSOCK
  157. case os.ModeDevice:
  158. return syscall.S_IFBLK
  159. case os.ModeCharDevice:
  160. return syscall.S_IFCHR
  161. default:
  162. return syscall.S_IFREG
  163. }
  164. }
  165. func toFileType(mode uint32) os.FileMode {
  166. switch mode & (syscall.S_IFMT & 0xffff) {
  167. case syscall.S_IFDIR:
  168. return os.ModeDir
  169. case syscall.S_IFLNK:
  170. return os.ModeSymlink
  171. case syscall.S_IFIFO:
  172. return os.ModeNamedPipe
  173. case syscall.S_IFSOCK:
  174. return os.ModeSocket
  175. case syscall.S_IFBLK:
  176. return os.ModeDevice
  177. case syscall.S_IFCHR:
  178. return os.ModeCharDevice
  179. default:
  180. return 0
  181. }
  182. }
  183. func toFileMode(mode uint32) os.FileMode {
  184. return toFileType(mode) | os.FileMode(mode&07777)
  185. }