dir.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package filesys
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "path"
  7. "sync"
  8. "bazil.org/fuse/fs"
  9. "bazil.org/fuse"
  10. "github.com/chrislusf/seaweedfs/weed/filer"
  11. "github.com/chrislusf/seaweedfs/weed/glog"
  12. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  13. )
  14. type Dir struct {
  15. Path string
  16. NodeMap map[string]fs.Node
  17. NodeMapLock sync.Mutex
  18. wfs *WFS
  19. }
  20. func (dir *Dir) Attr(context context.Context, attr *fuse.Attr) error {
  21. attr.Mode = os.ModeDir | 0777
  22. return nil
  23. }
  24. func (dir *Dir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
  25. dir.NodeMapLock.Lock()
  26. defer dir.NodeMapLock.Unlock()
  27. fmt.Printf("mkdir %+v\n", req)
  28. node := &Dir{Path: path.Join(dir.Path, req.Name), wfs: dir.wfs}
  29. dir.NodeMap[req.Name] = node
  30. return node, nil
  31. }
  32. func (dir *Dir) Lookup(ctx context.Context, name string) (node fs.Node, err error) {
  33. dir.NodeMapLock.Lock()
  34. defer dir.NodeMapLock.Unlock()
  35. if dir.NodeMap == nil {
  36. dir.NodeMap = make(map[string]fs.Node)
  37. }
  38. if node, ok := dir.NodeMap[name]; ok {
  39. return node, nil
  40. }
  41. var entry *filer_pb.Entry
  42. err = dir.wfs.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  43. request := &filer_pb.LookupDirectoryEntryRequest{
  44. Directory: dir.Path,
  45. Name: name,
  46. }
  47. glog.V(1).Infof("lookup directory entry: %v", request)
  48. resp, err := client.LookupDirectoryEntry(ctx, request)
  49. if err != nil {
  50. return err
  51. }
  52. entry = resp.Entry
  53. return nil
  54. })
  55. if entry != nil {
  56. if entry.IsDirectory {
  57. node = &Dir{Path: path.Join(dir.Path, name), wfs: dir.wfs}
  58. } else {
  59. node = &File{FileId: filer.FileId(entry.FileId), Name: name, wfs: dir.wfs}
  60. }
  61. dir.NodeMap[name] = node
  62. return node, nil
  63. }
  64. return nil, err
  65. }
  66. func (dir *Dir) ReadDirAll(ctx context.Context) (ret []fuse.Dirent, err error) {
  67. err = dir.wfs.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  68. request := &filer_pb.ListEntriesRequest{
  69. Directory: dir.Path,
  70. }
  71. glog.V(1).Infof("read directory: %v", request)
  72. resp, err := client.ListEntries(ctx, request)
  73. if err != nil {
  74. return err
  75. }
  76. for _, entry := range resp.Entries {
  77. if entry.IsDirectory {
  78. dirent := fuse.Dirent{Name: entry.Name, Type: fuse.DT_Dir}
  79. ret = append(ret, dirent)
  80. } else {
  81. dirent := fuse.Dirent{Name: entry.Name, Type: fuse.DT_File}
  82. ret = append(ret, dirent)
  83. }
  84. }
  85. return nil
  86. })
  87. return ret, err
  88. }
  89. func (dir *Dir) Remove(ctx context.Context, req *fuse.RemoveRequest) error {
  90. dir.NodeMapLock.Lock()
  91. defer dir.NodeMapLock.Unlock()
  92. return dir.wfs.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  93. request := &filer_pb.DeleteEntryRequest{
  94. Directory: dir.Path,
  95. Name: req.Name,
  96. IsDirectory: req.Dir,
  97. }
  98. glog.V(1).Infof("remove directory entry: %v", request)
  99. _, err := client.DeleteEntry(ctx, request)
  100. if err != nil {
  101. return err
  102. }
  103. delete(dir.NodeMap, req.Name)
  104. return nil
  105. })
  106. }