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.

109 lines
2.7 KiB

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