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.

95 lines
2.6 KiB

3 years ago
3 years ago
3 years ago
3 years ago
  1. package mount
  2. import (
  3. "context"
  4. "github.com/chrislusf/seaweedfs/weed/filer"
  5. "github.com/chrislusf/seaweedfs/weed/filesys/meta_cache"
  6. "github.com/chrislusf/seaweedfs/weed/glog"
  7. "github.com/chrislusf/seaweedfs/weed/util"
  8. "github.com/hanwen/go-fuse/v2/fuse"
  9. "math"
  10. "os"
  11. )
  12. // Directory handling
  13. func (wfs *WFS) OpenDir(cancel <-chan struct{}, input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.Status) {
  14. if !wfs.inodeToPath.HasInode(input.NodeId) {
  15. return fuse.ENOENT
  16. }
  17. return fuse.OK
  18. }
  19. func (wfs *WFS) ReleaseDir(input *fuse.ReleaseIn) {
  20. }
  21. func (wfs *WFS) FsyncDir(cancel <-chan struct{}, input *fuse.FsyncIn) (code fuse.Status) {
  22. return fuse.OK
  23. }
  24. func (wfs *WFS) ReadDir(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
  25. return wfs.doReadDirectory(input, out, false)
  26. }
  27. func (wfs *WFS) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
  28. return wfs.doReadDirectory(input, out, true)
  29. }
  30. func (wfs *WFS) doReadDirectory(input *fuse.ReadIn, out *fuse.DirEntryList, isPlusMode bool) fuse.Status {
  31. dirPath := wfs.inodeToPath.GetPath(input.NodeId)
  32. var counter uint64
  33. var dirEntry fuse.DirEntry
  34. if input.Offset == 0 {
  35. counter++
  36. dirEntry.Ino = input.NodeId
  37. dirEntry.Name = "."
  38. dirEntry.Mode = toSystemMode(os.ModeDir)
  39. out.AddDirEntry(dirEntry)
  40. counter++
  41. parentDir, _ := dirPath.DirAndName()
  42. parentInode := wfs.inodeToPath.GetInode(util.FullPath(parentDir))
  43. dirEntry.Ino = parentInode
  44. dirEntry.Name = ".."
  45. dirEntry.Mode = toSystemMode(os.ModeDir)
  46. out.AddDirEntry(dirEntry)
  47. }
  48. processEachEntryFn := func(entry *filer.Entry, isLast bool) bool {
  49. counter++
  50. if counter <= input.Offset {
  51. return true
  52. }
  53. dirEntry.Name = entry.Name()
  54. inode := wfs.inodeToPath.GetInode(dirPath.Child(dirEntry.Name))
  55. dirEntry.Ino = inode
  56. dirEntry.Mode = toSystemMode(entry.Mode)
  57. if !isPlusMode {
  58. if !out.AddDirEntry(dirEntry) {
  59. return false
  60. }
  61. } else {
  62. entryOut := out.AddDirLookupEntry(dirEntry)
  63. if entryOut == nil {
  64. return false
  65. }
  66. wfs.outputEntry(entryOut, inode, entry)
  67. }
  68. return true
  69. }
  70. // TODO remove this with checking whether directory is not forgotten
  71. if err := meta_cache.EnsureVisited(wfs.metaCache, wfs, dirPath); err != nil {
  72. glog.Errorf("dir ReadDirAll %s: %v", dirPath, err)
  73. return fuse.EIO
  74. }
  75. listErr := wfs.metaCache.ListDirectoryEntries(context.Background(), dirPath, "", false, int64(math.MaxInt32), func(entry *filer.Entry) bool {
  76. return processEachEntryFn(entry, false)
  77. })
  78. if listErr != nil {
  79. glog.Errorf("list meta cache: %v", listErr)
  80. return fuse.EIO
  81. }
  82. return fuse.OK
  83. }