mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-29 01:12:24 +08:00
godeps: update bazil.org/fuse
fuse: Attr() now has a Context parameter and error return value ~GOPATH/src/bazil.org/fuse:master$ git shortlog 48c34fb7780b88aca1696bf865508f6703aa47f1..e4fcc9a2c7567d1c42861deebeb483315d222262 Tommi Virtanen (8): Remove dead code Make saveLookup take Context, return error Make serveNode.attr take Context, return error Make nodeAttr take Context, return error API change: Move attribute validity time inside Attr Set attribute validity default time in one place API change: Attr method takes Context, returns error Set LookupResponse validity times up front, instead of after the handler
This commit is contained in:
2
Godeps/Godeps.json
generated
2
Godeps/Godeps.json
generated
@ -7,7 +7,7 @@
|
|||||||
"Deps": [
|
"Deps": [
|
||||||
{
|
{
|
||||||
"ImportPath": "bazil.org/fuse",
|
"ImportPath": "bazil.org/fuse",
|
||||||
"Rev": "79d103f5608724e3ccee0a10daccc5e4aff03591"
|
"Rev": "e4fcc9a2c7567d1c42861deebeb483315d222262"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "code.google.com/p/go-uuid/uuid",
|
"ImportPath": "code.google.com/p/go-uuid/uuid",
|
||||||
|
2
Godeps/_workspace/src/bazil.org/fuse/LICENSE
generated
vendored
2
Godeps/_workspace/src/bazil.org/fuse/LICENSE
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2013, 2014 Tommi Virtanen.
|
Copyright (c) 2013-2015 Tommi Virtanen.
|
||||||
Copyright (c) 2009, 2011, 2012 The Go Authors.
|
Copyright (c) 2009, 2011, 2012 The Go Authors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
2
Godeps/_workspace/src/bazil.org/fuse/README.md
generated
vendored
2
Godeps/_workspace/src/bazil.org/fuse/README.md
generated
vendored
@ -15,7 +15,7 @@ Here’s how to get going:
|
|||||||
|
|
||||||
Website: http://bazil.org/fuse/
|
Website: http://bazil.org/fuse/
|
||||||
|
|
||||||
Github repository: https://github.com/bazillion/fuse
|
Github repository: https://github.com/bazil/fuse
|
||||||
|
|
||||||
API docs: http://godoc.org/bazil.org/fuse
|
API docs: http://godoc.org/bazil.org/fuse
|
||||||
|
|
||||||
|
13
Godeps/_workspace/src/bazil.org/fuse/fs/bench/bench_test.go
generated
vendored
13
Godeps/_workspace/src/bazil.org/fuse/fs/bench/bench_test.go
generated
vendored
@ -43,8 +43,10 @@ var _ = fs.NodeStringLookuper(benchDir{})
|
|||||||
var _ = fs.Handle(benchDir{})
|
var _ = fs.Handle(benchDir{})
|
||||||
var _ = fs.HandleReadDirAller(benchDir{})
|
var _ = fs.HandleReadDirAller(benchDir{})
|
||||||
|
|
||||||
func (benchDir) Attr() fuse.Attr {
|
func (benchDir) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0555}
|
a.Inode = 1
|
||||||
|
a.Mode = os.ModeDir | 0555
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d benchDir) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
func (d benchDir) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
||||||
@ -72,8 +74,11 @@ var _ = fs.Handle(benchFile{})
|
|||||||
var _ = fs.HandleReader(benchFile{})
|
var _ = fs.HandleReader(benchFile{})
|
||||||
var _ = fs.HandleWriter(benchFile{})
|
var _ = fs.HandleWriter(benchFile{})
|
||||||
|
|
||||||
func (benchFile) Attr() fuse.Attr {
|
func (benchFile) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{Inode: 2, Mode: 0644, Size: 9999999999999999}
|
a.Inode = 2
|
||||||
|
a.Mode = 0644
|
||||||
|
a.Size = 9999999999999999
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f benchFile) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
|
func (f benchFile) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
|
||||||
|
15
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/testfs.go
generated
vendored
15
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/testfs.go
generated
vendored
@ -22,12 +22,18 @@ func (f SimpleFS) Root() (fs.Node, error) {
|
|||||||
// File can be embedded in a struct to make it look like a file.
|
// File can be embedded in a struct to make it look like a file.
|
||||||
type File struct{}
|
type File struct{}
|
||||||
|
|
||||||
func (f File) Attr() fuse.Attr { return fuse.Attr{Mode: 0666} }
|
func (f File) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
|
a.Mode = 0666
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Dir can be embedded in a struct to make it look like a directory.
|
// Dir can be embedded in a struct to make it look like a directory.
|
||||||
type Dir struct{}
|
type Dir struct{}
|
||||||
|
|
||||||
func (f Dir) Attr() fuse.Attr { return fuse.Attr{Mode: os.ModeDir | 0777} }
|
func (f Dir) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
|
a.Mode = os.ModeDir | 0777
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ChildMap is a directory with child nodes looked up from a map.
|
// ChildMap is a directory with child nodes looked up from a map.
|
||||||
type ChildMap map[string]fs.Node
|
type ChildMap map[string]fs.Node
|
||||||
@ -35,8 +41,9 @@ type ChildMap map[string]fs.Node
|
|||||||
var _ = fs.Node(ChildMap{})
|
var _ = fs.Node(ChildMap{})
|
||||||
var _ = fs.NodeStringLookuper(ChildMap{})
|
var _ = fs.NodeStringLookuper(ChildMap{})
|
||||||
|
|
||||||
func (f ChildMap) Attr() fuse.Attr {
|
func (f ChildMap) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{Mode: os.ModeDir | 0777}
|
a.Mode = os.ModeDir | 0777
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f ChildMap) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
func (f ChildMap) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
||||||
|
156
Godeps/_workspace/src/bazil.org/fuse/fs/serve.go
generated
vendored
156
Godeps/_workspace/src/bazil.org/fuse/fs/serve.go
generated
vendored
@ -7,7 +7,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -55,9 +57,6 @@ type FSDestroyer interface {
|
|||||||
// Linux only sends this request for block device backed (fuseblk)
|
// Linux only sends this request for block device backed (fuseblk)
|
||||||
// filesystems, to allow them to flush writes to disk before the
|
// filesystems, to allow them to flush writes to disk before the
|
||||||
// unmount completes.
|
// unmount completes.
|
||||||
//
|
|
||||||
// On normal FUSE filesystems, use Forget of the root Node to
|
|
||||||
// do actions at unmount time.
|
|
||||||
Destroy()
|
Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +86,8 @@ type FSInodeGenerator interface {
|
|||||||
// Other FUSE requests can be handled by implementing methods from the
|
// Other FUSE requests can be handled by implementing methods from the
|
||||||
// Node* interfaces, for example NodeOpener.
|
// Node* interfaces, for example NodeOpener.
|
||||||
type Node interface {
|
type Node interface {
|
||||||
Attr() fuse.Attr
|
// Attr fills attr with the standard metadata for the node.
|
||||||
|
Attr(ctx context.Context, attr *fuse.Attr) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeGetattrer interface {
|
type NodeGetattrer interface {
|
||||||
@ -192,6 +192,11 @@ type NodeCreater interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NodeForgetter interface {
|
type NodeForgetter interface {
|
||||||
|
// Forget about this node. This node will not receive further
|
||||||
|
// method calls.
|
||||||
|
//
|
||||||
|
// Forget is not necessarily seen on unmount, as all nodes are
|
||||||
|
// implicitly forgotten as part part of the unmount.
|
||||||
Forget()
|
Forget()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,24 +241,17 @@ type NodeRemovexattrer interface {
|
|||||||
|
|
||||||
var startTime = time.Now()
|
var startTime = time.Now()
|
||||||
|
|
||||||
func nodeAttr(n Node) (attr fuse.Attr) {
|
func nodeAttr(ctx context.Context, n Node, attr *fuse.Attr) error {
|
||||||
attr = n.Attr()
|
attr.Valid = attrValidTime
|
||||||
if attr.Nlink == 0 {
|
|
||||||
attr.Nlink = 1
|
attr.Nlink = 1
|
||||||
}
|
|
||||||
if attr.Atime.IsZero() {
|
|
||||||
attr.Atime = startTime
|
attr.Atime = startTime
|
||||||
}
|
|
||||||
if attr.Mtime.IsZero() {
|
|
||||||
attr.Mtime = startTime
|
attr.Mtime = startTime
|
||||||
}
|
|
||||||
if attr.Ctime.IsZero() {
|
|
||||||
attr.Ctime = startTime
|
attr.Ctime = startTime
|
||||||
}
|
|
||||||
if attr.Crtime.IsZero() {
|
|
||||||
attr.Crtime = startTime
|
attr.Crtime = startTime
|
||||||
|
if err := n.Attr(ctx, attr); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Handle is the interface required of an opened file or directory.
|
// A Handle is the interface required of an opened file or directory.
|
||||||
@ -323,12 +321,17 @@ type Server struct {
|
|||||||
//
|
//
|
||||||
// See fuse.Debug for the rules that log functions must follow.
|
// See fuse.Debug for the rules that log functions must follow.
|
||||||
Debug func(msg interface{})
|
Debug func(msg interface{})
|
||||||
|
|
||||||
|
// Used to ensure worker goroutines finish before Serve returns
|
||||||
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve serves the FUSE connection by making calls to the methods
|
// Serve serves the FUSE connection by making calls to the methods
|
||||||
// of fs and the Nodes and Handles it makes available. It returns only
|
// of fs and the Nodes and Handles it makes available. It returns only
|
||||||
// when the connection has been closed or an unexpected error occurs.
|
// when the connection has been closed or an unexpected error occurs.
|
||||||
func (s *Server) Serve(c *fuse.Conn) error {
|
func (s *Server) Serve(c *fuse.Conn) error {
|
||||||
|
defer s.wg.Wait() // Wait for worker goroutines to complete before return
|
||||||
|
|
||||||
sc := serveConn{
|
sc := serveConn{
|
||||||
fs: s.FS,
|
fs: s.FS,
|
||||||
debug: s.Debug,
|
debug: s.Debug,
|
||||||
@ -358,7 +361,11 @@ func (s *Server) Serve(c *fuse.Conn) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
go sc.serve(req)
|
s.wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer s.wg.Done()
|
||||||
|
sc.serve(req)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -398,12 +405,12 @@ type serveNode struct {
|
|||||||
refs uint64
|
refs uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sn *serveNode) attr() (attr fuse.Attr) {
|
func (sn *serveNode) attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
attr = nodeAttr(sn.node)
|
err := nodeAttr(ctx, sn.node, attr)
|
||||||
if attr.Inode == 0 {
|
if attr.Inode == 0 {
|
||||||
attr.Inode = sn.inode
|
attr.Inode = sn.inode
|
||||||
}
|
}
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
type serveHandle struct {
|
type serveHandle struct {
|
||||||
@ -646,6 +653,30 @@ func (m *renameNewDirNodeNotFound) String() string {
|
|||||||
return fmt.Sprintf("In RenameRequest (request %#x), node %d not found", m.Request.Hdr().ID, m.In.NewDir)
|
return fmt.Sprintf("In RenameRequest (request %#x), node %d not found", m.Request.Hdr().ID, m.In.NewDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type handlerPanickedError struct {
|
||||||
|
Request interface{}
|
||||||
|
Err interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ error = handlerPanickedError{}
|
||||||
|
|
||||||
|
func (h handlerPanickedError) Error() string {
|
||||||
|
return fmt.Sprintf("handler panicked: %v", h.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ fuse.ErrorNumber = handlerPanickedError{}
|
||||||
|
|
||||||
|
func (h handlerPanickedError) Errno() fuse.Errno {
|
||||||
|
if err, ok := h.Err.(fuse.ErrorNumber); ok {
|
||||||
|
return err.Errno()
|
||||||
|
}
|
||||||
|
return fuse.DefaultErrno
|
||||||
|
}
|
||||||
|
|
||||||
|
func initLookupResponse(s *fuse.LookupResponse) {
|
||||||
|
s.EntryValid = entryValidTime
|
||||||
|
}
|
||||||
|
|
||||||
func (c *serveConn) serve(r fuse.Request) {
|
func (c *serveConn) serve(r fuse.Request) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -725,6 +756,22 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
c.meta.Unlock()
|
c.meta.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if rec := recover(); rec != nil {
|
||||||
|
const size = 1 << 16
|
||||||
|
buf := make([]byte, size)
|
||||||
|
n := runtime.Stack(buf, false)
|
||||||
|
buf = buf[:n]
|
||||||
|
log.Printf("fuse: panic in handler for %v: %v\n%s", r, rec, buf)
|
||||||
|
err := handlerPanickedError{
|
||||||
|
Request: r,
|
||||||
|
Err: rec,
|
||||||
|
}
|
||||||
|
done(err)
|
||||||
|
r.RespondError(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
switch r := r.(type) {
|
switch r := r.(type) {
|
||||||
default:
|
default:
|
||||||
// Note: To FUSE, ENOSYS means "this server never implements this request."
|
// Note: To FUSE, ENOSYS means "this server never implements this request."
|
||||||
@ -771,8 +818,11 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s.AttrValid = attrValidTime
|
if err := snode.attr(ctx, &s.Attr); err != nil {
|
||||||
s.Attr = snode.attr()
|
done(err)
|
||||||
|
r.RespondError(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
done(s)
|
done(s)
|
||||||
r.Respond(s)
|
r.Respond(s)
|
||||||
@ -790,15 +840,17 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.AttrValid == 0 {
|
if err := snode.attr(ctx, &s.Attr); err != nil {
|
||||||
s.AttrValid = attrValidTime
|
done(err)
|
||||||
|
r.RespondError(err)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
s.Attr = snode.attr()
|
|
||||||
done(s)
|
done(s)
|
||||||
r.Respond(s)
|
r.Respond(s)
|
||||||
|
|
||||||
case *fuse.SymlinkRequest:
|
case *fuse.SymlinkRequest:
|
||||||
s := &fuse.SymlinkResponse{}
|
s := &fuse.SymlinkResponse{}
|
||||||
|
initLookupResponse(&s.LookupResponse)
|
||||||
n, ok := node.(NodeSymlinker)
|
n, ok := node.(NodeSymlinker)
|
||||||
if !ok {
|
if !ok {
|
||||||
done(fuse.EIO) // XXX or EPERM like Mkdir?
|
done(fuse.EIO) // XXX or EPERM like Mkdir?
|
||||||
@ -811,7 +863,11 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
r.RespondError(err)
|
r.RespondError(err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c.saveLookup(&s.LookupResponse, snode, r.NewName, n2)
|
if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.NewName, n2); err != nil {
|
||||||
|
done(err)
|
||||||
|
r.RespondError(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
done(s)
|
done(s)
|
||||||
r.Respond(s)
|
r.Respond(s)
|
||||||
|
|
||||||
@ -860,7 +916,12 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
s := &fuse.LookupResponse{}
|
s := &fuse.LookupResponse{}
|
||||||
c.saveLookup(s, snode, r.NewName, n2)
|
initLookupResponse(s)
|
||||||
|
if err := c.saveLookup(ctx, s, snode, r.NewName, n2); err != nil {
|
||||||
|
done(err)
|
||||||
|
r.RespondError(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
done(s)
|
done(s)
|
||||||
r.Respond(s)
|
r.Respond(s)
|
||||||
|
|
||||||
@ -895,6 +956,7 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
var n2 Node
|
var n2 Node
|
||||||
var err error
|
var err error
|
||||||
s := &fuse.LookupResponse{}
|
s := &fuse.LookupResponse{}
|
||||||
|
initLookupResponse(s)
|
||||||
if n, ok := node.(NodeStringLookuper); ok {
|
if n, ok := node.(NodeStringLookuper); ok {
|
||||||
n2, err = n.Lookup(ctx, r.Name)
|
n2, err = n.Lookup(ctx, r.Name)
|
||||||
} else if n, ok := node.(NodeRequestLookuper); ok {
|
} else if n, ok := node.(NodeRequestLookuper); ok {
|
||||||
@ -909,12 +971,17 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
r.RespondError(err)
|
r.RespondError(err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c.saveLookup(s, snode, r.Name, n2)
|
if err := c.saveLookup(ctx, s, snode, r.Name, n2); err != nil {
|
||||||
|
done(err)
|
||||||
|
r.RespondError(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
done(s)
|
done(s)
|
||||||
r.Respond(s)
|
r.Respond(s)
|
||||||
|
|
||||||
case *fuse.MkdirRequest:
|
case *fuse.MkdirRequest:
|
||||||
s := &fuse.MkdirResponse{}
|
s := &fuse.MkdirResponse{}
|
||||||
|
initLookupResponse(&s.LookupResponse)
|
||||||
n, ok := node.(NodeMkdirer)
|
n, ok := node.(NodeMkdirer)
|
||||||
if !ok {
|
if !ok {
|
||||||
done(fuse.EPERM)
|
done(fuse.EPERM)
|
||||||
@ -927,7 +994,11 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
r.RespondError(err)
|
r.RespondError(err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c.saveLookup(&s.LookupResponse, snode, r.Name, n2)
|
if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil {
|
||||||
|
done(err)
|
||||||
|
r.RespondError(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
done(s)
|
done(s)
|
||||||
r.Respond(s)
|
r.Respond(s)
|
||||||
|
|
||||||
@ -958,13 +1029,18 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
s := &fuse.CreateResponse{OpenResponse: fuse.OpenResponse{}}
|
s := &fuse.CreateResponse{OpenResponse: fuse.OpenResponse{}}
|
||||||
|
initLookupResponse(&s.LookupResponse)
|
||||||
n2, h2, err := n.Create(ctx, r, s)
|
n2, h2, err := n.Create(ctx, r, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
done(err)
|
done(err)
|
||||||
r.RespondError(err)
|
r.RespondError(err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c.saveLookup(&s.LookupResponse, snode, r.Name, n2)
|
if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil {
|
||||||
|
done(err)
|
||||||
|
r.RespondError(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
s.Handle = c.saveHandle(h2, hdr.Node)
|
s.Handle = c.saveHandle(h2, hdr.Node)
|
||||||
done(s)
|
done(s)
|
||||||
r.Respond(s)
|
r.Respond(s)
|
||||||
@ -1240,7 +1316,12 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
s := &fuse.LookupResponse{}
|
s := &fuse.LookupResponse{}
|
||||||
c.saveLookup(s, snode, r.Name, n2)
|
initLookupResponse(s)
|
||||||
|
if err := c.saveLookup(ctx, s, snode, r.Name, n2); err != nil {
|
||||||
|
done(err)
|
||||||
|
r.RespondError(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
done(s)
|
done(s)
|
||||||
r.Respond(s)
|
r.Respond(s)
|
||||||
|
|
||||||
@ -1290,19 +1371,16 @@ func (c *serveConn) serve(r fuse.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *serveConn) saveLookup(s *fuse.LookupResponse, snode *serveNode, elem string, n2 Node) {
|
func (c *serveConn) saveLookup(ctx context.Context, s *fuse.LookupResponse, snode *serveNode, elem string, n2 Node) error {
|
||||||
s.Attr = nodeAttr(n2)
|
if err := nodeAttr(ctx, n2, &s.Attr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if s.Attr.Inode == 0 {
|
if s.Attr.Inode == 0 {
|
||||||
s.Attr.Inode = c.dynamicInode(snode.inode, elem)
|
s.Attr.Inode = c.dynamicInode(snode.inode, elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Node, s.Generation = c.saveNode(s.Attr.Inode, n2)
|
s.Node, s.Generation = c.saveNode(s.Attr.Inode, n2)
|
||||||
if s.EntryValid == 0 {
|
return nil
|
||||||
s.EntryValid = entryValidTime
|
|
||||||
}
|
|
||||||
if s.AttrValid == 0 {
|
|
||||||
s.AttrValid = attrValidTime
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DataHandle returns a read-only Handle that satisfies reads
|
// DataHandle returns a read-only Handle that satisfies reads
|
||||||
|
182
Godeps/_workspace/src/bazil.org/fuse/fs/serve_test.go
generated
vendored
182
Godeps/_workspace/src/bazil.org/fuse/fs/serve_test.go
generated
vendored
@ -10,6 +10,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -42,12 +43,18 @@ type symlink struct {
|
|||||||
target string
|
target string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f symlink) Attr() fuse.Attr { return fuse.Attr{Mode: os.ModeSymlink | 0666} }
|
func (f symlink) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
|
a.Mode = os.ModeSymlink | 0666
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// fifo can be embedded in a struct to make it look like a named pipe.
|
// fifo can be embedded in a struct to make it look like a named pipe.
|
||||||
type fifo struct{}
|
type fifo struct{}
|
||||||
|
|
||||||
func (f fifo) Attr() fuse.Attr { return fuse.Attr{Mode: os.ModeNamedPipe | 0666} }
|
func (f fifo) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
|
a.Mode = os.ModeNamedPipe | 0666
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type badRootFS struct{}
|
type badRootFS struct{}
|
||||||
|
|
||||||
@ -79,14 +86,59 @@ func TestRootErr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testPanic struct{}
|
||||||
|
|
||||||
|
type panicSentinel struct{}
|
||||||
|
|
||||||
|
var _ error = panicSentinel{}
|
||||||
|
|
||||||
|
func (panicSentinel) Error() string { return "just a test" }
|
||||||
|
|
||||||
|
var _ fuse.ErrorNumber = panicSentinel{}
|
||||||
|
|
||||||
|
func (panicSentinel) Errno() fuse.Errno {
|
||||||
|
return fuse.Errno(syscall.ENAMETOOLONG)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f testPanic) Root() (fs.Node, error) {
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f testPanic) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
|
a.Inode = 1
|
||||||
|
a.Mode = os.ModeDir | 0777
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f testPanic) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error {
|
||||||
|
panic(panicSentinel{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPanic(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
mnt, err := fstestutil.MountedT(t, testPanic{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer mnt.Close()
|
||||||
|
|
||||||
|
var st syscall.Statfs_t
|
||||||
|
err = syscall.Statfs(mnt.Dir, &st)
|
||||||
|
if g, e := err, syscall.ENAMETOOLONG; g != e {
|
||||||
|
t.Fatalf("wrong error from panicking handler: %v != %v", g, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type testStatFS struct{}
|
type testStatFS struct{}
|
||||||
|
|
||||||
func (f testStatFS) Root() (fs.Node, error) {
|
func (f testStatFS) Root() (fs.Node, error) {
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f testStatFS) Attr() fuse.Attr {
|
func (f testStatFS) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0777}
|
a.Inode = 1
|
||||||
|
a.Mode = os.ModeDir | 0777
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f testStatFS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error {
|
func (f testStatFS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error {
|
||||||
@ -148,8 +200,10 @@ func (f root) Root() (fs.Node, error) {
|
|||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (root) Attr() fuse.Attr {
|
func (root) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0555}
|
a.Inode = 1
|
||||||
|
a.Mode = os.ModeDir | 0555
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStatRoot(t *testing.T) {
|
func TestStatRoot(t *testing.T) {
|
||||||
@ -196,11 +250,10 @@ type readAll struct {
|
|||||||
|
|
||||||
const hi = "hello, world"
|
const hi = "hello, world"
|
||||||
|
|
||||||
func (readAll) Attr() fuse.Attr {
|
func (readAll) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{
|
a.Mode = 0666
|
||||||
Mode: 0666,
|
a.Size = uint64(len(hi))
|
||||||
Size: uint64(len(hi)),
|
return nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (readAll) ReadAll(ctx context.Context) ([]byte, error) {
|
func (readAll) ReadAll(ctx context.Context) ([]byte, error) {
|
||||||
@ -234,11 +287,10 @@ type readWithHandleRead struct {
|
|||||||
fstestutil.File
|
fstestutil.File
|
||||||
}
|
}
|
||||||
|
|
||||||
func (readWithHandleRead) Attr() fuse.Attr {
|
func (readWithHandleRead) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{
|
a.Mode = 0666
|
||||||
Mode: 0666,
|
a.Size = uint64(len(hi))
|
||||||
Size: uint64(len(hi)),
|
return nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (readWithHandleRead) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
func (readWithHandleRead) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
||||||
@ -772,11 +824,10 @@ type dataHandleTest struct {
|
|||||||
fstestutil.File
|
fstestutil.File
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dataHandleTest) Attr() fuse.Attr {
|
func (dataHandleTest) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{
|
a.Mode = 0666
|
||||||
Mode: 0666,
|
a.Size = uint64(len(hi))
|
||||||
Size: uint64(len(hi)),
|
return nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dataHandleTest) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
|
func (dataHandleTest) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
|
||||||
@ -811,11 +862,10 @@ type interrupt struct {
|
|||||||
hanging chan struct{}
|
hanging chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (interrupt) Attr() fuse.Attr {
|
func (interrupt) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{
|
a.Mode = 0666
|
||||||
Mode: 0666,
|
a.Size = 1
|
||||||
Size: 1,
|
return nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *interrupt) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
func (it *interrupt) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
||||||
@ -1609,22 +1659,38 @@ func TestCustomErrno(t *testing.T) {
|
|||||||
// Test Mmap writing
|
// Test Mmap writing
|
||||||
|
|
||||||
type inMemoryFile struct {
|
type inMemoryFile struct {
|
||||||
|
mu sync.Mutex
|
||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *inMemoryFile) Attr() fuse.Attr {
|
func (f *inMemoryFile) bytes() []byte {
|
||||||
return fuse.Attr{
|
f.mu.Lock()
|
||||||
Mode: 0666,
|
defer f.mu.Unlock()
|
||||||
Size: uint64(len(f.data)),
|
|
||||||
|
return f.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *inMemoryFile) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
|
f.mu.Lock()
|
||||||
|
defer f.mu.Unlock()
|
||||||
|
|
||||||
|
a.Mode = 0666
|
||||||
|
a.Size = uint64(len(f.data))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *inMemoryFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
func (f *inMemoryFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
||||||
|
f.mu.Lock()
|
||||||
|
defer f.mu.Unlock()
|
||||||
|
|
||||||
fuseutil.HandleRead(req, resp, f.data)
|
fuseutil.HandleRead(req, resp, f.data)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *inMemoryFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error {
|
func (f *inMemoryFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error {
|
||||||
|
f.mu.Lock()
|
||||||
|
defer f.mu.Unlock()
|
||||||
|
|
||||||
resp.Size = copy(f.data[req.Offset:], req.Data)
|
resp.Size = copy(f.data[req.Offset:], req.Data)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1709,7 +1775,7 @@ func TestMmap(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
got := w.data
|
got := w.bytes()
|
||||||
if g, e := len(got), mmapSize; g != e {
|
if g, e := len(got), mmapSize; g != e {
|
||||||
t.Fatalf("bad write length: %d != %d", g, e)
|
t.Fatalf("bad write length: %d != %d", g, e)
|
||||||
}
|
}
|
||||||
@ -1797,3 +1863,57 @@ func TestDirectWrite(t *testing.T) {
|
|||||||
t.Errorf("write = %q, want %q", got, hi)
|
t.Errorf("write = %q, want %q", got, hi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test Attr
|
||||||
|
|
||||||
|
// attrUnlinked is a file that is unlinked (Nlink==0).
|
||||||
|
type attrUnlinked struct {
|
||||||
|
fstestutil.File
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ fs.Node = attrUnlinked{}
|
||||||
|
|
||||||
|
func (f attrUnlinked) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
|
if err := f.File.Attr(ctx, a); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
a.Nlink = 0
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAttrUnlinked(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": attrUnlinked{}}})
|
||||||
|
|
||||||
|
fi, err := os.Stat(mnt.Dir + "/child")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Stat failed with %v", err)
|
||||||
|
}
|
||||||
|
switch stat := fi.Sys().(type) {
|
||||||
|
case *syscall.Stat_t:
|
||||||
|
if stat.Nlink != 0 {
|
||||||
|
t.Errorf("wrong link count: %v", stat.Nlink)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test behavior when Attr method fails
|
||||||
|
|
||||||
|
type attrBad struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ fs.Node = attrBad{}
|
||||||
|
|
||||||
|
func (attrBad) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
|
return fuse.Errno(syscall.ENAMETOOLONG)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAttrBad(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": attrBad{}}})
|
||||||
|
|
||||||
|
_, err = os.Stat(mnt.Dir + "/child")
|
||||||
|
if nerr, ok := err.(*os.PathError); !ok || nerr.Err != syscall.ENAMETOOLONG {
|
||||||
|
t.Fatalf("wrong error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
5
Godeps/_workspace/src/bazil.org/fuse/fs/tree.go
generated
vendored
5
Godeps/_workspace/src/bazil.org/fuse/fs/tree.go
generated
vendored
@ -77,8 +77,9 @@ func (t *tree) add(name string, n Node) {
|
|||||||
t.dir = append(t.dir, treeDir{name, n})
|
t.dir = append(t.dir, treeDir{name, n})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tree) Attr() fuse.Attr {
|
func (t *tree) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{Mode: os.ModeDir | 0555}
|
a.Mode = os.ModeDir | 0555
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tree) Lookup(ctx context.Context, name string) (Node, error) {
|
func (t *tree) Lookup(ctx context.Context, name string) (Node, error) {
|
||||||
|
42
Godeps/_workspace/src/bazil.org/fuse/fuse.go
generated
vendored
42
Godeps/_workspace/src/bazil.org/fuse/fuse.go
generated
vendored
@ -1,4 +1,5 @@
|
|||||||
// See the file LICENSE for copyright and licensing information.
|
// See the file LICENSE for copyright and licensing information.
|
||||||
|
|
||||||
// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c,
|
// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c,
|
||||||
// which carries this notice:
|
// which carries this notice:
|
||||||
//
|
//
|
||||||
@ -45,7 +46,7 @@
|
|||||||
// The required and optional methods for the FS, Node, and Handle interfaces
|
// The required and optional methods for the FS, Node, and Handle interfaces
|
||||||
// have the general form
|
// have the general form
|
||||||
//
|
//
|
||||||
// Op(ctx context.Context, req *OpRequest, resp *OpResponse) Error
|
// Op(ctx context.Context, req *OpRequest, resp *OpResponse) error
|
||||||
//
|
//
|
||||||
// where Op is the name of a FUSE operation. Op reads request
|
// where Op is the name of a FUSE operation. Op reads request
|
||||||
// parameters from req and writes results to resp. An operation whose
|
// parameters from req and writes results to resp. An operation whose
|
||||||
@ -67,7 +68,7 @@
|
|||||||
// can implement ErrorNumber to control the errno returned. Without
|
// can implement ErrorNumber to control the errno returned. Without
|
||||||
// ErrorNumber, a generic errno (EIO) is returned.
|
// ErrorNumber, a generic errno (EIO) is returned.
|
||||||
//
|
//
|
||||||
// Errors messages will be visible in the debug log as part of the
|
// Error messages will be visible in the debug log as part of the
|
||||||
// response.
|
// response.
|
||||||
//
|
//
|
||||||
// Interrupted Operations
|
// Interrupted Operations
|
||||||
@ -1064,6 +1065,8 @@ func (r *AccessRequest) Respond() {
|
|||||||
|
|
||||||
// An Attr is the metadata for a single file or directory.
|
// An Attr is the metadata for a single file or directory.
|
||||||
type Attr struct {
|
type Attr struct {
|
||||||
|
Valid time.Duration // how long Attr can be cached
|
||||||
|
|
||||||
Inode uint64 // inode number
|
Inode uint64 // inode number
|
||||||
Size uint64 // size in bytes
|
Size uint64 // size in bytes
|
||||||
Blocks uint64 // size in blocks
|
Blocks uint64 // size in blocks
|
||||||
@ -1143,8 +1146,8 @@ func (r *GetattrRequest) String() string {
|
|||||||
func (r *GetattrRequest) Respond(resp *GetattrResponse) {
|
func (r *GetattrRequest) Respond(resp *GetattrResponse) {
|
||||||
out := &attrOut{
|
out := &attrOut{
|
||||||
outHeader: outHeader{Unique: uint64(r.ID)},
|
outHeader: outHeader{Unique: uint64(r.ID)},
|
||||||
AttrValid: uint64(resp.AttrValid / time.Second),
|
AttrValid: uint64(resp.Attr.Valid / time.Second),
|
||||||
AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond),
|
AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
|
||||||
Attr: resp.Attr.attr(),
|
Attr: resp.Attr.attr(),
|
||||||
}
|
}
|
||||||
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
||||||
@ -1152,7 +1155,6 @@ func (r *GetattrRequest) Respond(resp *GetattrResponse) {
|
|||||||
|
|
||||||
// A GetattrResponse is the response to a GetattrRequest.
|
// A GetattrResponse is the response to a GetattrRequest.
|
||||||
type GetattrResponse struct {
|
type GetattrResponse struct {
|
||||||
AttrValid time.Duration // how long Attr can be cached
|
|
||||||
Attr Attr // file attributes
|
Attr Attr // file attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1333,8 +1335,8 @@ func (r *LookupRequest) Respond(resp *LookupResponse) {
|
|||||||
Generation: resp.Generation,
|
Generation: resp.Generation,
|
||||||
EntryValid: uint64(resp.EntryValid / time.Second),
|
EntryValid: uint64(resp.EntryValid / time.Second),
|
||||||
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
||||||
AttrValid: uint64(resp.AttrValid / time.Second),
|
AttrValid: uint64(resp.Attr.Valid / time.Second),
|
||||||
AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond),
|
AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
|
||||||
Attr: resp.Attr.attr(),
|
Attr: resp.Attr.attr(),
|
||||||
}
|
}
|
||||||
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
||||||
@ -1345,7 +1347,6 @@ type LookupResponse struct {
|
|||||||
Node NodeID
|
Node NodeID
|
||||||
Generation uint64
|
Generation uint64
|
||||||
EntryValid time.Duration
|
EntryValid time.Duration
|
||||||
AttrValid time.Duration
|
|
||||||
Attr Attr
|
Attr Attr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1409,8 +1410,8 @@ func (r *CreateRequest) Respond(resp *CreateResponse) {
|
|||||||
Generation: resp.Generation,
|
Generation: resp.Generation,
|
||||||
EntryValid: uint64(resp.EntryValid / time.Second),
|
EntryValid: uint64(resp.EntryValid / time.Second),
|
||||||
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
||||||
AttrValid: uint64(resp.AttrValid / time.Second),
|
AttrValid: uint64(resp.Attr.Valid / time.Second),
|
||||||
AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond),
|
AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
|
||||||
Attr: resp.Attr.attr(),
|
Attr: resp.Attr.attr(),
|
||||||
|
|
||||||
Fh: uint64(resp.Handle),
|
Fh: uint64(resp.Handle),
|
||||||
@ -1451,8 +1452,8 @@ func (r *MkdirRequest) Respond(resp *MkdirResponse) {
|
|||||||
Generation: resp.Generation,
|
Generation: resp.Generation,
|
||||||
EntryValid: uint64(resp.EntryValid / time.Second),
|
EntryValid: uint64(resp.EntryValid / time.Second),
|
||||||
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
||||||
AttrValid: uint64(resp.AttrValid / time.Second),
|
AttrValid: uint64(resp.Attr.Valid / time.Second),
|
||||||
AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond),
|
AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
|
||||||
Attr: resp.Attr.attr(),
|
Attr: resp.Attr.attr(),
|
||||||
}
|
}
|
||||||
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
||||||
@ -1776,8 +1777,8 @@ func (r *SetattrRequest) String() string {
|
|||||||
func (r *SetattrRequest) Respond(resp *SetattrResponse) {
|
func (r *SetattrRequest) Respond(resp *SetattrResponse) {
|
||||||
out := &attrOut{
|
out := &attrOut{
|
||||||
outHeader: outHeader{Unique: uint64(r.ID)},
|
outHeader: outHeader{Unique: uint64(r.ID)},
|
||||||
AttrValid: uint64(resp.AttrValid / time.Second),
|
AttrValid: uint64(resp.Attr.Valid / time.Second),
|
||||||
AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond),
|
AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
|
||||||
Attr: resp.Attr.attr(),
|
Attr: resp.Attr.attr(),
|
||||||
}
|
}
|
||||||
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
||||||
@ -1785,7 +1786,6 @@ func (r *SetattrRequest) Respond(resp *SetattrResponse) {
|
|||||||
|
|
||||||
// A SetattrResponse is the response to a SetattrRequest.
|
// A SetattrResponse is the response to a SetattrRequest.
|
||||||
type SetattrResponse struct {
|
type SetattrResponse struct {
|
||||||
AttrValid time.Duration // how long Attr can be cached
|
|
||||||
Attr Attr // file attributes
|
Attr Attr // file attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1855,8 +1855,8 @@ func (r *SymlinkRequest) Respond(resp *SymlinkResponse) {
|
|||||||
Generation: resp.Generation,
|
Generation: resp.Generation,
|
||||||
EntryValid: uint64(resp.EntryValid / time.Second),
|
EntryValid: uint64(resp.EntryValid / time.Second),
|
||||||
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
||||||
AttrValid: uint64(resp.AttrValid / time.Second),
|
AttrValid: uint64(resp.Attr.Valid / time.Second),
|
||||||
AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond),
|
AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
|
||||||
Attr: resp.Attr.attr(),
|
Attr: resp.Attr.attr(),
|
||||||
}
|
}
|
||||||
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
||||||
@ -1903,8 +1903,8 @@ func (r *LinkRequest) Respond(resp *LookupResponse) {
|
|||||||
Generation: resp.Generation,
|
Generation: resp.Generation,
|
||||||
EntryValid: uint64(resp.EntryValid / time.Second),
|
EntryValid: uint64(resp.EntryValid / time.Second),
|
||||||
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
||||||
AttrValid: uint64(resp.AttrValid / time.Second),
|
AttrValid: uint64(resp.Attr.Valid / time.Second),
|
||||||
AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond),
|
AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
|
||||||
Attr: resp.Attr.attr(),
|
Attr: resp.Attr.attr(),
|
||||||
}
|
}
|
||||||
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
||||||
@ -1948,8 +1948,8 @@ func (r *MknodRequest) Respond(resp *LookupResponse) {
|
|||||||
Generation: resp.Generation,
|
Generation: resp.Generation,
|
||||||
EntryValid: uint64(resp.EntryValid / time.Second),
|
EntryValid: uint64(resp.EntryValid / time.Second),
|
||||||
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
|
||||||
AttrValid: uint64(resp.AttrValid / time.Second),
|
AttrValid: uint64(resp.Attr.Valid / time.Second),
|
||||||
AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond),
|
AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
|
||||||
Attr: resp.Attr.attr(),
|
Attr: resp.Attr.attr(),
|
||||||
}
|
}
|
||||||
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
r.respond(&out.outHeader, unsafe.Sizeof(*out))
|
||||||
|
2
Godeps/_workspace/src/bazil.org/fuse/fuse_kernel.go
generated
vendored
2
Godeps/_workspace/src/bazil.org/fuse/fuse_kernel.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
// See the file LICENSE for copyright and licensing information.
|
// See the file LICENSE for copyright and licensing information.
|
||||||
|
|
||||||
// Derived from FUSE's fuse_kernel.h
|
// Derived from FUSE's fuse_kernel.h, which carries this notice:
|
||||||
/*
|
/*
|
||||||
This file defines the kernel interface of FUSE
|
This file defines the kernel interface of FUSE
|
||||||
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
|
13
Godeps/_workspace/src/bazil.org/fuse/hellofs/hello.go
generated
vendored
13
Godeps/_workspace/src/bazil.org/fuse/hellofs/hello.go
generated
vendored
@ -63,8 +63,10 @@ func (FS) Root() (fs.Node, error) {
|
|||||||
// Dir implements both Node and Handle for the root directory.
|
// Dir implements both Node and Handle for the root directory.
|
||||||
type Dir struct{}
|
type Dir struct{}
|
||||||
|
|
||||||
func (Dir) Attr() fuse.Attr {
|
func (Dir) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0555}
|
a.Inode = 1
|
||||||
|
a.Mode = os.ModeDir | 0555
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
||||||
@ -87,8 +89,11 @@ type File struct{}
|
|||||||
|
|
||||||
const greeting = "hello, world\n"
|
const greeting = "hello, world\n"
|
||||||
|
|
||||||
func (File) Attr() fuse.Attr {
|
func (File) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{Inode: 2, Mode: 0444, Size: uint64(len(greeting))}
|
a.Inode = 2
|
||||||
|
a.Mode = 0444
|
||||||
|
a.Size = uint64(len(greeting))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (File) ReadAll(ctx context.Context) ([]byte, error) {
|
func (File) ReadAll(ctx context.Context) ([]byte, error) {
|
||||||
|
46
Godeps/_workspace/src/bazil.org/fuse/mount_linux.go
generated
vendored
46
Godeps/_workspace/src/bazil.org/fuse/mount_linux.go
generated
vendored
@ -1,13 +1,37 @@
|
|||||||
package fuse
|
package fuse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func lineLogger(wg *sync.WaitGroup, prefix string, r io.ReadCloser) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(r)
|
||||||
|
for scanner.Scan() {
|
||||||
|
switch line := scanner.Text(); line {
|
||||||
|
case `fusermount: failed to open /etc/fuse.conf: Permission denied`:
|
||||||
|
// Silence this particular message, it occurs way too
|
||||||
|
// commonly and isn't very relevant to whether the mount
|
||||||
|
// succeeds or not.
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
log.Printf("%s: %s", prefix, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
log.Printf("%s, error reading: %v", prefix, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func mount(dir string, conf *MountConfig, ready chan<- struct{}, errp *error) (fusefd *os.File, err error) {
|
func mount(dir string, conf *MountConfig, ready chan<- struct{}, errp *error) (fusefd *os.File, err error) {
|
||||||
// linux mount is never delayed
|
// linux mount is never delayed
|
||||||
close(ready)
|
close(ready)
|
||||||
@ -31,9 +55,25 @@ func mount(dir string, conf *MountConfig, ready chan<- struct{}, errp *error) (f
|
|||||||
defer writeFile.Close()
|
defer writeFile.Close()
|
||||||
cmd.ExtraFiles = []*os.File{writeFile}
|
cmd.ExtraFiles = []*os.File{writeFile}
|
||||||
|
|
||||||
out, err := cmd.CombinedOutput()
|
var wg sync.WaitGroup
|
||||||
if len(out) > 0 || err != nil {
|
stdout, err := cmd.StdoutPipe()
|
||||||
return nil, fmt.Errorf("fusermount: %q, %v", out, err)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("setting up fusermount stderr: %v", err)
|
||||||
|
}
|
||||||
|
stderr, err := cmd.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("setting up fusermount stderr: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return nil, fmt.Errorf("fusermount: %v", err)
|
||||||
|
}
|
||||||
|
wg.Add(2)
|
||||||
|
go lineLogger(&wg, "mount helper output", stdout)
|
||||||
|
go lineLogger(&wg, "mount helper error", stderr)
|
||||||
|
wg.Wait()
|
||||||
|
if err := cmd.Wait(); err != nil {
|
||||||
|
return nil, fmt.Errorf("fusermount: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads")
|
readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads")
|
||||||
|
5
Godeps/_workspace/src/bazil.org/fuse/options_test.go
generated
vendored
5
Godeps/_workspace/src/bazil.org/fuse/options_test.go
generated
vendored
@ -155,7 +155,10 @@ func TestMountOptionAllowRootThenAllowOther(t *testing.T) {
|
|||||||
|
|
||||||
type unwritableFile struct{}
|
type unwritableFile struct{}
|
||||||
|
|
||||||
func (f unwritableFile) Attr() fuse.Attr { return fuse.Attr{Mode: 0000} }
|
func (f unwritableFile) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
|
a.Mode = 0000
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func TestMountOptionDefaultPermissions(t *testing.T) {
|
func TestMountOptionDefaultPermissions(t *testing.T) {
|
||||||
if runtime.GOOS == "freebsd" {
|
if runtime.GOOS == "freebsd" {
|
||||||
|
@ -6,6 +6,7 @@ package ipns
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -106,9 +107,10 @@ func CreateRoot(ipfs *core.IpfsNode, keys []ci.PrivKey, ipfspath, ipnspath strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attr returns file attributes.
|
// Attr returns file attributes.
|
||||||
func (*Root) Attr() fuse.Attr {
|
func (*Root) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
log.Debug("Root Attr")
|
log.Debug("Root Attr")
|
||||||
return fuse.Attr{Mode: os.ModeDir | 0111} // -rw+x
|
*a = fuse.Attr{Mode: os.ModeDir | 0111} // -rw+x
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup performs a lookup under this node.
|
// Lookup performs a lookup under this node.
|
||||||
@ -215,29 +217,31 @@ type File struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attr returns the attributes of a given node.
|
// Attr returns the attributes of a given node.
|
||||||
func (d *Directory) Attr() fuse.Attr {
|
func (d *Directory) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
log.Debug("Directory Attr")
|
log.Debug("Directory Attr")
|
||||||
return fuse.Attr{
|
*a = fuse.Attr{
|
||||||
Mode: os.ModeDir | 0555,
|
Mode: os.ModeDir | 0555,
|
||||||
Uid: uint32(os.Getuid()),
|
Uid: uint32(os.Getuid()),
|
||||||
Gid: uint32(os.Getgid()),
|
Gid: uint32(os.Getgid()),
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attr returns the attributes of a given node.
|
// Attr returns the attributes of a given node.
|
||||||
func (fi *File) Attr() fuse.Attr {
|
func (fi *File) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
log.Debug("File Attr")
|
log.Debug("File Attr")
|
||||||
size, err := fi.fi.Size()
|
size, err := fi.fi.Size()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// In this case, the dag node in question may not be unixfs
|
// In this case, the dag node in question may not be unixfs
|
||||||
log.Critical("Failed to get file size: %s", err)
|
return fmt.Errorf("fuse/ipns: failed to get file.Size(): %s", err)
|
||||||
}
|
}
|
||||||
return fuse.Attr{
|
*a = fuse.Attr{
|
||||||
Mode: os.FileMode(0666),
|
Mode: os.FileMode(0666),
|
||||||
Size: uint64(size),
|
Size: uint64(size),
|
||||||
Uid: uint32(os.Getuid()),
|
Uid: uint32(os.Getuid()),
|
||||||
Gid: uint32(os.Getgid()),
|
Gid: uint32(os.Getgid()),
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup performs a lookup under this node.
|
// Lookup performs a lookup under this node.
|
||||||
|
@ -14,11 +14,12 @@ type Link struct {
|
|||||||
Target string
|
Target string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Link) Attr() fuse.Attr {
|
func (l *Link) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
log.Debug("Link attr.")
|
log.Debug("Link attr.")
|
||||||
return fuse.Attr{
|
*a = fuse.Attr{
|
||||||
Mode: os.ModeSymlink | 0555,
|
Mode: os.ModeSymlink | 0555,
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Link) Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) {
|
func (l *Link) Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
package readonly
|
package readonly
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -43,8 +44,9 @@ type Root struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attr returns file attributes.
|
// Attr returns file attributes.
|
||||||
func (*Root) Attr() fuse.Attr {
|
func (*Root) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return fuse.Attr{Mode: os.ModeDir | 0111} // -rw+x
|
*a = fuse.Attr{Mode: os.ModeDir | 0111} // -rw+x
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup performs a lookup under this node.
|
// Lookup performs a lookup under this node.
|
||||||
@ -85,21 +87,23 @@ func (s *Node) loadData() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attr returns the attributes of a given node.
|
// Attr returns the attributes of a given node.
|
||||||
func (s *Node) Attr() fuse.Attr {
|
func (s *Node) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
log.Debug("Node attr.")
|
log.Debug("Node attr.")
|
||||||
if s.cached == nil {
|
if s.cached == nil {
|
||||||
s.loadData()
|
if err := s.loadData(); err != nil {
|
||||||
|
return fmt.Errorf("readonly: loadData() failed: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch s.cached.GetType() {
|
switch s.cached.GetType() {
|
||||||
case ftpb.Data_Directory:
|
case ftpb.Data_Directory:
|
||||||
return fuse.Attr{
|
*a = fuse.Attr{
|
||||||
Mode: os.ModeDir | 0555,
|
Mode: os.ModeDir | 0555,
|
||||||
Uid: uint32(os.Getuid()),
|
Uid: uint32(os.Getuid()),
|
||||||
Gid: uint32(os.Getgid()),
|
Gid: uint32(os.Getgid()),
|
||||||
}
|
}
|
||||||
case ftpb.Data_File:
|
case ftpb.Data_File:
|
||||||
size := s.cached.GetFilesize()
|
size := s.cached.GetFilesize()
|
||||||
return fuse.Attr{
|
*a = fuse.Attr{
|
||||||
Mode: 0444,
|
Mode: 0444,
|
||||||
Size: uint64(size),
|
Size: uint64(size),
|
||||||
Blocks: uint64(len(s.Nd.Links)),
|
Blocks: uint64(len(s.Nd.Links)),
|
||||||
@ -107,7 +111,7 @@ func (s *Node) Attr() fuse.Attr {
|
|||||||
Gid: uint32(os.Getgid()),
|
Gid: uint32(os.Getgid()),
|
||||||
}
|
}
|
||||||
case ftpb.Data_Raw:
|
case ftpb.Data_Raw:
|
||||||
return fuse.Attr{
|
*a = fuse.Attr{
|
||||||
Mode: 0444,
|
Mode: 0444,
|
||||||
Size: uint64(len(s.cached.GetData())),
|
Size: uint64(len(s.cached.GetData())),
|
||||||
Blocks: uint64(len(s.Nd.Links)),
|
Blocks: uint64(len(s.Nd.Links)),
|
||||||
@ -116,9 +120,9 @@ func (s *Node) Attr() fuse.Attr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Debug("Invalid data type.")
|
return fmt.Errorf("Invalid data type - %s", s.cached.GetType())
|
||||||
return fuse.Attr{}
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup performs a lookup under this node.
|
// Lookup performs a lookup under this node.
|
||||||
|
Reference in New Issue
Block a user