dir.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package main
  15. import (
  16. "context"
  17. "os"
  18. "syscall"
  19. "bazil.org/fuse"
  20. "bazil.org/fuse/fs"
  21. "github.com/pkg/errors"
  22. )
  23. const (
  24. CONTENT_FILE_NAME = "content"
  25. META_FILE_NAME = "meta"
  26. )
  27. // Dir implements both Node and Handle for the root directory.
  28. type Dir struct{}
  29. func (Dir) Attr(ctx context.Context, a *fuse.Attr) error {
  30. a.Inode = 1
  31. a.Mode = os.ModeDir | 0755
  32. return nil
  33. }
  34. func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
  35. if name == CONTENT_FILE_NAME {
  36. return Content{}, nil
  37. } else if name == META_FILE_NAME {
  38. return Meta{}, nil
  39. }
  40. return nil, syscall.ENOENT
  41. }
  42. func (Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
  43. return dirDirs, nil
  44. }
  45. var (
  46. dirDirs = []fuse.Dirent{
  47. {Inode: 2, Name: CONTENT_FILE_NAME, Type: fuse.DT_File},
  48. {Inode: 3, Name: META_FILE_NAME, Type: fuse.DT_File},
  49. }
  50. )
  51. // Content implements both Node and Handle for the content file.
  52. type Content struct{}
  53. func NewContent() *Content {
  54. return &Content{}
  55. }
  56. func (Content) Attr(ctx context.Context, a *fuse.Attr) error {
  57. a.Inode = 2
  58. a.Mode = 0444
  59. a.Size = uint64(fetcherFs.GetSize())
  60. a.BlockSize = uint32(opt.Blocksize) * 1024 * 1024
  61. return nil
  62. }
  63. func (Content) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
  64. // fmt.Printf("req.Size %d, req.Offset %d, resp.Data %d", req.Size, req.Offset, len(resp.Data))
  65. if req.Offset >= 0 && req.Offset < fetcherFs.GetSize() {
  66. if req.Offset+int64(req.Size) > fetcherFs.GetSize() {
  67. req.Size = int(fetcherFs.GetSize() - req.Offset)
  68. }
  69. if data, err := fetcherFs.doRead(req.Size, req.Offset); err != nil {
  70. return err
  71. } else {
  72. resp.Data = data
  73. return nil
  74. }
  75. } else if req.Offset == fetcherFs.GetSize() {
  76. return nil
  77. } else {
  78. return errors.Errorf("bad offset %d", req.Offset)
  79. }
  80. }
  81. // Meta implements both Node and Handle for the meta file.
  82. type Meta struct{}
  83. func NewMeta() *Meta {
  84. return &Meta{}
  85. }
  86. func (Meta) Attr(ctx context.Context, a *fuse.Attr) error {
  87. a.Inode = 3
  88. a.Mode = 0444
  89. a.Size = uint64(len(fetcherFs.GetMeta()))
  90. return nil
  91. }
  92. func (Meta) ReadAll(ctx context.Context) ([]byte, error) {
  93. return []byte(fetcherFs.GetMeta()), nil
  94. }