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.

144 lines
2.8 KiB

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