@cryptotaxi247 / kubo / commits / fcf7f0e7c

fuse/ipfs: seeking

This commit changed the "ReadAll" to do proper read requests. Seeking in fuse mounted fs now works. Note: this is why opening a mounted video didnt work... we just didnt look at this code in months.

Juan Batiz-Benet committed Jan 29, 2015 at 12:24 UTC fcf7f0e7c1ea32f027d2735747f51f9200b87845
1 file changed +49 -11
fuse/readonly/readonly_unix.go
+49 -11
@@ -5,7 +5,7 @@
5 package readonly
6
7 import (
8 - "io/ioutil"
8 + "io"
9 "os"
10
11 fuse "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
@@ -16,12 +16,13 @@ import (
16 core "github.com/jbenet/go-ipfs/core"
17 mdag "github.com/jbenet/go-ipfs/merkledag"
18 path "github.com/jbenet/go-ipfs/path"
19 + eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
20 uio "github.com/jbenet/go-ipfs/unixfs/io"
21 ftpb "github.com/jbenet/go-ipfs/unixfs/pb"
21 - u "github.com/jbenet/go-ipfs/util"
22 + lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
23 )
24
24 -var log = u.Logger("ipfs")
25 +var log = eventlog.Logger("fuse/ipfs")
26
27 // FileSystem is the readonly Ipfs Fuse Filesystem.
28 type FileSystem struct {
@@ -144,14 +145,51 @@ func (s *Node) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) {
145 return nil, fuse.ENOENT
146 }
147
147 -// ReadAll reads the object data as file data
148 -func (s *Node) ReadAll(intr fs.Intr) ([]byte, fuse.Error) {
149 - log.Debug("Read node.")
150 - r, err := uio.NewDagReader(context.TODO(), s.Nd, s.Ipfs.DAG)
148 +func (s *Node) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fs.Intr) fuse.Error {
149 + // intr will be closed by fuse if the request is cancelled. turn this into a context.
150 + ctx, cancel := context.WithCancel(context.TODO())
151 + defer cancel() // make sure all operations we started close.
152 +
153 + // we wait on intr and cancel our context if it closes.
154 + go func() {
155 + select {
156 + case <-intr: // closed by fuse
157 + cancel() // cancel our context
158 + case <-ctx.Done():
159 + }
160 + }()
161 +
162 + k, err := s.Nd.Key()
163 if err != nil {
152 - return nil, err
164 + return err
165 }
154 - // this is a terrible function... 'ReadAll'?
155 - // what if i have a 6TB file? GG RAM.
156 - return ioutil.ReadAll(r)
166 +
167 + // setup our logging event
168 + lm := make(lgbl.DeferredMap)
169 + lm["key"] = func() interface{} { return k.Pretty() }
170 + lm["req_offset"] = req.Offset
171 + lm["req_size"] = req.Size
172 + defer log.EventBegin(ctx, "fuseRead", lm).Done()
173 +
174 + r, err := uio.NewDagReader(ctx, s.Nd, s.Ipfs.DAG)
175 + if err != nil {
176 + return err
177 + }
178 + o, err := r.Seek(req.Offset, os.SEEK_SET)
179 + lm["req_offset"] = o
180 + if err != nil {
181 + return err
182 + }
183 + n, err := io.ReadFull(r, resp.Data[:req.Size])
184 + resp.Data = resp.Data[:n]
185 + lm["req_size"] = n
186 + return err // may be non-nil / not succeeded
187 }
188 +
189 +// // ReadAll reads the object data as file data
190 +// func (s *Node) ReadAll(intr fs.Intr) ([]byte, fuse.Error) {
191 +// // this is a terrible function... 'ReadAll'?
192 +// // what if i have a 6TB file? GG RAM.
193 +// return ioutil.ReadAll(r)
194 +// }
195 +// GG RAM alright... -jbenet