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.

93 lines
2.6 KiB

  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. return fuse.OK
  15. }
  16. func (wfs *WFS) ReleaseDir(input *fuse.ReleaseIn) {
  17. }
  18. func (wfs *WFS) FsyncDir(cancel <-chan struct{}, input *fuse.FsyncIn) (code fuse.Status) {
  19. return fuse.OK
  20. }
  21. func (wfs *WFS) ReadDir(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
  22. return wfs.doReadDirectory(input, out, false)
  23. }
  24. func (wfs *WFS) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
  25. return wfs.doReadDirectory(input, out, true)
  26. }
  27. func (wfs *WFS) doReadDirectory(input *fuse.ReadIn, out *fuse.DirEntryList, isPlusMode bool) fuse.Status {
  28. dirPath := wfs.inodeToPath.GetPath(input.NodeId)
  29. println("input size", input.Size, "offset", input.Offset, "pid", input.Caller.Pid)
  30. var dirEntry fuse.DirEntry
  31. if input.Offset == 0 {
  32. dirEntry.Ino = input.NodeId
  33. dirEntry.Name = "."
  34. dirEntry.Mode = toSystemMode(os.ModeDir)
  35. out.AddDirEntry(dirEntry)
  36. parentDir, _ := dirPath.DirAndName()
  37. parentInode := wfs.inodeToPath.GetInode(util.FullPath(parentDir))
  38. dirEntry.Ino = parentInode
  39. dirEntry.Name = ".."
  40. dirEntry.Mode = toSystemMode(os.ModeDir)
  41. out.AddDirEntry(dirEntry)
  42. }
  43. var counter uint64
  44. processEachEntryFn := func(entry *filer.Entry, isLast bool) bool {
  45. counter++
  46. if counter <= input.Offset {
  47. return true
  48. }
  49. dirEntry.Name = entry.Name()
  50. inode := wfs.inodeToPath.GetInode(dirPath.Child(dirEntry.Name))
  51. println("entry", dirEntry.Name, "inode", inode)
  52. dirEntry.Ino = inode
  53. dirEntry.Mode = toSystemMode(entry.Mode)
  54. if !isPlusMode {
  55. if !out.AddDirEntry(dirEntry) {
  56. return false
  57. }
  58. } else {
  59. entryOut := out.AddDirLookupEntry(dirEntry)
  60. if entryOut == nil {
  61. return false
  62. }
  63. wfs.outputEntry(entryOut, inode, entry)
  64. }
  65. return true
  66. }
  67. // TODO remove this with checking whether directory is not forgotten
  68. if err := meta_cache.EnsureVisited(wfs.metaCache, wfs, dirPath); err != nil {
  69. glog.Errorf("dir ReadDirAll %s: %v", dirPath, err)
  70. return fuse.EIO
  71. }
  72. listErr := wfs.metaCache.ListDirectoryEntries(context.Background(), dirPath, "", false, int64(math.MaxInt32), func(entry *filer.Entry) bool {
  73. return processEachEntryFn(entry, false)
  74. })
  75. if listErr != nil {
  76. glog.Errorf("list meta cache: %v", listErr)
  77. return fuse.EIO
  78. }
  79. return fuse.OK
  80. }