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.

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