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
}