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.

213 lines
3.6 KiB

4 years ago
4 years ago
4 years ago
4 years ago
  1. package filesys
  2. import (
  3. "sync"
  4. "github.com/seaweedfs/fuse/fs"
  5. "github.com/chrislusf/seaweedfs/weed/util"
  6. )
  7. type FsCache struct {
  8. root *FsNode
  9. sync.RWMutex
  10. }
  11. type FsNode struct {
  12. parent *FsNode
  13. node fs.Node
  14. name string
  15. childrenLock sync.RWMutex
  16. children map[string]*FsNode
  17. }
  18. func newFsCache(root fs.Node) *FsCache {
  19. return &FsCache{
  20. root: &FsNode{
  21. node: root,
  22. },
  23. }
  24. }
  25. func (c *FsCache) GetFsNode(path util.FullPath) fs.Node {
  26. c.RLock()
  27. defer c.RUnlock()
  28. return c.doGetFsNode(path)
  29. }
  30. func (c *FsCache) doGetFsNode(path util.FullPath) fs.Node {
  31. t := c.root
  32. for _, p := range path.Split() {
  33. t = t.findChild(p)
  34. if t == nil {
  35. return nil
  36. }
  37. }
  38. return t.node
  39. }
  40. func (c *FsCache) SetFsNode(path util.FullPath, node fs.Node) {
  41. c.Lock()
  42. defer c.Unlock()
  43. c.doSetFsNode(path, node)
  44. }
  45. func (c *FsCache) doSetFsNode(path util.FullPath, node fs.Node) {
  46. t := c.root
  47. for _, p := range path.Split() {
  48. t = t.ensureChild(p)
  49. }
  50. t.node = node
  51. }
  52. func (c *FsCache) EnsureFsNode(path util.FullPath, genNodeFn func() fs.Node) fs.Node {
  53. c.Lock()
  54. defer c.Unlock()
  55. t := c.doGetFsNode(path)
  56. if t != nil {
  57. return t
  58. }
  59. t = genNodeFn()
  60. c.doSetFsNode(path, t)
  61. return t
  62. }
  63. func (c *FsCache) DeleteFsNode(path util.FullPath) {
  64. c.Lock()
  65. defer c.Unlock()
  66. t := c.root
  67. for _, p := range path.Split() {
  68. t = t.findChild(p)
  69. if t == nil {
  70. return
  71. }
  72. }
  73. if t.parent != nil {
  74. t.parent.disconnectChild(t)
  75. }
  76. t.deleteSelf()
  77. }
  78. // oldPath and newPath are full path including the new name
  79. func (c *FsCache) Move(oldPath util.FullPath, newPath util.FullPath) *FsNode {
  80. c.Lock()
  81. defer c.Unlock()
  82. // find old node
  83. src := c.root
  84. for _, p := range oldPath.Split() {
  85. src = src.findChild(p)
  86. if src == nil {
  87. return src
  88. }
  89. }
  90. if src.parent != nil {
  91. src.parent.disconnectChild(src)
  92. }
  93. // find new node
  94. target := c.root
  95. for _, p := range newPath.Split() {
  96. target = target.ensureChild(p)
  97. }
  98. parent := target.parent
  99. if dir, ok := src.node.(*Dir); ok {
  100. dir.name = target.name // target is not Dir, but a shortcut
  101. }
  102. if f, ok := src.node.(*File); ok {
  103. f.Name = target.name
  104. entry := f.getEntry()
  105. if entry != nil {
  106. entry.Name = f.Name
  107. }
  108. }
  109. parent.disconnectChild(target)
  110. target.deleteSelf()
  111. src.name = target.name
  112. src.connectToParent(parent)
  113. return src
  114. }
  115. func (n *FsNode) connectToParent(parent *FsNode) {
  116. n.parent = parent
  117. oldNode := parent.findChild(n.name)
  118. if oldNode != nil {
  119. oldNode.deleteSelf()
  120. }
  121. if dir, ok := n.node.(*Dir); ok {
  122. if parent.node != nil {
  123. dir.parent = parent.node.(*Dir)
  124. }
  125. }
  126. if f, ok := n.node.(*File); ok {
  127. if parent.node != nil {
  128. f.dir = parent.node.(*Dir)
  129. }
  130. }
  131. n.childrenLock.Lock()
  132. parent.children[n.name] = n
  133. n.childrenLock.Unlock()
  134. }
  135. func (n *FsNode) findChild(name string) *FsNode {
  136. n.childrenLock.RLock()
  137. defer n.childrenLock.RUnlock()
  138. child, found := n.children[name]
  139. if found {
  140. return child
  141. }
  142. return nil
  143. }
  144. func (n *FsNode) ensureChild(name string) *FsNode {
  145. n.childrenLock.Lock()
  146. defer n.childrenLock.Unlock()
  147. if n.children == nil {
  148. n.children = make(map[string]*FsNode)
  149. }
  150. child, found := n.children[name]
  151. if found {
  152. return child
  153. }
  154. t := &FsNode{
  155. parent: n,
  156. node: nil,
  157. name: name,
  158. children: nil,
  159. }
  160. n.children[name] = t
  161. return t
  162. }
  163. func (n *FsNode) disconnectChild(child *FsNode) {
  164. n.childrenLock.Lock()
  165. delete(n.children, child.name)
  166. n.childrenLock.Unlock()
  167. child.parent = nil
  168. }
  169. func (n *FsNode) deleteSelf() {
  170. n.childrenLock.Lock()
  171. for _, child := range n.children {
  172. child.deleteSelf()
  173. }
  174. n.children = nil
  175. n.childrenLock.Unlock()
  176. n.node = nil
  177. n.parent = nil
  178. }