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.

139 lines
2.8 KiB

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