diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 1403d3f83..912742a38 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -7,7 +7,7 @@ "Deps": [ { "ImportPath": "bazil.org/fuse", - "Rev": "d62a1291477b51b24becf4def173bd843138c4b6" + "Rev": "489e985dcb429718328be2bb055adb685c4ae1e3" }, { "ImportPath": "code.google.com/p/go-uuid/uuid", diff --git a/Godeps/_workspace/src/bazil.org/fuse/error_darwin.go b/Godeps/_workspace/src/bazil.org/fuse/error_darwin.go index adb9789a2..195b0a772 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/error_darwin.go +++ b/Godeps/_workspace/src/bazil.org/fuse/error_darwin.go @@ -22,7 +22,7 @@ func (getxattrError) Errno() Errno { // http://mail-index.netbsd.org/tech-kern/2012/04/30/msg013090.html // http://mail-index.netbsd.org/tech-kern/2012/04/30/msg013097.html // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html -func translateGetxattrError(err Error) Error { +func translateGetxattrError(err error) error { ferr, ok := err.(ErrorNumber) if !ok { return err diff --git a/Godeps/_workspace/src/bazil.org/fuse/error_std.go b/Godeps/_workspace/src/bazil.org/fuse/error_std.go index 3cae6c82d..76aaaf574 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/error_std.go +++ b/Godeps/_workspace/src/bazil.org/fuse/error_std.go @@ -2,6 +2,6 @@ package fuse -func translateGetxattrError(err Error) Error { +func translateGetxattrError(err error) error { return err } diff --git a/Godeps/_workspace/src/bazil.org/fuse/fs/bench/bench_test.go b/Godeps/_workspace/src/bazil.org/fuse/fs/bench/bench_test.go index 30950fed8..a381533d3 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/fs/bench/bench_test.go +++ b/Godeps/_workspace/src/bazil.org/fuse/fs/bench/bench_test.go @@ -10,6 +10,7 @@ import ( "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil" + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) type benchConfig struct { @@ -23,13 +24,13 @@ type benchFS struct { var _ = fs.FS(benchFS{}) var _ = fs.FSIniter(benchFS{}) -func (benchFS) Init(req *fuse.InitRequest, resp *fuse.InitResponse, intr fs.Intr) fuse.Error { +func (benchFS) Init(ctx context.Context, req *fuse.InitRequest, resp *fuse.InitResponse) error { resp.MaxReadahead = 64 * 1024 * 1024 resp.Flags |= fuse.InitAsyncRead return nil } -func (f benchFS) Root() (fs.Node, fuse.Error) { +func (f benchFS) Root() (fs.Node, error) { return benchDir{conf: f.conf}, nil } @@ -40,20 +41,20 @@ type benchDir struct { var _ = fs.Node(benchDir{}) var _ = fs.NodeStringLookuper(benchDir{}) var _ = fs.Handle(benchDir{}) -var _ = fs.HandleReadDirer(benchDir{}) +var _ = fs.HandleReadDirAller(benchDir{}) func (benchDir) Attr() fuse.Attr { return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0555} } -func (d benchDir) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (d benchDir) Lookup(ctx context.Context, name string) (fs.Node, error) { if name == "bench" { return benchFile{conf: d.conf}, nil } return nil, fuse.ENOENT } -func (benchDir) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { +func (benchDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { l := []fuse.Dirent{ {Inode: 2, Name: "bench", Type: fuse.DT_File}, } @@ -75,7 +76,7 @@ func (benchFile) Attr() fuse.Attr { return fuse.Attr{Inode: 2, Mode: 0644, Size: 9999999999999999} } -func (f benchFile) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr) (fs.Handle, fuse.Error) { +func (f benchFile) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) { if f.conf.directIO { resp.Flags |= fuse.OpenDirectIO } @@ -84,17 +85,17 @@ func (f benchFile) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs. return f, nil } -func (benchFile) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fs.Intr) fuse.Error { +func (benchFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { resp.Data = resp.Data[:cap(resp.Data)] return nil } -func (benchFile) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.Intr) fuse.Error { +func (benchFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error { resp.Size = len(req.Data) return nil } -func (benchFile) Fsync(req *fuse.FsyncRequest, intr fs.Intr) fuse.Error { +func (benchFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) error { return nil } diff --git a/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/record.go b/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/record.go index 1e1d2bd92..ed8bcd342 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/record.go +++ b/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/record.go @@ -6,6 +6,7 @@ import ( "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs" + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) // Writes gathers data from FUSE Write calls. @@ -15,7 +16,7 @@ type Writes struct { var _ = fs.HandleWriter(&Writes{}) -func (w *Writes) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.Intr) fuse.Error { +func (w *Writes) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error { n, err := w.buf.Write(req.Data) resp.Size = n if err != nil { @@ -62,7 +63,7 @@ type Flushes struct { var _ = fs.HandleFlusher(&Flushes{}) -func (r *Flushes) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error { +func (r *Flushes) Flush(ctx context.Context, req *fuse.FlushRequest) error { r.rec.Mark() return nil } @@ -120,7 +121,7 @@ type Setattrs struct { var _ = fs.NodeSetattrer(&Setattrs{}) -func (r *Setattrs) Setattr(req *fuse.SetattrRequest, resp *fuse.SetattrResponse, intr fs.Intr) fuse.Error { +func (r *Setattrs) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { tmp := *req r.rec.RecordRequest(&tmp) return nil @@ -141,7 +142,7 @@ type Fsyncs struct { var _ = fs.NodeFsyncer(&Fsyncs{}) -func (r *Fsyncs) Fsync(req *fuse.FsyncRequest, intr fs.Intr) fuse.Error { +func (r *Fsyncs) Fsync(ctx context.Context, req *fuse.FsyncRequest) error { tmp := *req r.rec.RecordRequest(&tmp) return nil @@ -164,7 +165,7 @@ var _ = fs.NodeMkdirer(&Mkdirs{}) // Mkdir records the request and returns an error. Most callers should // wrap this call in a function that returns a more useful result. -func (r *Mkdirs) Mkdir(req *fuse.MkdirRequest, intr fs.Intr) (fs.Node, fuse.Error) { +func (r *Mkdirs) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { tmp := *req r.rec.RecordRequest(&tmp) return nil, fuse.EIO @@ -189,7 +190,7 @@ var _ = fs.NodeSymlinker(&Symlinks{}) // Symlink records the request and returns an error. Most callers should // wrap this call in a function that returns a more useful result. -func (r *Symlinks) Symlink(req *fuse.SymlinkRequest, intr fs.Intr) (fs.Node, fuse.Error) { +func (r *Symlinks) Symlink(ctx context.Context, req *fuse.SymlinkRequest) (fs.Node, error) { tmp := *req r.rec.RecordRequest(&tmp) return nil, fuse.EIO @@ -214,7 +215,7 @@ var _ = fs.NodeLinker(&Links{}) // Link records the request and returns an error. Most callers should // wrap this call in a function that returns a more useful result. -func (r *Links) Link(req *fuse.LinkRequest, old fs.Node, intr fs.Intr) (fs.Node, fuse.Error) { +func (r *Links) Link(ctx context.Context, req *fuse.LinkRequest, old fs.Node) (fs.Node, error) { tmp := *req r.rec.RecordRequest(&tmp) return nil, fuse.EIO @@ -239,7 +240,7 @@ var _ = fs.NodeMknoder(&Mknods{}) // Mknod records the request and returns an error. Most callers should // wrap this call in a function that returns a more useful result. -func (r *Mknods) Mknod(req *fuse.MknodRequest, intr fs.Intr) (fs.Node, fuse.Error) { +func (r *Mknods) Mknod(ctx context.Context, req *fuse.MknodRequest) (fs.Node, error) { tmp := *req r.rec.RecordRequest(&tmp) return nil, fuse.EIO @@ -264,7 +265,7 @@ var _ = fs.NodeOpener(&Opens{}) // Open records the request and returns an error. Most callers should // wrap this call in a function that returns a more useful result. -func (r *Opens) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr) (fs.Handle, fuse.Error) { +func (r *Opens) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) { tmp := *req r.rec.RecordRequest(&tmp) return nil, fuse.EIO @@ -289,7 +290,7 @@ var _ = fs.NodeGetxattrer(&Getxattrs{}) // Getxattr records the request and returns an error. Most callers should // wrap this call in a function that returns a more useful result. -func (r *Getxattrs) Getxattr(req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse, intr fs.Intr) fuse.Error { +func (r *Getxattrs) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error { tmp := *req r.rec.RecordRequest(&tmp) return fuse.ENODATA @@ -314,7 +315,7 @@ var _ = fs.NodeListxattrer(&Listxattrs{}) // Listxattr records the request and returns an error. Most callers should // wrap this call in a function that returns a more useful result. -func (r *Listxattrs) Listxattr(req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse, intr fs.Intr) fuse.Error { +func (r *Listxattrs) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error { tmp := *req r.rec.RecordRequest(&tmp) return fuse.ENODATA @@ -339,7 +340,7 @@ var _ = fs.NodeSetxattrer(&Setxattrs{}) // Setxattr records the request and returns an error. Most callers should // wrap this call in a function that returns a more useful result. -func (r *Setxattrs) Setxattr(req *fuse.SetxattrRequest, intr fs.Intr) fuse.Error { +func (r *Setxattrs) Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error { tmp := *req r.rec.RecordRequest(&tmp) return nil @@ -364,7 +365,7 @@ var _ = fs.NodeRemovexattrer(&Removexattrs{}) // Removexattr records the request and returns an error. Most callers should // wrap this call in a function that returns a more useful result. -func (r *Removexattrs) Removexattr(req *fuse.RemovexattrRequest, intr fs.Intr) fuse.Error { +func (r *Removexattrs) Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error { tmp := *req r.rec.RecordRequest(&tmp) return nil diff --git a/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/wait.go b/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/wait.go index bca723772..1bbe092ac 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/wait.go +++ b/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/wait.go @@ -6,6 +6,7 @@ import ( "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs" + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) type nothing struct{} @@ -27,7 +28,7 @@ func (r *ReleaseWaiter) init() { }) } -func (r *ReleaseWaiter) Release(req *fuse.ReleaseRequest, intr fs.Intr) fuse.Error { +func (r *ReleaseWaiter) Release(ctx context.Context, req *fuse.ReleaseRequest) error { r.init() close(r.seen) return nil diff --git a/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/testfs.go b/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/testfs.go index 9596804c7..8b1cda730 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/testfs.go +++ b/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/testfs.go @@ -14,7 +14,7 @@ type SimpleFS struct { var _ = fs.FS(SimpleFS{}) -func (f SimpleFS) Root() (fs.Node, fuse.Error) { +func (f SimpleFS) Root() (fs.Node, error) { return f.Node, nil } diff --git a/Godeps/_workspace/src/bazil.org/fuse/fs/serve.go b/Godeps/_workspace/src/bazil.org/fuse/fs/serve.go index f0185140e..8b89e00e7 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/fs/serve.go +++ b/Godeps/_workspace/src/bazil.org/fuse/fs/serve.go @@ -11,6 +11,8 @@ import ( "strings" "sync" "time" + + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) import ( @@ -25,33 +27,26 @@ const ( // TODO: FINISH DOCS -// An Intr is a channel that signals that a request has been interrupted. -// Being able to receive from the channel means the request has been -// interrupted. -type Intr chan struct{} - -func (Intr) String() string { return "fuse.Intr" } - // An FS is the interface required of a file system. // // Other FUSE requests can be handled by implementing methods from the // FS* interfaces, for example FSIniter. type FS interface { // Root is called to obtain the Node for the file system root. - Root() (Node, fuse.Error) + Root() (Node, error) } type FSIniter interface { // Init is called to initialize the FUSE connection. // It can inspect the request and adjust the response as desired. // Init must return promptly. - Init(req *fuse.InitRequest, resp *fuse.InitResponse, intr Intr) fuse.Error + Init(ctx context.Context, req *fuse.InitRequest, resp *fuse.InitResponse) error } type FSStatfser interface { // Statfs is called to obtain file system metadata. // It should write that data to resp. - Statfs(req *fuse.StatfsRequest, resp *fuse.StatfsResponse, intr Intr) fuse.Error + Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error } type FSDestroyer interface { @@ -101,38 +96,38 @@ type NodeGetattrer interface { // // If this method is not implemented, the attributes will be // generated based on Attr(), with zero values filled in. - Getattr(req *fuse.GetattrRequest, resp *fuse.GetattrResponse, intr Intr) fuse.Error + Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error } type NodeSetattrer interface { // Setattr sets the standard metadata for the receiver. - Setattr(req *fuse.SetattrRequest, resp *fuse.SetattrResponse, intr Intr) fuse.Error + Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error } type NodeSymlinker interface { // Symlink creates a new symbolic link in the receiver, which must be a directory. // // TODO is the above true about directories? - Symlink(req *fuse.SymlinkRequest, intr Intr) (Node, fuse.Error) + Symlink(ctx context.Context, req *fuse.SymlinkRequest) (Node, error) } // This optional request will be called only for symbolic link nodes. type NodeReadlinker interface { // Readlink reads a symbolic link. - Readlink(req *fuse.ReadlinkRequest, intr Intr) (string, fuse.Error) + Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) } type NodeLinker interface { // Link creates a new directory entry in the receiver based on an // existing Node. Receiver must be a directory. - Link(req *fuse.LinkRequest, old Node, intr Intr) (Node, fuse.Error) + Link(ctx context.Context, req *fuse.LinkRequest, old Node) (Node, error) } type NodeRemover interface { // Remove removes the entry with the given name from // the receiver, which must be a directory. The entry to be removed // may correspond to a file (unlink) or to a directory (rmdir). - Remove(req *fuse.RemoveRequest, intr Intr) fuse.Error + Remove(ctx context.Context, req *fuse.RemoveRequest) error } type NodeAccesser interface { @@ -144,7 +139,7 @@ type NodeAccesser interface { // call but not the open(2) system call. If Access is not // implemented, the Node behaves as if it always returns nil // (permission granted), relying on checks in Open instead. - Access(req *fuse.AccessRequest, intr Intr) fuse.Error + Access(ctx context.Context, req *fuse.AccessRequest) error } type NodeStringLookuper interface { @@ -154,30 +149,37 @@ type NodeStringLookuper interface { // the directory, Lookup should return nil, err. // // Lookup need not to handle the names "." and "..". - Lookup(name string, intr Intr) (Node, fuse.Error) + Lookup(ctx context.Context, name string) (Node, error) } type NodeRequestLookuper interface { // Lookup looks up a specific entry in the receiver. // See NodeStringLookuper for more. - Lookup(req *fuse.LookupRequest, resp *fuse.LookupResponse, intr Intr) (Node, fuse.Error) + Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (Node, error) } type NodeMkdirer interface { - Mkdir(req *fuse.MkdirRequest, intr Intr) (Node, fuse.Error) + Mkdir(ctx context.Context, req *fuse.MkdirRequest) (Node, error) } type NodeOpener interface { - // Open opens the receiver. + // Open opens the receiver. After a successful open, a client + // process has a file descriptor referring to this Handle. + // + // Open can also be also called on non-files. For example, + // directories are Opened for ReadDir or fchdir(2). + // + // If this method is not implemented, the open will always + // succeed, and the Node itself will be used as the Handle. + // // XXX note about access. XXX OpenFlags. - // XXX note that the Node may be a file or directory. - Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr Intr) (Handle, fuse.Error) + Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (Handle, error) } type NodeCreater interface { // Create creates a new directory entry in the receiver, which // must be a directory. - Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr Intr) (Node, Handle, fuse.Error) + Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (Node, Handle, error) } type NodeForgetter interface { @@ -185,16 +187,16 @@ type NodeForgetter interface { } type NodeRenamer interface { - Rename(req *fuse.RenameRequest, newDir Node, intr Intr) fuse.Error + Rename(ctx context.Context, req *fuse.RenameRequest, newDir Node) error } type NodeMknoder interface { - Mknod(req *fuse.MknodRequest, intr Intr) (Node, fuse.Error) + Mknod(ctx context.Context, req *fuse.MknodRequest) (Node, error) } // TODO this should be on Handle not Node type NodeFsyncer interface { - Fsync(req *fuse.FsyncRequest, intr Intr) fuse.Error + Fsync(ctx context.Context, req *fuse.FsyncRequest) error } type NodeGetxattrer interface { @@ -204,18 +206,18 @@ type NodeGetxattrer interface { // If there is no xattr by that name, returns fuse.ENODATA. This // will be translated to the platform-specific correct error code // by the framework. - Getxattr(req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse, intr Intr) fuse.Error + Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error } type NodeListxattrer interface { // Listxattr lists the extended attributes recorded for the node. - Listxattr(req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse, intr Intr) fuse.Error + Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error } type NodeSetxattrer interface { // Setxattr sets an extended attribute with the given name and // value for the node. - Setxattr(req *fuse.SetxattrRequest, intr Intr) fuse.Error + Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error } type NodeRemovexattrer interface { @@ -224,7 +226,7 @@ type NodeRemovexattrer interface { // If there is no xattr by that name, returns fuse.ENODATA. This // will be translated to the platform-specific correct error code // by the framework. - Removexattr(req *fuse.RemovexattrRequest, intr Intr) fuse.Error + Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error } var startTime = time.Now() @@ -254,8 +256,8 @@ func nodeAttr(n Node) (attr fuse.Attr) { // pertaining to all methods. // // Other FUSE requests can be handled by implementing methods from the -// Node* interfaces. The most common to implement are -// HandleReader, HandleReadDirer, and HandleWriter. +// Handle* interfaces. The most common to implement are HandleReader, +// HandleReadDirer, and HandleWriter. // // TODO implement methods: Getlk, Setlk, Setlkw type Handle interface { @@ -265,27 +267,27 @@ type HandleFlusher interface { // Flush is called each time the file or directory is closed. // Because there can be multiple file descriptors referring to a // single opened file, Flush can be called multiple times. - Flush(req *fuse.FlushRequest, intr Intr) fuse.Error + Flush(ctx context.Context, req *fuse.FlushRequest) error } type HandleReadAller interface { - ReadAll(intr Intr) ([]byte, fuse.Error) + ReadAll(ctx context.Context) ([]byte, error) } -type HandleReadDirer interface { - ReadDir(intrt Intr) ([]fuse.Dirent, fuse.Error) +type HandleReadDirAller interface { + ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) } type HandleReader interface { - Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr Intr) fuse.Error + Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error } type HandleWriter interface { - Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr Intr) fuse.Error + Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error } type HandleReleaser interface { - Release(req *fuse.ReleaseRequest, intr Intr) fuse.Error + Release(ctx context.Context, req *fuse.ReleaseRequest) error } type Server struct { @@ -363,7 +365,7 @@ type serveConn struct { type serveRequest struct { Request fuse.Request - Intr Intr + cancel func() } type serveNode struct { @@ -621,8 +623,10 @@ func (m *renameNewDirNodeNotFound) String() string { } func (c *serveConn) serve(r fuse.Request) { - intr := make(Intr) - req := &serveRequest{Request: r, Intr: intr} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + req := &serveRequest{Request: r, cancel: cancel} c.debug(request{ Op: opName(r), @@ -661,7 +665,6 @@ func (c *serveConn) serve(r fuse.Request) { // Otherwise everything wedges. TODO: Report to OSXFUSE? // // TODO this might have been because of missing done() calls - intr = nil } else { c.req[hdr.ID] = req } @@ -713,7 +716,7 @@ func (c *serveConn) serve(r fuse.Request) { Flags: fuse.InitBigWrites, } if fs, ok := c.fs.(FSIniter); ok { - if err := fs.Init(r, s, intr); err != nil { + if err := fs.Init(ctx, r, s); err != nil { done(err) r.RespondError(err) break @@ -725,7 +728,7 @@ func (c *serveConn) serve(r fuse.Request) { case *fuse.StatfsRequest: s := &fuse.StatfsResponse{} if fs, ok := c.fs.(FSStatfser); ok { - if err := fs.Statfs(r, s, intr); err != nil { + if err := fs.Statfs(ctx, r, s); err != nil { done(err) r.RespondError(err) break @@ -738,7 +741,7 @@ func (c *serveConn) serve(r fuse.Request) { case *fuse.GetattrRequest: s := &fuse.GetattrResponse{} if n, ok := node.(NodeGetattrer); ok { - if err := n.Getattr(r, s, intr); err != nil { + if err := n.Getattr(ctx, r, s); err != nil { done(err) r.RespondError(err) break @@ -753,7 +756,7 @@ func (c *serveConn) serve(r fuse.Request) { case *fuse.SetattrRequest: s := &fuse.SetattrResponse{} if n, ok := node.(NodeSetattrer); ok { - if err := n.Setattr(r, s, intr); err != nil { + if err := n.Setattr(ctx, r, s); err != nil { done(err) r.RespondError(err) break @@ -778,7 +781,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.EIO) break } - n2, err := n.Symlink(r, intr) + n2, err := n.Symlink(ctx, r) if err != nil { done(err) r.RespondError(err) @@ -795,7 +798,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.EIO) break } - target, err := n.Readlink(r, intr) + target, err := n.Readlink(ctx, r) if err != nil { done(err) r.RespondError(err) @@ -826,7 +829,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.EIO) break } - n2, err := n.Link(r, oldNode.node, intr) + n2, err := n.Link(ctx, r, oldNode.node) if err != nil { done(err) r.RespondError(err) @@ -844,7 +847,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.EIO) break } - err := n.Remove(r, intr) + err := n.Remove(ctx, r) if err != nil { done(err) r.RespondError(err) @@ -855,7 +858,7 @@ func (c *serveConn) serve(r fuse.Request) { case *fuse.AccessRequest: if n, ok := node.(NodeAccesser); ok { - if err := n.Access(r, intr); err != nil { + if err := n.Access(ctx, r); err != nil { done(err) r.RespondError(err) break @@ -866,12 +869,12 @@ func (c *serveConn) serve(r fuse.Request) { case *fuse.LookupRequest: var n2 Node - var err fuse.Error + var err error s := &fuse.LookupResponse{} if n, ok := node.(NodeStringLookuper); ok { - n2, err = n.Lookup(r.Name, intr) + n2, err = n.Lookup(ctx, r.Name) } else if n, ok := node.(NodeRequestLookuper); ok { - n2, err = n.Lookup(r, s, intr) + n2, err = n.Lookup(ctx, r, s) } else { done(fuse.ENOENT) r.RespondError(fuse.ENOENT) @@ -894,7 +897,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.EPERM) break } - n2, err := n.Mkdir(r, intr) + n2, err := n.Mkdir(ctx, r) if err != nil { done(err) r.RespondError(err) @@ -908,7 +911,7 @@ func (c *serveConn) serve(r fuse.Request) { s := &fuse.OpenResponse{} var h2 Handle if n, ok := node.(NodeOpener); ok { - hh, err := n.Open(r, s, intr) + hh, err := n.Open(ctx, r, s) if err != nil { done(err) r.RespondError(err) @@ -931,7 +934,7 @@ func (c *serveConn) serve(r fuse.Request) { break } s := &fuse.CreateResponse{OpenResponse: fuse.OpenResponse{}} - n2, h2, err := n.Create(r, s, intr) + n2, h2, err := n.Create(ctx, r, s) if err != nil { done(err) r.RespondError(err) @@ -950,7 +953,7 @@ func (c *serveConn) serve(r fuse.Request) { break } s := &fuse.GetxattrResponse{} - err := n.Getxattr(r, s, intr) + err := n.Getxattr(ctx, r, s) if err != nil { done(err) r.RespondError(err) @@ -972,7 +975,7 @@ func (c *serveConn) serve(r fuse.Request) { break } s := &fuse.ListxattrResponse{} - err := n.Listxattr(r, s, intr) + err := n.Listxattr(ctx, r, s) if err != nil { done(err) r.RespondError(err) @@ -993,7 +996,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.ENOTSUP) break } - err := n.Setxattr(r, intr) + err := n.Setxattr(ctx, r) if err != nil { done(err) r.RespondError(err) @@ -1009,7 +1012,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.ENOTSUP) break } - err := n.Removexattr(r, intr) + err := n.Removexattr(ctx, r) if err != nil { done(err) r.RespondError(err) @@ -1041,9 +1044,9 @@ func (c *serveConn) serve(r fuse.Request) { s := &fuse.ReadResponse{Data: make([]byte, 0, r.Size)} if r.Dir { - if h, ok := handle.(HandleReadDirer); ok { + if h, ok := handle.(HandleReadDirAller); ok { if shandle.readData == nil { - dirs, err := h.ReadDir(intr) + dirs, err := h.ReadDirAll(ctx) if err != nil { done(err) r.RespondError(err) @@ -1066,7 +1069,7 @@ func (c *serveConn) serve(r fuse.Request) { } else { if h, ok := handle.(HandleReadAller); ok { if shandle.readData == nil { - data, err := h.ReadAll(intr) + data, err := h.ReadAll(ctx) if err != nil { done(err) r.RespondError(err) @@ -1089,7 +1092,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.EIO) break } - if err := h.Read(r, s, intr); err != nil { + if err := h.Read(ctx, r, s); err != nil { done(err) r.RespondError(err) break @@ -1108,7 +1111,7 @@ func (c *serveConn) serve(r fuse.Request) { s := &fuse.WriteResponse{} if h, ok := shandle.handle.(HandleWriter); ok { - if err := h.Write(r, s, intr); err != nil { + if err := h.Write(ctx, r, s); err != nil { done(err) r.RespondError(err) break @@ -1130,7 +1133,7 @@ func (c *serveConn) serve(r fuse.Request) { handle := shandle.handle if h, ok := handle.(HandleFlusher); ok { - if err := h.Flush(r, intr); err != nil { + if err := h.Flush(ctx, r); err != nil { done(err) r.RespondError(err) break @@ -1152,7 +1155,7 @@ func (c *serveConn) serve(r fuse.Request) { c.dropHandle(r.Handle) if h, ok := handle.(HandleReleaser); ok { - if err := h.Release(r, intr); err != nil { + if err := h.Release(ctx, r); err != nil { done(err) r.RespondError(err) break @@ -1190,7 +1193,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.EIO) break } - err := n.Rename(r, newDirNode.node, intr) + err := n.Rename(ctx, r, newDirNode.node) if err != nil { done(err) r.RespondError(err) @@ -1206,7 +1209,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.EIO) break } - n2, err := n.Mknod(r, intr) + n2, err := n.Mknod(ctx, r) if err != nil { done(err) r.RespondError(err) @@ -1224,7 +1227,7 @@ func (c *serveConn) serve(r fuse.Request) { r.RespondError(fuse.EIO) break } - err := n.Fsync(r, intr) + err := n.Fsync(ctx, r) if err != nil { done(err) r.RespondError(err) @@ -1236,9 +1239,9 @@ func (c *serveConn) serve(r fuse.Request) { case *fuse.InterruptRequest: c.meta.Lock() ireq := c.req[r.IntrID] - if ireq != nil && ireq.Intr != nil { - close(ireq.Intr) - ireq.Intr = nil + if ireq != nil && ireq.cancel != nil { + ireq.cancel() + ireq.cancel = nil } c.meta.Unlock() done(nil) @@ -1288,7 +1291,7 @@ type dataHandle struct { data []byte } -func (d *dataHandle) ReadAll(intr Intr) ([]byte, fuse.Error) { +func (d *dataHandle) ReadAll(ctx context.Context) ([]byte, error) { return d.data, nil } diff --git a/Godeps/_workspace/src/bazil.org/fuse/fs/serve_test.go b/Godeps/_workspace/src/bazil.org/fuse/fs/serve_test.go index c1468c3b0..0026cad09 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/fs/serve_test.go +++ b/Godeps/_workspace/src/bazil.org/fuse/fs/serve_test.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "flag" + "io" "io/ioutil" "log" "os" @@ -22,6 +23,7 @@ import ( "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fuseutil" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/syscallx" + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) // TO TEST: @@ -75,11 +77,11 @@ func (f childMapFS) Attr() fuse.Attr { return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0777} } -func (f childMapFS) Root() (fs.Node, fuse.Error) { +func (f childMapFS) Root() (fs.Node, error) { return f, nil } -func (f childMapFS) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (f childMapFS) Lookup(ctx context.Context, name string) (fs.Node, error) { child, ok := f[name] if !ok { return nil, fuse.ENOENT @@ -101,7 +103,7 @@ func (f fifo) Attr() fuse.Attr { return fuse.Attr{Mode: os.ModeNamedPipe | 0666} type badRootFS struct{} -func (badRootFS) Root() (fs.Node, fuse.Error) { +func (badRootFS) Root() (fs.Node, error) { // pick a really distinct error, to identify it later return nil, fuse.Errno(syscall.ENAMETOOLONG) } @@ -131,7 +133,7 @@ func TestRootErr(t *testing.T) { type testStatFS struct{} -func (f testStatFS) Root() (fs.Node, fuse.Error) { +func (f testStatFS) Root() (fs.Node, error) { return f, nil } @@ -139,7 +141,7 @@ func (f testStatFS) Attr() fuse.Attr { return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0777} } -func (f testStatFS) Statfs(req *fuse.StatfsRequest, resp *fuse.StatfsResponse, int fs.Intr) fuse.Error { +func (f testStatFS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error { resp.Blocks = 42 resp.Files = 13 return nil @@ -194,7 +196,7 @@ func TestStatfs(t *testing.T) { type root struct{} -func (f root) Root() (fs.Node, fuse.Error) { +func (f root) Root() (fs.Node, error) { return f, nil } @@ -253,7 +255,7 @@ func (readAll) Attr() fuse.Attr { } } -func (readAll) ReadAll(intr fs.Intr) ([]byte, fuse.Error) { +func (readAll) ReadAll(ctx context.Context) ([]byte, error) { return []byte(hi), nil } @@ -291,7 +293,7 @@ func (readWithHandleRead) Attr() fuse.Attr { } } -func (readWithHandleRead) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fs.Intr) fuse.Error { +func (readWithHandleRead) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { fuseutil.HandleRead(req, resp, []byte(hi)) return nil } @@ -466,8 +468,8 @@ type mkdir1 struct { record.Mkdirs } -func (f *mkdir1) Mkdir(req *fuse.MkdirRequest, intr fs.Intr) (fs.Node, fuse.Error) { - f.Mkdirs.Mkdir(req, intr) +func (f *mkdir1) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { + f.Mkdirs.Mkdir(ctx, req) return &mkdir1{}, nil } @@ -505,7 +507,7 @@ type create1 struct { f create1file } -func (f *create1) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr fs.Intr) (fs.Node, fs.Handle, fuse.Error) { +func (f *create1) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) { if req.Name != "foo" { log.Printf("ERROR create1.Create unexpected name: %q\n", req.Name) return nil, nil, fuse.EPERM @@ -577,7 +579,7 @@ type create3 struct { fooRemoved record.MarkRecorder } -func (f *create3) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr fs.Intr) (fs.Node, fs.Handle, fuse.Error) { +func (f *create3) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) { if req.Name != "foo" { log.Printf("ERROR create3.Create unexpected name: %q\n", req.Name) return nil, nil, fuse.EPERM @@ -586,14 +588,14 @@ func (f *create3) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, int return &f.f, &f.f, nil } -func (f *create3) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (f *create3) Lookup(ctx context.Context, name string) (fs.Node, error) { if f.fooCreated.Recorded() && !f.fooRemoved.Recorded() && name == "foo" { return &f.f, nil } return nil, fuse.ENOENT } -func (f *create3) Remove(r *fuse.RemoveRequest, intr fs.Intr) fuse.Error { +func (f *create3) Remove(ctx context.Context, r *fuse.RemoveRequest) error { if f.fooCreated.Recorded() && !f.fooRemoved.Recorded() && r.Name == "foo" && !r.Dir { f.fooRemoved.Mark() @@ -637,7 +639,7 @@ type symlink1link struct { target string } -func (f symlink1link) Readlink(*fuse.ReadlinkRequest, fs.Intr) (string, fuse.Error) { +func (f symlink1link) Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) { return f.target, nil } @@ -646,8 +648,8 @@ type symlink1 struct { record.Symlinks } -func (f *symlink1) Symlink(req *fuse.SymlinkRequest, intr fs.Intr) (fs.Node, fuse.Error) { - f.Symlinks.Symlink(req, intr) +func (f *symlink1) Symlink(ctx context.Context, req *fuse.SymlinkRequest) (fs.Node, error) { + f.Symlinks.Symlink(ctx, req) return symlink1link{target: req.Target}, nil } @@ -688,15 +690,15 @@ type link1 struct { record.Links } -func (f *link1) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (f *link1) Lookup(ctx context.Context, name string) (fs.Node, error) { if name == "old" { return fstestutil.File{}, nil } return nil, fuse.ENOENT } -func (f *link1) Link(r *fuse.LinkRequest, old fs.Node, intr fs.Intr) (fs.Node, fuse.Error) { - f.Links.Link(r, old, intr) +func (f *link1) Link(ctx context.Context, r *fuse.LinkRequest, old fs.Node) (fs.Node, error) { + f.Links.Link(ctx, r, old) return fstestutil.File{}, nil } @@ -732,14 +734,14 @@ type rename1 struct { renamed record.Counter } -func (f *rename1) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (f *rename1) Lookup(ctx context.Context, name string) (fs.Node, error) { if name == "old" { return fstestutil.File{}, nil } return nil, fuse.ENOENT } -func (f *rename1) Rename(r *fuse.RenameRequest, newDir fs.Node, intr fs.Intr) fuse.Error { +func (f *rename1) Rename(ctx context.Context, r *fuse.RenameRequest, newDir fs.Node) error { if r.OldName == "old" && r.NewName == "new" && newDir == f { f.renamed.Inc() return nil @@ -776,8 +778,8 @@ type mknod1 struct { record.Mknods } -func (f *mknod1) Mknod(r *fuse.MknodRequest, intr fs.Intr) (fs.Node, fuse.Error) { - f.Mknods.Mknod(r, intr) +func (f *mknod1) Mknod(ctx context.Context, r *fuse.MknodRequest) (fs.Node, error) { + f.Mknods.Mknod(ctx, r) return fifo{}, nil } @@ -829,7 +831,7 @@ func (dataHandleTest) Attr() fuse.Attr { } } -func (dataHandleTest) Open(*fuse.OpenRequest, *fuse.OpenResponse, fs.Intr) (fs.Handle, fuse.Error) { +func (dataHandleTest) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) { return fs.DataHandle([]byte(hi)), nil } @@ -868,12 +870,12 @@ func (interrupt) Attr() fuse.Attr { } } -func (it *interrupt) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fs.Intr) fuse.Error { +func (it *interrupt) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { select { case it.hanging <- struct{}{}: default: } - <-intr + <-ctx.Done() return fuse.EINTR } @@ -1063,13 +1065,13 @@ func TestTruncateWithOpen(t *testing.T) { t.Logf("Got request: %#v", gotr) } -// Test readdir +// Test readdir calling ReadDirAll -type readdir struct { +type readDirAll struct { fstestutil.Dir } -func (d *readdir) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { +func (d *readDirAll) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { return []fuse.Dirent{ {Name: "one", Inode: 11, Type: fuse.DT_Dir}, {Name: "three", Inode: 13}, @@ -1077,9 +1079,9 @@ func (d *readdir) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { }, nil } -func TestReadDir(t *testing.T) { +func TestReadDirAll(t *testing.T) { t.Parallel() - f := &readdir{} + f := &readDirAll{} mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f}) if err != nil { t.Fatal(err) @@ -1113,6 +1115,37 @@ func TestReadDir(t *testing.T) { } } +// Test readdir without any ReadDir methods implemented. + +type readDirNotImplemented struct { + fstestutil.Dir +} + +func TestReadDirNotImplemented(t *testing.T) { + t.Parallel() + f := &readDirNotImplemented{} + mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f}) + if err != nil { + t.Fatal(err) + } + defer mnt.Close() + + fil, err := os.Open(mnt.Dir) + if err != nil { + t.Error(err) + return + } + defer fil.Close() + + // go Readdir is just Readdirnames + Lstat, there's no point in + // testing that here; we have no consumption API for the real + // dirent data + names, err := fil.Readdirnames(100) + if len(names) > 0 || err != io.EOF { + t.Fatalf("expected EOF got names=%v err=%v", names, err) + } +} + // Test Chmod. type chmod struct { @@ -1120,12 +1153,12 @@ type chmod struct { record.Setattrs } -func (f *chmod) Setattr(req *fuse.SetattrRequest, resp *fuse.SetattrResponse, intr fs.Intr) fuse.Error { +func (f *chmod) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { if !req.Valid.Mode() { log.Printf("setattr not a chmod: %v", req.Valid) return fuse.EIO } - f.Setattrs.Setattr(req, resp, intr) + f.Setattrs.Setattr(ctx, req, resp) return nil } @@ -1156,8 +1189,8 @@ type open struct { record.Opens } -func (f *open) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr) (fs.Handle, fuse.Error) { - f.Opens.Open(req, resp, intr) +func (f *open) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) { + f.Opens.Open(ctx, req, resp) // pick a really distinct error, to identify it later return nil, fuse.Errno(syscall.ENAMETOOLONG) @@ -1265,8 +1298,8 @@ type getxattr struct { record.Getxattrs } -func (f *getxattr) Getxattr(req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse, intr fs.Intr) fuse.Error { - f.Getxattrs.Getxattr(req, resp, intr) +func (f *getxattr) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error { + f.Getxattrs.Getxattr(ctx, req, resp) resp.Xattr = []byte("hello, world") return nil } @@ -1302,7 +1335,7 @@ type getxattrTooSmall struct { fstestutil.File } -func (f *getxattrTooSmall) Getxattr(req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse, intr fs.Intr) fuse.Error { +func (f *getxattrTooSmall) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error { resp.Xattr = []byte("hello, world") return nil } @@ -1333,7 +1366,7 @@ type getxattrSize struct { fstestutil.File } -func (f *getxattrSize) Getxattr(req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse, intr fs.Intr) fuse.Error { +func (f *getxattrSize) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error { resp.Xattr = []byte("hello, world") return nil } @@ -1364,8 +1397,8 @@ type listxattr struct { record.Listxattrs } -func (f *listxattr) Listxattr(req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse, intr fs.Intr) fuse.Error { - f.Listxattrs.Listxattr(req, resp, intr) +func (f *listxattr) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error { + f.Listxattrs.Listxattr(ctx, req, resp) resp.Append("one", "two") return nil } @@ -1404,7 +1437,7 @@ type listxattrTooSmall struct { fstestutil.File } -func (f *listxattrTooSmall) Listxattr(req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse, intr fs.Intr) fuse.Error { +func (f *listxattrTooSmall) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error { resp.Xattr = []byte("one\x00two\x00") return nil } @@ -1435,7 +1468,7 @@ type listxattrSize struct { fstestutil.File } -func (f *listxattrSize) Listxattr(req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse, intr fs.Intr) fuse.Error { +func (f *listxattrSize) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error { resp.Xattr = []byte("one\x00two\x00") return nil } @@ -1551,7 +1584,7 @@ type defaultErrno struct { fstestutil.Dir } -func (f defaultErrno) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (f defaultErrno) Lookup(ctx context.Context, name string) (fs.Node, error) { return nil, errors.New("bork") } @@ -1595,7 +1628,7 @@ func (myCustomError) Error() string { return "bork" } -func (f customErrNode) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (f customErrNode) Lookup(ctx context.Context, name string) (fs.Node, error) { return nil, myCustomError{ ErrorNumber: fuse.Errno(syscall.ENAMETOOLONG), } @@ -1638,12 +1671,12 @@ func (f *inMemoryFile) Attr() fuse.Attr { } } -func (f *inMemoryFile) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fs.Intr) fuse.Error { +func (f *inMemoryFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { fuseutil.HandleRead(req, resp, f.data) return nil } -func (f *inMemoryFile) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.Intr) fuse.Error { +func (f *inMemoryFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error { resp.Size = copy(f.data[req.Offset:], req.Data) return nil } @@ -1744,13 +1777,13 @@ type directRead struct { // explicitly not defining Attr and setting Size -func (f directRead) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr) (fs.Handle, fuse.Error) { +func (f directRead) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) { // do not allow the kernel to use page cache resp.Flags |= fuse.OpenDirectIO return f, nil } -func (directRead) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fs.Intr) fuse.Error { +func (directRead) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { fuseutil.HandleRead(req, resp, []byte(hi)) return nil } diff --git a/Godeps/_workspace/src/bazil.org/fuse/fs/tree.go b/Godeps/_workspace/src/bazil.org/fuse/fs/tree.go index 13d6aa73e..fe4086e4d 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/fs/tree.go +++ b/Godeps/_workspace/src/bazil.org/fuse/fs/tree.go @@ -6,6 +6,8 @@ import ( "os" pathpkg "path" "strings" + + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) import ( @@ -18,7 +20,7 @@ type Tree struct { tree } -func (t *Tree) Root() (Node, fuse.Error) { +func (t *Tree) Root() (Node, error) { return &t.tree, nil } @@ -79,7 +81,7 @@ func (t *tree) Attr() fuse.Attr { return fuse.Attr{Mode: os.ModeDir | 0555} } -func (t *tree) Lookup(name string, intr Intr) (Node, fuse.Error) { +func (t *tree) Lookup(ctx context.Context, name string) (Node, error) { n := t.lookup(name) if n != nil { return n, nil @@ -87,7 +89,7 @@ func (t *tree) Lookup(name string, intr Intr) (Node, fuse.Error) { return nil, fuse.ENOENT } -func (t *tree) ReadDir(intr Intr) ([]fuse.Dirent, fuse.Error) { +func (t *tree) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { var out []fuse.Dirent for _, d := range t.dir { out = append(out, fuse.Dirent{Name: d.name}) diff --git a/Godeps/_workspace/src/bazil.org/fuse/fuse.go b/Godeps/_workspace/src/bazil.org/fuse/fuse.go index 5d6ed81df..7b5244479 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/fuse.go +++ b/Godeps/_workspace/src/bazil.org/fuse/fuse.go @@ -45,7 +45,7 @@ // The required and optional methods for the FS, Node, and Handle interfaces // have the general form // -// Op(req *OpRequest, resp *OpResponse, intr Intr) Error +// Op(ctx context.Context, req *OpRequest, resp *OpResponse) Error // // where Op is the name of a FUSE operation. Op reads request parameters // from req and writes results to resp. An operation whose only result is @@ -53,18 +53,29 @@ // service methods simultaneously; the methods being called are responsible // for appropriate synchronization. // +// Errors +// +// Operations can return errors. The FUSE interface can only +// communicate POSIX errno error numbers to file system clients, the +// message is not visible to file system clients. The returned error +// can implement ErrorNumber to control the errno returned. Without +// ErrorNumber, a generic errno (EIO) is returned. +// +// Errors messages will be visible in the debug log as part of the +// response. +// // Interrupted Operations // // In some file systems, some operations // may take an undetermined amount of time. For example, a Read waiting for // a network message or a matching Write might wait indefinitely. If the request -// is cancelled and no longer needed, the package will close intr, a chan struct{}. -// Blocking operations should select on a receive from intr and attempt to +// is cancelled and no longer needed, the context will be cancelled. +// Blocking operations should select on a receive from ctx.Done() and attempt to // abort the operation early if the receive succeeds (meaning the channel is closed). // To indicate that the operation failed because it was aborted, return fuse.EINTR. // -// If an operation does not block for an indefinite amount of time, the intr parameter -// can be ignored. +// If an operation does not block for an indefinite amount of time, supporting +// cancellation is not necessary. // // Authentication // @@ -151,7 +162,7 @@ type Request interface { Hdr() *Header // RespondError responds to the request with the given error. - RespondError(Error) + RespondError(error) String() string } @@ -206,18 +217,6 @@ func (h *Header) respondData(out *outHeader, n uintptr, data []byte) { putMessage(h.msg) } -// An Error is a FUSE error. -// -// Errors messages will be visible in the debug log as part of the -// response. -// -// The FUSE interface can only communicate POSIX errno error numbers -// to file system clients, the message is not visible to file system -// clients. The returned error can implement ErrorNumber to control -// the errno returned. Without ErrorNumber, a generic errno (EIO) is -// returned. -type Error error - // An ErrorNumber is an error with a specific error number. // // Operations may return an error value that implements ErrorNumber to @@ -267,7 +266,6 @@ var errnoNames = map[Errno]string{ type Errno syscall.Errno var _ = ErrorNumber(Errno(0)) -var _ = Error(Errno(0)) var _ = error(Errno(0)) func (e Errno) Errno() Errno { @@ -297,7 +295,7 @@ func (e Errno) MarshalText() ([]byte, error) { return []byte(s), nil } -func (h *Header) RespondError(err Error) { +func (h *Header) RespondError(err error) { errno := DefaultErrno if ferr, ok := err.(ErrorNumber); ok { errno = ferr.Errno() @@ -1197,7 +1195,7 @@ func (r *GetxattrRequest) Respond(resp *GetxattrResponse) { } } -func (r *GetxattrRequest) RespondError(err Error) { +func (r *GetxattrRequest) RespondError(err error) { err = translateGetxattrError(err) r.Header.RespondError(err) } @@ -1273,7 +1271,7 @@ func (r *RemovexattrRequest) Respond() { r.respond(out, unsafe.Sizeof(*out)) } -func (r *RemovexattrRequest) RespondError(err Error) { +func (r *RemovexattrRequest) RespondError(err error) { err = translateGetxattrError(err) r.Header.RespondError(err) } @@ -1323,7 +1321,7 @@ func (r *SetxattrRequest) Respond() { r.respond(out, unsafe.Sizeof(*out)) } -func (r *SetxattrRequest) RespondError(err Error) { +func (r *SetxattrRequest) RespondError(err error) { err = translateGetxattrError(err) r.Header.RespondError(err) } diff --git a/Godeps/_workspace/src/bazil.org/fuse/hellofs/hello.go b/Godeps/_workspace/src/bazil.org/fuse/hellofs/hello.go index 7e74f9fed..dc8f3727f 100644 --- a/Godeps/_workspace/src/bazil.org/fuse/hellofs/hello.go +++ b/Godeps/_workspace/src/bazil.org/fuse/hellofs/hello.go @@ -10,6 +10,7 @@ import ( "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs" _ "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil" + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) var Usage = func() { @@ -55,7 +56,7 @@ func main() { // FS implements the hello world file system. type FS struct{} -func (FS) Root() (fs.Node, fuse.Error) { +func (FS) Root() (fs.Node, error) { return Dir{}, nil } @@ -66,7 +67,7 @@ func (Dir) Attr() fuse.Attr { return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0555} } -func (Dir) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) { if name == "hello" { return File{}, nil } @@ -77,7 +78,7 @@ var dirDirs = []fuse.Dirent{ {Inode: 2, Name: "hello", Type: fuse.DT_File}, } -func (Dir) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { +func (Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { return dirDirs, nil } @@ -90,6 +91,6 @@ func (File) Attr() fuse.Attr { return fuse.Attr{Inode: 2, Mode: 0444, Size: uint64(len(greeting))} } -func (File) ReadAll(intr fs.Intr) ([]byte, fuse.Error) { +func (File) ReadAll(ctx context.Context) ([]byte, error) { return []byte(greeting), nil } diff --git a/Godeps/_workspace/src/bazil.org/fuse/hellofs/hellofs b/Godeps/_workspace/src/bazil.org/fuse/hellofs/hellofs deleted file mode 100644 index 641c0ef1c..000000000 Binary files a/Godeps/_workspace/src/bazil.org/fuse/hellofs/hellofs and /dev/null differ diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index 6214bf7d5..85fc5c2e8 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -145,7 +145,7 @@ func CreateRoot(n *core.IpfsNode, keys []ci.PrivKey, ipfsroot string) (*Root, er } // Root constructs the Root of the filesystem, a Root object. -func (f FileSystem) Root() (fs.Node, fuse.Error) { +func (f FileSystem) Root() (fs.Node, error) { return f.RootNode, nil } @@ -167,7 +167,7 @@ func (*Root) Attr() fuse.Attr { } // Lookup performs a lookup under this node. -func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (s *Root) Lookup(name string, ctx context.Context) (fs.Node, error) { switch name { case "mach_kernel", ".hidden", "._.": // Just quiet some log noise on OS X. @@ -196,7 +196,7 @@ func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { } // ReadDir reads a particular directory. Disallowed for root. -func (r *Root) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { +func (r *Root) ReadDir(ctx context.Context) ([]fuse.Dirent, error) { listing := []fuse.Dirent{ fuse.Dirent{ Name: "local", @@ -285,7 +285,7 @@ func (s *Node) Attr() fuse.Attr { } // Lookup performs a lookup under this node. -func (s *Node) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (s *Node) Lookup(name string, ctx context.Context) (fs.Node, error) { nodes, err := s.Ipfs.Resolver.ResolveLinks(s.Nd, []string{name}) if err != nil { // todo: make this error more versatile. @@ -315,7 +315,7 @@ func (n *Node) makeChild(name string, node *mdag.Node) *Node { } // ReadDir reads the link structure as directory entries -func (s *Node) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { +func (s *Node) ReadDir(ctx context.Context) ([]fuse.Dirent, error) { entries := make([]fuse.Dirent, len(s.Nd.Links)) for i, link := range s.Nd.Links { n := link.Name @@ -331,20 +331,7 @@ func (s *Node) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { return nil, fuse.ENOENT } -func (s *Node) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fs.Intr) fuse.Error { - // intr will be closed by fuse if the request is cancelled. turn this into a context. - ctx, cancel := context.WithCancel(context.TODO()) - defer cancel() // make sure all operations we started close. - - // we wait on intr and cancel our context if it closes. - go func() { - select { - case <-intr: // closed by fuse - cancel() // cancel our context - case <-ctx.Done(): - } - }() - +func (s *Node) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, ctx context.Context) error { k, err := s.Nd.Key() if err != nil { return err @@ -373,7 +360,7 @@ func (s *Node) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fs.Intr return err // may be non-nil / not succeeded } -func (n *Node) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.Intr) fuse.Error { +func (n *Node) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, ctx context.Context) error { // log.Debugf("ipns: Node Write [%s]: flags = %s, offset = %d, size = %d", n.name, req.Flags.String(), req.Offset, len(req.Data)) if IpnsReadonly { log.Debug("Attempted to write on readonly ipns filesystem.") @@ -396,7 +383,7 @@ func (n *Node) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.I return nil } -func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error { +func (n *Node) Flush(req *fuse.FlushRequest, ctx context.Context) error { if IpnsReadonly { return nil } @@ -483,11 +470,11 @@ func (n *Node) republishRoot() error { return nil } -func (n *Node) Fsync(req *fuse.FsyncRequest, intr fs.Intr) fuse.Error { +func (n *Node) Fsync(req *fuse.FsyncRequest, ctx context.Context) error { return nil } -func (n *Node) Mkdir(req *fuse.MkdirRequest, intr fs.Intr) (fs.Node, fuse.Error) { +func (n *Node) Mkdir(req *fuse.MkdirRequest, ctx context.Context) (fs.Node, error) { if IpnsReadonly { return nil, fuse.EPERM } @@ -521,7 +508,7 @@ func (n *Node) Mkdir(req *fuse.MkdirRequest, intr fs.Intr) (fs.Node, fuse.Error) return child, nil } -func (n *Node) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr) (fs.Handle, fuse.Error) { +func (n *Node) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, ctx context.Context) (fs.Handle, error) { //log.Debug("[%s] Received open request! flags = %s", n.name, req.Flags.String()) //TODO: check open flags and truncate if necessary if req.Flags&fuse.OpenTruncate != 0 { @@ -534,11 +521,11 @@ func (n *Node) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr return n, nil } -func (n *Node) Mknod(req *fuse.MknodRequest, intr fs.Intr) (fs.Node, fuse.Error) { +func (n *Node) Mknod(req *fuse.MknodRequest, ctx context.Context) (fs.Node, error) { return nil, nil } -func (n *Node) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr fs.Intr) (fs.Node, fs.Handle, fuse.Error) { +func (n *Node) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, ctx context.Context) (fs.Node, fs.Handle, error) { if IpnsReadonly { log.Debug("Attempted to call Create on a readonly filesystem.") return nil, nil, fuse.EPERM @@ -568,7 +555,7 @@ func (n *Node) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr f return child, child, nil } -func (n *Node) Remove(req *fuse.RemoveRequest, intr fs.Intr) fuse.Error { +func (n *Node) Remove(req *fuse.RemoveRequest, ctx context.Context) error { if IpnsReadonly { return fuse.EPERM } @@ -591,7 +578,7 @@ func (n *Node) Remove(req *fuse.RemoveRequest, intr fs.Intr) fuse.Error { return nil } -func (n *Node) Rename(req *fuse.RenameRequest, newDir fs.Node, intr fs.Intr) fuse.Error { +func (n *Node) Rename(req *fuse.RenameRequest, newDir fs.Node, ctx context.Context) error { if IpnsReadonly { log.Debug("Attempted to call Rename on a readonly filesystem.") return fuse.EPERM diff --git a/fuse/ipns/link_unix.go b/fuse/ipns/link_unix.go index fcaada15f..209849679 100644 --- a/fuse/ipns/link_unix.go +++ b/fuse/ipns/link_unix.go @@ -4,7 +4,7 @@ import ( "os" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse" - "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs" + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) type Link struct { @@ -18,7 +18,7 @@ func (l *Link) Attr() fuse.Attr { } } -func (l *Link) Readlink(req *fuse.ReadlinkRequest, intr fs.Intr) (string, fuse.Error) { +func (l *Link) Readlink(req *fuse.ReadlinkRequest, ctx context.Context) (string, error) { log.Debugf("ReadLink: %s", l.Target) return l.Target, nil } diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index e5982a5ea..c8646856f 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -35,7 +35,7 @@ func NewFileSystem(ipfs *core.IpfsNode) *FileSystem { } // Root constructs the Root of the filesystem, a Root object. -func (f FileSystem) Root() (fs.Node, fuse.Error) { +func (f FileSystem) Root() (fs.Node, error) { return &Root{Ipfs: f.Ipfs}, nil } @@ -50,7 +50,7 @@ func (*Root) Attr() fuse.Attr { } // Lookup performs a lookup under this node. -func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (s *Root) Lookup(name string, ctx context.Context) (fs.Node, error) { log.Debugf("Root Lookup: '%s'", name) switch name { case "mach_kernel", ".hidden", "._.": @@ -68,7 +68,7 @@ func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { } // ReadDir reads a particular directory. Disallowed for root. -func (*Root) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { +func (*Root) ReadDir(ctx context.Context) ([]fuse.Dirent, error) { log.Debug("Read Root.") return nil, fuse.EPERM } @@ -116,7 +116,7 @@ func (s *Node) Attr() fuse.Attr { } // Lookup performs a lookup under this node. -func (s *Node) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { +func (s *Node) Lookup(name string, ctx context.Context) (fs.Node, error) { log.Debugf("Lookup '%s'", name) nodes, err := s.Ipfs.Resolver.ResolveLinks(s.Nd, []string{name}) if err != nil { @@ -128,7 +128,7 @@ func (s *Node) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { } // ReadDir reads the link structure as directory entries -func (s *Node) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { +func (s *Node) ReadDir(ctx context.Context) ([]fuse.Dirent, error) { log.Debug("Node ReadDir") entries := make([]fuse.Dirent, len(s.Nd.Links)) for i, link := range s.Nd.Links { @@ -145,19 +145,7 @@ func (s *Node) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { return nil, fuse.ENOENT } -func (s *Node) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fs.Intr) fuse.Error { - // intr will be closed by fuse if the request is cancelled. turn this into a context. - ctx, cancel := context.WithCancel(context.TODO()) - defer cancel() // make sure all operations we started close. - - // we wait on intr and cancel our context if it closes. - go func() { - select { - case <-intr: // closed by fuse - cancel() // cancel our context - case <-ctx.Done(): - } - }() +func (s *Node) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, ctx context.Context) error { k, err := s.Nd.Key() if err != nil {