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.

110 lines
2.8 KiB

7 years ago
7 years ago
  1. package filesys
  2. import (
  3. "bazil.org/fuse/fs"
  4. "fmt"
  5. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  6. "github.com/karlseguin/ccache"
  7. "google.golang.org/grpc"
  8. "sync"
  9. "bazil.org/fuse"
  10. "github.com/chrislusf/seaweedfs/weed/glog"
  11. )
  12. type WFS struct {
  13. filerGrpcAddress string
  14. listDirectoryEntriesCache *ccache.Cache
  15. collection string
  16. replication string
  17. chunkSizeLimit int64
  18. // contains all open handles
  19. handles []*FileHandle
  20. pathToHandleIndex map[string]int
  21. pathToHandleLock sync.Mutex
  22. }
  23. func NewSeaweedFileSystem(filerGrpcAddress string, collection string, replication string, chunkSizeLimitMB int) *WFS {
  24. return &WFS{
  25. filerGrpcAddress: filerGrpcAddress,
  26. listDirectoryEntriesCache: ccache.New(ccache.Configure().MaxSize(6000).ItemsToPrune(100)),
  27. collection: collection,
  28. replication: replication,
  29. chunkSizeLimit: int64(chunkSizeLimitMB) * 1024 * 1024,
  30. pathToHandleIndex: make(map[string]int),
  31. }
  32. }
  33. func (wfs *WFS) Root() (fs.Node, error) {
  34. return &Dir{Path: "/", wfs: wfs}, nil
  35. }
  36. func (wfs *WFS) withFilerClient(fn func(filer_pb.SeaweedFilerClient) error) error {
  37. grpcConnection, err := grpc.Dial(wfs.filerGrpcAddress, grpc.WithInsecure())
  38. if err != nil {
  39. return fmt.Errorf("fail to dial %s: %v", wfs.filerGrpcAddress, err)
  40. }
  41. defer grpcConnection.Close()
  42. client := filer_pb.NewSeaweedFilerClient(grpcConnection)
  43. return fn(client)
  44. }
  45. func (wfs *WFS) AcquireHandle(file *File, uid, gid uint32) (handle *FileHandle) {
  46. wfs.pathToHandleLock.Lock()
  47. defer wfs.pathToHandleLock.Unlock()
  48. fullpath := file.fullpath()
  49. index, found := wfs.pathToHandleIndex[fullpath]
  50. if found && wfs.handles[index] != nil {
  51. glog.V(4).Infoln(fullpath, "found handle id", index)
  52. return wfs.handles[index]
  53. }
  54. // create a new handler
  55. handle = &FileHandle{
  56. f: file,
  57. dirtyPages: newDirtyPages(file),
  58. Uid: uid,
  59. Gid: gid,
  60. }
  61. if found && wfs.handles[index] != nil {
  62. glog.V(4).Infoln(fullpath, "reuse previous handle id", index)
  63. wfs.handles[index] = handle
  64. handle.handle = uint64(index)
  65. return
  66. }
  67. for i, h := range wfs.handles {
  68. if h == nil {
  69. wfs.handles[i] = handle
  70. handle.handle = uint64(i)
  71. wfs.pathToHandleIndex[fullpath] = i
  72. glog.V(4).Infoln(fullpath, "reuse handle id", handle.handle)
  73. return
  74. }
  75. }
  76. wfs.handles = append(wfs.handles, handle)
  77. handle.handle = uint64(len(wfs.handles) - 1)
  78. glog.V(4).Infoln(fullpath, "new handle id", handle.handle)
  79. wfs.pathToHandleIndex[fullpath] = int(handle.handle)
  80. return
  81. }
  82. func (wfs *WFS) ReleaseHandle(handleId fuse.HandleID) {
  83. wfs.pathToHandleLock.Lock()
  84. defer wfs.pathToHandleLock.Unlock()
  85. glog.V(4).Infoln("releasing handle id", handleId, "current handles lengh", len(wfs.handles))
  86. if int(handleId) < len(wfs.handles) {
  87. wfs.handles[int(handleId)] = nil
  88. }
  89. return
  90. }