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.

144 lines
3.9 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package mount
  2. import (
  3. "context"
  4. "github.com/chrislusf/seaweedfs/weed/filesys/meta_cache"
  5. "github.com/chrislusf/seaweedfs/weed/pb"
  6. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  7. "github.com/chrislusf/seaweedfs/weed/storage/types"
  8. "github.com/chrislusf/seaweedfs/weed/util"
  9. "github.com/chrislusf/seaweedfs/weed/util/grace"
  10. "github.com/hanwen/go-fuse/v2/fuse"
  11. "google.golang.org/grpc"
  12. "os"
  13. "path"
  14. "path/filepath"
  15. "time"
  16. "github.com/hanwen/go-fuse/v2/fs"
  17. )
  18. type Option struct {
  19. MountDirectory string
  20. FilerAddresses []pb.ServerAddress
  21. filerIndex int
  22. GrpcDialOption grpc.DialOption
  23. FilerMountRootPath string
  24. Collection string
  25. Replication string
  26. TtlSec int32
  27. DiskType types.DiskType
  28. ChunkSizeLimit int64
  29. ConcurrentWriters int
  30. CacheDir string
  31. CacheSizeMB int64
  32. DataCenter string
  33. Umask os.FileMode
  34. MountUid uint32
  35. MountGid uint32
  36. MountMode os.FileMode
  37. MountCtime time.Time
  38. MountMtime time.Time
  39. MountParentInode uint64
  40. VolumeServerAccess string // how to access volume servers
  41. Cipher bool // whether encrypt data on volume server
  42. UidGidMapper *meta_cache.UidGidMapper
  43. uniqueCacheDir string
  44. uniqueCacheTempPageDir string
  45. }
  46. type WFS struct {
  47. // follow https://github.com/hanwen/go-fuse/blob/master/fuse/api.go
  48. fuse.RawFileSystem
  49. fs.Inode
  50. option *Option
  51. metaCache *meta_cache.MetaCache
  52. stats statsCache
  53. root Directory
  54. signature int32
  55. inodeToPath *InodeToPath
  56. }
  57. func NewSeaweedFileSystem(option *Option) *WFS {
  58. wfs := &WFS{
  59. RawFileSystem: fuse.NewDefaultRawFileSystem(),
  60. option: option,
  61. signature: util.RandomInt32(),
  62. inodeToPath: NewInodeToPath(),
  63. }
  64. wfs.root = Directory{
  65. name: "/",
  66. wfs: wfs,
  67. entry: nil,
  68. parent: nil,
  69. }
  70. wfs.metaCache = meta_cache.NewMetaCache(path.Join(option.getUniqueCacheDir(), "meta"), util.FullPath(option.FilerMountRootPath), option.UidGidMapper, func(filePath util.FullPath, entry *filer_pb.Entry) {
  71. })
  72. grace.OnInterrupt(func() {
  73. wfs.metaCache.Shutdown()
  74. })
  75. return wfs
  76. }
  77. func (wfs *WFS) Root() *Directory {
  78. return &wfs.root
  79. }
  80. func (wfs *WFS) String() string {
  81. return "seaweedfs"
  82. }
  83. func (wfs *WFS) maybeReadEntry(inode uint64) (path util.FullPath, entry *filer_pb.Entry, status fuse.Status) {
  84. path = wfs.inodeToPath.GetPath(inode)
  85. entry, status = wfs.maybeLoadEntry(path)
  86. return
  87. }
  88. func (wfs *WFS) maybeLoadEntry(fullpath util.FullPath) (*filer_pb.Entry, fuse.Status) {
  89. // glog.V(3).Infof("read entry cache miss %s", fullpath)
  90. dir, name := fullpath.DirAndName()
  91. // return a valid entry for the mount root
  92. if string(fullpath) == wfs.option.FilerMountRootPath {
  93. return &filer_pb.Entry{
  94. Name: name,
  95. IsDirectory: true,
  96. Attributes: &filer_pb.FuseAttributes{
  97. Mtime: wfs.option.MountMtime.Unix(),
  98. FileMode: uint32(wfs.option.MountMode),
  99. Uid: wfs.option.MountUid,
  100. Gid: wfs.option.MountGid,
  101. Crtime: wfs.option.MountCtime.Unix(),
  102. },
  103. }, fuse.OK
  104. }
  105. // read from async meta cache
  106. meta_cache.EnsureVisited(wfs.metaCache, wfs, util.FullPath(dir))
  107. cachedEntry, cacheErr := wfs.metaCache.FindEntry(context.Background(), fullpath)
  108. if cacheErr == filer_pb.ErrNotFound {
  109. return nil, fuse.ENOENT
  110. }
  111. return cachedEntry.ToProtoEntry(), fuse.ENOSYS
  112. }
  113. func (option *Option) setupUniqueCacheDirectory() {
  114. cacheUniqueId := util.Md5String([]byte(option.MountDirectory + string(option.FilerAddresses[0]) + option.FilerMountRootPath + util.Version()))[0:8]
  115. option.uniqueCacheDir = path.Join(option.CacheDir, cacheUniqueId)
  116. option.uniqueCacheTempPageDir = filepath.Join(option.uniqueCacheDir, "sw")
  117. os.MkdirAll(option.uniqueCacheTempPageDir, os.FileMode(0777)&^option.Umask)
  118. }
  119. func (option *Option) getTempFilePageDir() string {
  120. return option.uniqueCacheTempPageDir
  121. }
  122. func (option *Option) getUniqueCacheDir() string {
  123. return option.uniqueCacheDir
  124. }