2016-07-18 06:03:23 +08:00
|
|
|
// FUSE main Fs
|
|
|
|
|
|
|
|
// +build linux darwin freebsd
|
|
|
|
|
|
|
|
package mount
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bazil.org/fuse"
|
|
|
|
fusefs "bazil.org/fuse/fs"
|
2017-05-03 05:35:07 +08:00
|
|
|
"github.com/ncw/rclone/cmd/mountlib"
|
2016-07-18 06:03:23 +08:00
|
|
|
"github.com/ncw/rclone/fs"
|
2017-05-03 05:35:07 +08:00
|
|
|
"github.com/pkg/errors"
|
2016-11-21 06:54:03 +08:00
|
|
|
"golang.org/x/net/context"
|
2016-07-18 06:03:23 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// FS represents the top level filing system
|
|
|
|
type FS struct {
|
2017-05-03 05:35:07 +08:00
|
|
|
*mountlib.FS
|
|
|
|
f fs.Fs
|
2016-07-18 06:03:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check interface satistfied
|
|
|
|
var _ fusefs.FS = (*FS)(nil)
|
|
|
|
|
2017-05-03 05:35:07 +08:00
|
|
|
// NewFS makes a new FS
|
|
|
|
func NewFS(f fs.Fs) *FS {
|
|
|
|
fsys := &FS{
|
|
|
|
FS: mountlib.NewFS(f),
|
|
|
|
f: f,
|
2016-09-09 15:39:19 +08:00
|
|
|
}
|
2017-05-03 05:35:07 +08:00
|
|
|
if noSeek {
|
|
|
|
fsys.FS.NoSeek()
|
2016-09-09 15:39:19 +08:00
|
|
|
}
|
2017-05-03 05:35:07 +08:00
|
|
|
return fsys
|
2016-09-09 15:39:19 +08:00
|
|
|
}
|
|
|
|
|
2017-05-03 05:35:07 +08:00
|
|
|
// Root returns the root node
|
|
|
|
func (f *FS) Root() (fusefs.Node, error) {
|
|
|
|
root, err := f.FS.Root()
|
2017-05-05 04:49:06 +08:00
|
|
|
if err != nil {
|
2017-05-03 05:35:07 +08:00
|
|
|
return nil, translateError(err)
|
2016-07-18 06:03:23 +08:00
|
|
|
}
|
2017-05-03 05:35:07 +08:00
|
|
|
return &Dir{root}, nil
|
2016-07-18 06:03:23 +08:00
|
|
|
}
|
2016-11-21 06:54:03 +08:00
|
|
|
|
|
|
|
// Check interface satsified
|
|
|
|
var _ fusefs.FSStatfser = (*FS)(nil)
|
|
|
|
|
|
|
|
// Statfs is called to obtain file system metadata.
|
|
|
|
// It should write that data to resp.
|
|
|
|
func (f *FS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error {
|
|
|
|
const blockSize = 4096
|
|
|
|
const fsBlocks = (1 << 50) / blockSize
|
|
|
|
resp.Blocks = fsBlocks // Total data blocks in file system.
|
|
|
|
resp.Bfree = fsBlocks // Free blocks in file system.
|
|
|
|
resp.Bavail = fsBlocks // Free blocks in file system if you're not root.
|
|
|
|
resp.Files = 1E9 // Total files in file system.
|
|
|
|
resp.Ffree = 1E9 // Free files in file system.
|
|
|
|
resp.Bsize = blockSize // Block size
|
|
|
|
resp.Namelen = 255 // Maximum file name length?
|
|
|
|
resp.Frsize = blockSize // Fragment size, smallest addressable data size in the file system.
|
|
|
|
return nil
|
|
|
|
}
|
2017-05-05 04:49:06 +08:00
|
|
|
|
2017-05-03 05:35:07 +08:00
|
|
|
// Translate errors from mountlib
|
|
|
|
func translateError(err error) error {
|
|
|
|
if err == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
cause := errors.Cause(err)
|
|
|
|
if mErr, ok := cause.(mountlib.Error); ok {
|
|
|
|
switch mErr {
|
|
|
|
case mountlib.ENOENT:
|
|
|
|
return fuse.ENOENT
|
|
|
|
case mountlib.ENOTEMPTY:
|
|
|
|
return fuse.EEXIST // return fuse.ENOTEMPTY - doesn't exist though so use EEXIST
|
|
|
|
case mountlib.EEXIST:
|
|
|
|
return fuse.EEXIST
|
2017-05-05 04:49:06 +08:00
|
|
|
}
|
2017-05-03 05:35:07 +08:00
|
|
|
}
|
|
|
|
return err
|
2017-05-05 04:49:06 +08:00
|
|
|
}
|