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.

167 lines
3.6 KiB

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/glog"
  4. "github.com/chrislusf/seaweedfs/weed/util"
  5. "sync"
  6. )
  7. type InodeToPath struct {
  8. sync.RWMutex
  9. nextInodeId uint64
  10. inode2path map[uint64]*InodeEntry
  11. path2inode map[util.FullPath]uint64
  12. }
  13. type InodeEntry struct {
  14. util.FullPath
  15. nlookup uint64
  16. isDirectory bool
  17. isChildrenCached bool
  18. }
  19. func NewInodeToPath() *InodeToPath {
  20. t := &InodeToPath{
  21. inode2path: make(map[uint64]*InodeEntry),
  22. path2inode: make(map[util.FullPath]uint64),
  23. nextInodeId: 2, // the root inode id is 1
  24. }
  25. t.inode2path[1] = &InodeEntry{"/", 1, true, false}
  26. t.path2inode["/"] = 1
  27. return t
  28. }
  29. func (i *InodeToPath) Lookup(path util.FullPath, isDirectory bool, isLookup bool) uint64 {
  30. i.Lock()
  31. defer i.Unlock()
  32. inode, found := i.path2inode[path]
  33. if !found {
  34. inode = i.nextInodeId
  35. i.nextInodeId++
  36. i.path2inode[path] = inode
  37. if !isLookup {
  38. i.inode2path[inode] = &InodeEntry{path, 0, isDirectory, false}
  39. } else {
  40. i.inode2path[inode] = &InodeEntry{path, 1, isDirectory, false}
  41. }
  42. } else {
  43. if isLookup {
  44. i.inode2path[inode].nlookup++
  45. }
  46. }
  47. return inode
  48. }
  49. func (i *InodeToPath) GetInode(path util.FullPath) uint64 {
  50. if path == "/" {
  51. return 1
  52. }
  53. i.Lock()
  54. defer i.Unlock()
  55. inode, found := i.path2inode[path]
  56. if !found {
  57. // glog.Fatalf("GetInode unknown inode for %s", path)
  58. // this could be the parent for mount point
  59. }
  60. return inode
  61. }
  62. func (i *InodeToPath) GetPath(inode uint64) util.FullPath {
  63. i.RLock()
  64. defer i.RUnlock()
  65. path, found := i.inode2path[inode]
  66. if !found {
  67. glog.Fatalf("not found inode %d", inode)
  68. }
  69. return path.FullPath
  70. }
  71. func (i *InodeToPath) HasPath(path util.FullPath) bool {
  72. i.RLock()
  73. defer i.RUnlock()
  74. _, found := i.path2inode[path]
  75. return found
  76. }
  77. func (i *InodeToPath) MarkChildrenCached(fullpath util.FullPath) {
  78. i.RLock()
  79. defer i.RUnlock()
  80. inode, found := i.path2inode[fullpath]
  81. if !found {
  82. glog.Fatalf("MarkChildrenCached not found inode %v", fullpath)
  83. }
  84. path, found := i.inode2path[inode]
  85. path.isChildrenCached = true
  86. }
  87. func (i *InodeToPath) IsChildrenCached(fullpath util.FullPath) bool {
  88. i.RLock()
  89. defer i.RUnlock()
  90. inode, found := i.path2inode[fullpath]
  91. if !found {
  92. return false
  93. }
  94. path, found := i.inode2path[inode]
  95. if found {
  96. return path.isChildrenCached
  97. }
  98. return false
  99. }
  100. func (i *InodeToPath) HasInode(inode uint64) bool {
  101. if inode == 1 {
  102. return true
  103. }
  104. i.RLock()
  105. defer i.RUnlock()
  106. _, found := i.inode2path[inode]
  107. return found
  108. }
  109. func (i *InodeToPath) RemovePath(path util.FullPath) {
  110. i.Lock()
  111. defer i.Unlock()
  112. inode, found := i.path2inode[path]
  113. if found {
  114. delete(i.path2inode, path)
  115. delete(i.inode2path, inode)
  116. }
  117. }
  118. func (i *InodeToPath) MovePath(sourcePath, targetPath util.FullPath) {
  119. i.Lock()
  120. defer i.Unlock()
  121. sourceInode, sourceFound := i.path2inode[sourcePath]
  122. targetInode, targetFound := i.path2inode[targetPath]
  123. if sourceFound {
  124. delete(i.path2inode, sourcePath)
  125. i.path2inode[targetPath] = sourceInode
  126. } else {
  127. // it is possible some source folder items has not been visited before
  128. // so no need to worry about their source inodes
  129. return
  130. }
  131. i.inode2path[sourceInode].FullPath = targetPath
  132. if targetFound {
  133. delete(i.inode2path, targetInode)
  134. } else {
  135. i.inode2path[sourceInode].nlookup++
  136. }
  137. }
  138. func (i *InodeToPath) Forget(inode, nlookup uint64, onForgetDir func(dir util.FullPath)) {
  139. i.Lock()
  140. path, found := i.inode2path[inode]
  141. if found {
  142. path.nlookup -= nlookup
  143. if path.nlookup <= 0 {
  144. delete(i.path2inode, path.FullPath)
  145. delete(i.inode2path, inode)
  146. }
  147. }
  148. i.Unlock()
  149. if found {
  150. if path.isDirectory && onForgetDir != nil {
  151. onForgetDir(path.FullPath)
  152. }
  153. }
  154. }