@cryptotaxi247 / kubo / commits / 0831928c3

using bazil.org/fuse

Juan Batiz-Benet committed Jul 6, 2014 at 03:22 UTC 0831928c3dc058eeb89eef1cb2c91105118e5e99
2 files changed +92 -86
cli/mount.go
+1 -8
@@ -36,12 +36,5 @@ func mountCmd(c *commander.Command, inp []string) error {
36 mp := inp[0]
37 fmt.Printf("Mounting at %s\n", mp)
38
39 - fs := rofs.NewFileSystem(n)
40 - s, err := rofs.Mount(fs, mp)
41 - if err != nil {
42 - return err
43 - }
44 - s.SetDebug(true)
45 - s.Serve()
46 - return nil
39 + return rofs.Mount(n, mp)
40 }
fuse/readonly/readonly.go
+91 -78
@@ -3,103 +3,116 @@
3 package readonly
4
5 import (
6 - "github.com/hanwen/go-fuse/fuse"
7 - "github.com/hanwen/go-fuse/fuse/nodefs"
8 - "github.com/hanwen/go-fuse/fuse/pathfs"
9 - core "github.com/jbenet/go-ipfs/core"
6 + "os"
7 + "bazil.org/fuse"
8 + "bazil.org/fuse/fs"
9 + core "github.com/jbenet/go-ipfs/core"
10 + mdag "github.com/jbenet/go-ipfs/merkledag"
11 )
12
13 +
14 type FileSystem struct {
13 - Ipfs *core.IpfsNode
14 - pathfs.FileSystem
15 + Ipfs *core.IpfsNode
16 }
17
18 func NewFileSystem(ipfs *core.IpfsNode) *FileSystem {
18 - return &FileSystem{
19 - Ipfs: ipfs,
20 - FileSystem: pathfs.NewDefaultFileSystem(),
21 - }
19 + return &FileSystem{ Ipfs: ipfs }
20 +}
21 +
22 +func (f FileSystem) Root() (fs.Node, fuse.Error) {
23 + return Root{Ipfs: f.Ipfs }, nil
24 +}
25 +
26 +
27 +type Root struct {
28 + Ipfs *core.IpfsNode
29 +}
30 +
31 +func (Root) Attr() fuse.Attr {
32 + return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0111} // -rw+x
33 +}
34 +
35 +func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
36 +
37 + nd, err := s.Ipfs.Resolver.ResolvePath(name)
38 + if err != nil {
39 + // todo: make this error more versatile.
40 + return nil, fuse.ENOENT
41 + }
42 +
43 + return Node{Ipfs: s.Ipfs, Nd: nd}, nil
44 }
45
24 -func (s *FileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
25 - if name == "/" { // -rw +x on root
26 - return &fuse.Attr{Mode: fuse.S_IFDIR | 0111}, fuse.OK
27 - }
28 -
29 - nd, err := s.Ipfs.Resolver.ResolvePath(name)
30 - if err != nil {
31 - // todo: make this error more versatile.
32 - return nil, fuse.ENOENT
33 - }
34 -
35 - // links? say dir. could have data...
36 - if len(nd.Links) > 0 {
37 - return &fuse.Attr{Mode: fuse.S_IFDIR | 0555}, fuse.OK
38 - }
39 -
40 - // size
41 - size, _ := nd.Size()
42 -
43 - // file.
44 - return &fuse.Attr{
45 - Mode: fuse.S_IFREG | 0444,
46 - Size: uint64(size),
47 - }, fuse.OK
46 +func (Root) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) {
47 + return nil, fuse.EPERM
48 }
49
50 -func (s *FileSystem) OpenDir(name string, context *fuse.Context) (c []fuse.DirEntry, code fuse.Status) {
51 - if name == "/" { // nope
52 - return nil, fuse.EPERM
53 - }
54 -
55 - nd, err := s.Ipfs.Resolver.ResolvePath(name)
56 - if err != nil {
57 - // todo: make this error more versatile.
58 - return nil, fuse.ENOENT
59 - }
60 -
61 - entries := make([]fuse.DirEntry, len(nd.Links))
62 - for i, link := range nd.Links {
63 - n := link.Name
64 - if len(n) == 0 {
65 - n = link.Hash.B58String()
66 - }
67 - entries[i] = fuse.DirEntry{Name: n, Mode: fuse.S_IFREG | 0444}
68 - }
69 -
70 - if len(entries) > 0 {
71 - return entries, fuse.OK
72 - }
73 - return nil, fuse.ENOENT
50 +type Node struct {
51 + Ipfs *core.IpfsNode
52 + Nd *mdag.Node
53 }
54
76 -func (s *FileSystem) Open(name string, flags uint32, context *fuse.Context) (
77 - file nodefs.File, code fuse.Status) {
55 +func (s Node) Attr() fuse.Attr {
56 +
57 + if len(s.Nd.Links) > 0 {
58 + return fuse.Attr{Mode: os.ModeDir | 0555}
59 + }
60 +
61 + size, _ := s.Nd.Size()
62 + return fuse.Attr{Mode: 0444, Size: uint64(size)}
63 +}
64
79 - // read only, bro!
80 - if flags&fuse.O_ANYWRITE != 0 {
81 - return nil, fuse.EPERM
82 - }
65 +func (s *Node) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
66
84 - nd, err := s.Ipfs.Resolver.ResolvePath(name)
85 - if err != nil {
86 - // todo: make this error more versatile.
87 - return nil, fuse.ENOENT
88 - }
67 + nd, err := s.Ipfs.Resolver.ResolveLinks(s.Nd, []string{name})
68 + if err != nil {
69 + // todo: make this error more versatile.
70 + return nil, fuse.ENOENT
71 + }
72
90 - return nodefs.NewDataFile([]byte(nd.Data)), fuse.OK
73 + return Node{Ipfs: s.Ipfs, Nd: nd}, nil
74 }
75
93 -func (s *FileSystem) String() string {
94 - return "IpfsReadOnly"
76 +func (s *Node) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) {
77 +
78 + entries := make([]fuse.Dirent, len(s.Nd.Links))
79 + for i, link := range s.Nd.Links {
80 + n := link.Name
81 + if len(n) == 0 {
82 + n = link.Hash.B58String()
83 + }
84 + entries[i] = fuse.Dirent{Name: n, Type: fuse.DT_File}
85 + }
86 +
87 + if len(entries) > 0 {
88 + return entries, nil
89 + }
90 + return nil, fuse.ENOENT
91 }
92
97 -func (s *FileSystem) OnMount(nodeFs *pathfs.PathNodeFs) {
93 +func (s *Node) ReadAll(intr fs.Intr) ([]byte, fuse.Error) {
94 + return []byte(s.Nd.Data), nil
95 }
96
100 -func Mount(s *FileSystem, path string) (*fuse.Server, error) {
101 - rfs := pathfs.NewReadonlyFileSystem(s)
102 - fs := pathfs.NewPathNodeFs(rfs, nil)
103 - ser, _, err := nodefs.MountRoot(path, fs.Root(), nil)
104 - return ser, err
97 +
98 +
99 +func Mount(ipfs *core.IpfsNode, fpath string) (error) {
100 +
101 + c, err := fuse.Mount(fpath)
102 + if err != nil {
103 + return err
104 + }
105 + defer c.Close()
106 +
107 + err = fs.Serve(c, FileSystem{Ipfs: ipfs})
108 + if err != nil {
109 + return err
110 + }
111 +
112 + // check if the mount process has an error to report
113 + <-c.Ready
114 + if err := c.MountError; err != nil {
115 + return err
116 + }
117 + return nil
118 }