Commit 0831928c authored by Juan Batiz-Benet's avatar Juan Batiz-Benet

using bazil.org/fuse

parent e9bc9236
...@@ -36,12 +36,5 @@ func mountCmd(c *commander.Command, inp []string) error { ...@@ -36,12 +36,5 @@ func mountCmd(c *commander.Command, inp []string) error {
mp := inp[0] mp := inp[0]
fmt.Printf("Mounting at %s\n", mp) fmt.Printf("Mounting at %s\n", mp)
fs := rofs.NewFileSystem(n) return rofs.Mount(n, mp)
s, err := rofs.Mount(fs, mp)
if err != nil {
return err
}
s.SetDebug(true)
s.Serve()
return nil
} }
...@@ -3,28 +3,36 @@ ...@@ -3,28 +3,36 @@
package readonly package readonly
import ( import (
"github.com/hanwen/go-fuse/fuse" "os"
"github.com/hanwen/go-fuse/fuse/nodefs" "bazil.org/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs" "bazil.org/fuse/fs"
core "github.com/jbenet/go-ipfs/core" core "github.com/jbenet/go-ipfs/core"
mdag "github.com/jbenet/go-ipfs/merkledag"
) )
type FileSystem struct { type FileSystem struct {
Ipfs *core.IpfsNode Ipfs *core.IpfsNode
pathfs.FileSystem
} }
func NewFileSystem(ipfs *core.IpfsNode) *FileSystem { func NewFileSystem(ipfs *core.IpfsNode) *FileSystem {
return &FileSystem{ return &FileSystem{ Ipfs: ipfs }
Ipfs: ipfs,
FileSystem: pathfs.NewDefaultFileSystem(),
}
} }
func (s *FileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) { func (f FileSystem) Root() (fs.Node, fuse.Error) {
if name == "/" { // -rw +x on root return Root{Ipfs: f.Ipfs }, nil
return &fuse.Attr{Mode: fuse.S_IFDIR | 0111}, fuse.OK }
}
type Root struct {
Ipfs *core.IpfsNode
}
func (Root) Attr() fuse.Attr {
return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0111} // -rw+x
}
func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
nd, err := s.Ipfs.Resolver.ResolvePath(name) nd, err := s.Ipfs.Resolver.ResolvePath(name)
if err != nil { if err != nil {
...@@ -32,74 +40,79 @@ func (s *FileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fu ...@@ -32,74 +40,79 @@ func (s *FileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fu
return nil, fuse.ENOENT return nil, fuse.ENOENT
} }
// links? say dir. could have data... return Node{Ipfs: s.Ipfs, Nd: nd}, nil
if len(nd.Links) > 0 { }
return &fuse.Attr{Mode: fuse.S_IFDIR | 0555}, fuse.OK
}
// size func (Root) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) {
size, _ := nd.Size() return nil, fuse.EPERM
}
// file. type Node struct {
return &fuse.Attr{ Ipfs *core.IpfsNode
Mode: fuse.S_IFREG | 0444, Nd *mdag.Node
Size: uint64(size),
}, fuse.OK
} }
func (s *FileSystem) OpenDir(name string, context *fuse.Context) (c []fuse.DirEntry, code fuse.Status) { func (s Node) Attr() fuse.Attr {
if name == "/" { // nope
return nil, fuse.EPERM if len(s.Nd.Links) > 0 {
return fuse.Attr{Mode: os.ModeDir | 0555}
} }
nd, err := s.Ipfs.Resolver.ResolvePath(name) size, _ := s.Nd.Size()
return fuse.Attr{Mode: 0444, Size: uint64(size)}
}
func (s *Node) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
nd, err := s.Ipfs.Resolver.ResolveLinks(s.Nd, []string{name})
if err != nil { if err != nil {
// todo: make this error more versatile. // todo: make this error more versatile.
return nil, fuse.ENOENT return nil, fuse.ENOENT
} }
entries := make([]fuse.DirEntry, len(nd.Links)) return Node{Ipfs: s.Ipfs, Nd: nd}, nil
for i, link := range nd.Links { }
func (s *Node) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) {
entries := make([]fuse.Dirent, len(s.Nd.Links))
for i, link := range s.Nd.Links {
n := link.Name n := link.Name
if len(n) == 0 { if len(n) == 0 {
n = link.Hash.B58String() n = link.Hash.B58String()
} }
entries[i] = fuse.DirEntry{Name: n, Mode: fuse.S_IFREG | 0444} entries[i] = fuse.Dirent{Name: n, Type: fuse.DT_File}
} }
if len(entries) > 0 { if len(entries) > 0 {
return entries, fuse.OK return entries, nil
} }
return nil, fuse.ENOENT return nil, fuse.ENOENT
} }
func (s *FileSystem) Open(name string, flags uint32, context *fuse.Context) ( func (s *Node) ReadAll(intr fs.Intr) ([]byte, fuse.Error) {
file nodefs.File, code fuse.Status) { return []byte(s.Nd.Data), nil
}
// read only, bro!
if flags&fuse.O_ANYWRITE != 0 {
return nil, fuse.EPERM
}
nd, err := s.Ipfs.Resolver.ResolvePath(name)
if err != nil {
// todo: make this error more versatile.
return nil, fuse.ENOENT
}
return nodefs.NewDataFile([]byte(nd.Data)), fuse.OK func Mount(ipfs *core.IpfsNode, fpath string) (error) {
}
func (s *FileSystem) String() string { c, err := fuse.Mount(fpath)
return "IpfsReadOnly" if err != nil {
} return err
}
defer c.Close()
func (s *FileSystem) OnMount(nodeFs *pathfs.PathNodeFs) { err = fs.Serve(c, FileSystem{Ipfs: ipfs})
} if err != nil {
return err
}
func Mount(s *FileSystem, path string) (*fuse.Server, error) { // check if the mount process has an error to report
rfs := pathfs.NewReadonlyFileSystem(s) <-c.Ready
fs := pathfs.NewPathNodeFs(rfs, nil) if err := c.MountError; err != nil {
ser, _, err := nodefs.MountRoot(path, fs.Root(), nil) return err
return ser, err }
return nil
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment