github.com/swiftstack/proxyfs@v0.0.0-20201223034610-5434d919416e/fuse/fuse.go (about) 1 package fuse 2 3 import ( 4 "fmt" 5 "sync" 6 7 fuselib "bazil.org/fuse" 8 fusefslib "bazil.org/fuse/fs" 9 "golang.org/x/net/context" 10 11 "github.com/swiftstack/ProxyFS/blunder" 12 "github.com/swiftstack/ProxyFS/fs" 13 "github.com/swiftstack/ProxyFS/inode" 14 ) 15 16 type ProxyFUSE struct { 17 volumeHandle fs.VolumeHandle 18 wg sync.WaitGroup // Used to synchronize mount 19 } 20 21 func (pfs *ProxyFUSE) Root() (fusefslib.Node, error) { 22 root := Dir{volumeHandle: pfs.volumeHandle, inodeNumber: inode.RootDirInodeNumber} 23 24 // Signal any waiters that we have completed mounting the volume. 25 // We know this because this call is only made after the user level FUSE 26 // library and the FUSE driver have agreed on the FUSE prototocol level. 27 pfs.wg.Done() 28 return root, nil 29 } 30 31 func (pfs *ProxyFUSE) Statfs(ctx context.Context, req *fuselib.StatfsRequest, resp *fuselib.StatfsResponse) error { 32 enterGate() 33 defer leaveGate() 34 35 statvfs, err := pfs.volumeHandle.StatVfs() 36 if err != nil { 37 return newFuseError(err) 38 } 39 resp.Blocks = statvfs[fs.StatVFSTotalBlocks] 40 resp.Bfree = statvfs[fs.StatVFSFreeBlocks] 41 resp.Bavail = statvfs[fs.StatVFSAvailBlocks] 42 resp.Files = statvfs[fs.StatVFSTotalInodes] 43 resp.Ffree = statvfs[fs.StatVFSFreeInodes] 44 resp.Bsize = uint32(statvfs[fs.StatVFSBlockSize]) 45 resp.Namelen = uint32(statvfs[fs.StatVFSMaxFilenameLen]) 46 resp.Frsize = uint32(statvfs[fs.StatVFSFragmentSize]) 47 return nil 48 } 49 50 type fuseError struct { 51 str string 52 errno fuselib.Errno 53 } 54 55 func (fE *fuseError) Errno() fuselib.Errno { 56 return fE.errno 57 } 58 59 func (fE *fuseError) Error() string { 60 return fE.str 61 } 62 63 func newFuseError(err error) *fuseError { 64 return &fuseError{ 65 str: fmt.Sprintf("%v", err), 66 errno: fuselib.Errno(blunder.Errno(err)), 67 } 68 }