fs.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // FUSE main Fs
  2. //go:build linux
  3. // +build linux
  4. package mount
  5. import (
  6. "context"
  7. "syscall"
  8. "bazil.org/fuse"
  9. fusefs "bazil.org/fuse/fs"
  10. "github.com/rclone/rclone/cmd/mountlib"
  11. "github.com/rclone/rclone/fs"
  12. "github.com/rclone/rclone/fs/fserrors"
  13. "github.com/rclone/rclone/fs/log"
  14. "github.com/rclone/rclone/vfs"
  15. )
  16. // FS represents the top level filing system
  17. type FS struct {
  18. *vfs.VFS
  19. f fs.Fs
  20. opt *mountlib.Options
  21. server *fusefs.Server
  22. }
  23. // Check interface satisfied
  24. var _ fusefs.FS = (*FS)(nil)
  25. // NewFS makes a new FS
  26. func NewFS(VFS *vfs.VFS, opt *mountlib.Options) *FS {
  27. fsys := &FS{
  28. VFS: VFS,
  29. f: VFS.Fs(),
  30. opt: opt,
  31. }
  32. return fsys
  33. }
  34. // Root returns the root node
  35. func (f *FS) Root() (node fusefs.Node, err error) {
  36. defer log.Trace("", "")("node=%+v, err=%v", &node, &err)
  37. root, err := f.VFS.Root()
  38. if err != nil {
  39. return nil, translateError(err)
  40. }
  41. return &Dir{root, f}, nil
  42. }
  43. // Check interface satisfied
  44. var _ fusefs.FSStatfser = (*FS)(nil)
  45. // Statfs is called to obtain file system metadata.
  46. // It should write that data to resp.
  47. func (f *FS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) (err error) {
  48. defer log.Trace("", "")("stat=%+v, err=%v", resp, &err)
  49. const blockSize = 4096
  50. total, _, free := f.VFS.Statfs()
  51. resp.Blocks = uint64(total) / blockSize // Total data blocks in file system.
  52. resp.Bfree = uint64(free) / blockSize // Free blocks in file system.
  53. resp.Bavail = resp.Bfree // Free blocks in file system if you're not root.
  54. resp.Files = 1e9 // Total files in file system.
  55. resp.Ffree = 1e9 // Free files in file system.
  56. resp.Bsize = blockSize // Block size
  57. resp.Namelen = 255 // Maximum file name length?
  58. resp.Frsize = blockSize // Fragment size, smallest addressable data size in the file system.
  59. mountlib.ClipBlocks(&resp.Blocks)
  60. mountlib.ClipBlocks(&resp.Bfree)
  61. mountlib.ClipBlocks(&resp.Bavail)
  62. return nil
  63. }
  64. // Translate errors from mountlib
  65. func translateError(err error) error {
  66. if err == nil {
  67. return nil
  68. }
  69. _, uErr := fserrors.Cause(err)
  70. switch uErr {
  71. case vfs.OK:
  72. return nil
  73. case vfs.ENOENT, fs.ErrorDirNotFound, fs.ErrorObjectNotFound:
  74. return fuse.Errno(syscall.ENOENT)
  75. case vfs.EEXIST, fs.ErrorDirExists:
  76. return fuse.Errno(syscall.EEXIST)
  77. case vfs.EPERM, fs.ErrorPermissionDenied:
  78. return fuse.Errno(syscall.EPERM)
  79. case vfs.ECLOSED:
  80. return fuse.Errno(syscall.EBADF)
  81. case vfs.ENOTEMPTY:
  82. return fuse.Errno(syscall.ENOTEMPTY)
  83. case vfs.ESPIPE:
  84. return fuse.Errno(syscall.ESPIPE)
  85. case vfs.EBADF:
  86. return fuse.Errno(syscall.EBADF)
  87. case vfs.EROFS:
  88. return fuse.Errno(syscall.EROFS)
  89. case vfs.ENOSYS, fs.ErrorNotImplemented:
  90. return syscall.ENOSYS
  91. case vfs.EINVAL:
  92. return fuse.Errno(syscall.EINVAL)
  93. }
  94. fs.Errorf(nil, "IO error: %v", err)
  95. return err
  96. }