github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/third_party/bazil.org/fuse/fs/serve.go (about)

     1  // FUSE service loop, for servers that wish to use it.
     2  
     3  package fs
     4  
     5  import (
     6  	"fmt"
     7  	"hash/fnv"
     8  	"io"
     9  	"path"
    10  	"reflect"
    11  	"strings"
    12  	"sync"
    13  	"syscall"
    14  	"time"
    15  )
    16  
    17  import (
    18  	"camlistore.org/third_party/bazil.org/fuse"
    19  	"camlistore.org/third_party/bazil.org/fuse/fuseutil"
    20  )
    21  
    22  const (
    23  	attrValidTime  = 1 * time.Minute
    24  	entryValidTime = 1 * time.Minute
    25  )
    26  
    27  // TODO: FINISH DOCS
    28  
    29  // An Intr is a channel that signals that a request has been interrupted.
    30  // Being able to receive from the channel means the request has been
    31  // interrupted.
    32  type Intr chan struct{}
    33  
    34  func (Intr) String() string { return "fuse.Intr" }
    35  
    36  // An FS is the interface required of a file system.
    37  //
    38  // Other FUSE requests can be handled by implementing methods from the
    39  // FS* interfaces, for example FSIniter.
    40  type FS interface {
    41  	// Root is called to obtain the Node for the file system root.
    42  	Root() (Node, fuse.Error)
    43  }
    44  
    45  type FSIniter interface {
    46  	// Init is called to initialize the FUSE connection.
    47  	// It can inspect the request and adjust the response as desired.
    48  	// The default response sets MaxReadahead to 0 and MaxWrite to 4096.
    49  	// Init must return promptly.
    50  	Init(*fuse.InitRequest, *fuse.InitResponse, Intr) fuse.Error
    51  }
    52  
    53  type FSStatfser interface {
    54  	// Statfs is called to obtain file system metadata.
    55  	// It should write that data to resp.
    56  	Statfs(*fuse.StatfsRequest, *fuse.StatfsResponse, Intr) fuse.Error
    57  }
    58  
    59  type FSDestroyer interface {
    60  	// Destroy is called when the file system is shutting down.
    61  	//
    62  	// Linux only sends this request for block device backed (fuseblk)
    63  	// filesystems, to allow them to flush writes to disk before the
    64  	// unmount completes.
    65  	//
    66  	// On normal FUSE filesystems, use Forget of the root Node to
    67  	// do actions at unmount time.
    68  	Destroy()
    69  }
    70  
    71  // A Node is the interface required of a file or directory.
    72  // See the documentation for type FS for general information
    73  // pertaining to all methods.
    74  //
    75  // Other FUSE requests can be handled by implementing methods from the
    76  // Node* interfaces, for example NodeOpener.
    77  type Node interface {
    78  	Attr() fuse.Attr
    79  }
    80  
    81  type NodeGetattrer interface {
    82  	// Getattr obtains the standard metadata for the receiver.
    83  	// It should store that metadata in resp.
    84  	//
    85  	// If this method is not implemented, the attributes will be
    86  	// generated based on Attr(), with zero values filled in.
    87  	Getattr(*fuse.GetattrRequest, *fuse.GetattrResponse, Intr) fuse.Error
    88  }
    89  
    90  type NodeSetattrer interface {
    91  	// Setattr sets the standard metadata for the receiver.
    92  	Setattr(*fuse.SetattrRequest, *fuse.SetattrResponse, Intr) fuse.Error
    93  }
    94  
    95  type NodeSymlinker interface {
    96  	// Symlink creates a new symbolic link in the receiver, which must be a directory.
    97  	//
    98  	// TODO is the above true about directories?
    99  	Symlink(*fuse.SymlinkRequest, Intr) (Node, fuse.Error)
   100  }
   101  
   102  // This optional request will be called only for symbolic link nodes.
   103  type NodeReadlinker interface {
   104  	// Readlink reads a symbolic link.
   105  	Readlink(*fuse.ReadlinkRequest, Intr) (string, fuse.Error)
   106  }
   107  
   108  type NodeLinker interface {
   109  	// Link creates a new directory entry in the receiver based on an
   110  	// existing Node. Receiver must be a directory.
   111  	Link(r *fuse.LinkRequest, old Node, intr Intr) (Node, fuse.Error)
   112  }
   113  
   114  type NodeRemover interface {
   115  	// Remove removes the entry with the given name from
   116  	// the receiver, which must be a directory.  The entry to be removed
   117  	// may correspond to a file (unlink) or to a directory (rmdir).
   118  	Remove(*fuse.RemoveRequest, Intr) fuse.Error
   119  }
   120  
   121  type NodeAccesser interface {
   122  	// Access checks whether the calling context has permission for
   123  	// the given operations on the receiver. If so, Access should
   124  	// return nil. If not, Access should return EPERM.
   125  	//
   126  	// Note that this call affects the result of the access(2) system
   127  	// call but not the open(2) system call. If Access is not
   128  	// implemented, the Node behaves as if it always returns nil
   129  	// (permission granted), relying on checks in Open instead.
   130  	Access(*fuse.AccessRequest, Intr) fuse.Error
   131  }
   132  
   133  type NodeStringLookuper interface {
   134  	// Lookup looks up a specific entry in the receiver,
   135  	// which must be a directory.  Lookup should return a Node
   136  	// corresponding to the entry.  If the name does not exist in
   137  	// the directory, Lookup should return nil, err.
   138  	//
   139  	// Lookup need not to handle the names "." and "..".
   140  	Lookup(string, Intr) (Node, fuse.Error)
   141  }
   142  
   143  type NodeRequestLookuper interface {
   144  	// Lookup looks up a specific entry in the receiver.
   145  	// See NodeStringLookuper for more.
   146  	Lookup(*fuse.LookupRequest, *fuse.LookupResponse, Intr) (Node, fuse.Error)
   147  }
   148  
   149  type NodeMkdirer interface {
   150  	Mkdir(*fuse.MkdirRequest, Intr) (Node, fuse.Error)
   151  }
   152  
   153  type NodeOpener interface {
   154  	// Open opens the receiver.
   155  	// XXX note about access.  XXX OpenFlags.
   156  	// XXX note that the Node may be a file or directory.
   157  	Open(*fuse.OpenRequest, *fuse.OpenResponse, Intr) (Handle, fuse.Error)
   158  }
   159  
   160  type NodeCreater interface {
   161  	// Create creates a new directory entry in the receiver, which
   162  	// must be a directory.
   163  	Create(*fuse.CreateRequest, *fuse.CreateResponse, Intr) (Node, Handle, fuse.Error)
   164  }
   165  
   166  type NodeForgetter interface {
   167  	Forget()
   168  }
   169  
   170  type NodeRenamer interface {
   171  	Rename(r *fuse.RenameRequest, newDir Node, intr Intr) fuse.Error
   172  }
   173  
   174  type NodeMknoder interface {
   175  	Mknod(r *fuse.MknodRequest, intr Intr) (Node, fuse.Error)
   176  }
   177  
   178  // TODO this should be on Handle not Node
   179  type NodeFsyncer interface {
   180  	Fsync(r *fuse.FsyncRequest, intr Intr) fuse.Error
   181  }
   182  
   183  type NodeGetxattrer interface {
   184  	// Getxattr gets an extended attribute by the given name from the
   185  	// node.
   186  	//
   187  	// If there is no xattr by that name, returns fuse.ENODATA. This
   188  	// will be translated to the platform-specific correct error code
   189  	// by the framework.
   190  	Getxattr(req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse, intr Intr) fuse.Error
   191  }
   192  
   193  type NodeListxattrer interface {
   194  	// Listxattr lists the extended attributes recorded for the node.
   195  	Listxattr(req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse, intr Intr) fuse.Error
   196  }
   197  
   198  type NodeSetxattrer interface {
   199  	// Setxattr sets an extended attribute with the given name and
   200  	// value for the node.
   201  	Setxattr(req *fuse.SetxattrRequest, intr Intr) fuse.Error
   202  }
   203  
   204  type NodeRemovexattrer interface {
   205  	// Removexattr removes an extended attribute for the name.
   206  	//
   207  	// If there is no xattr by that name, returns fuse.ENODATA. This
   208  	// will be translated to the platform-specific correct error code
   209  	// by the framework.
   210  	Removexattr(req *fuse.RemovexattrRequest, intr Intr) fuse.Error
   211  }
   212  
   213  var startTime = time.Now()
   214  
   215  func nodeAttr(n Node) (attr fuse.Attr) {
   216  	attr = n.Attr()
   217  	if attr.Nlink == 0 {
   218  		attr.Nlink = 1
   219  	}
   220  	if attr.Atime.IsZero() {
   221  		attr.Atime = startTime
   222  	}
   223  	if attr.Mtime.IsZero() {
   224  		attr.Mtime = startTime
   225  	}
   226  	if attr.Ctime.IsZero() {
   227  		attr.Ctime = startTime
   228  	}
   229  	if attr.Crtime.IsZero() {
   230  		attr.Crtime = startTime
   231  	}
   232  	return
   233  }
   234  
   235  // A Handle is the interface required of an opened file or directory.
   236  // See the documentation for type FS for general information
   237  // pertaining to all methods.
   238  //
   239  // Other FUSE requests can be handled by implementing methods from the
   240  // Node* interfaces. The most common to implement are
   241  // HandleReader, HandleReadDirer, and HandleWriter.
   242  //
   243  // TODO implement methods: Getlk, Setlk, Setlkw
   244  type Handle interface {
   245  }
   246  
   247  type HandleFlusher interface {
   248  	// Flush is called each time the file or directory is closed.
   249  	// Because there can be multiple file descriptors referring to a
   250  	// single opened file, Flush can be called multiple times.
   251  	Flush(*fuse.FlushRequest, Intr) fuse.Error
   252  }
   253  
   254  type HandleReadAller interface {
   255  	ReadAll(Intr) ([]byte, fuse.Error)
   256  }
   257  
   258  type HandleReadDirer interface {
   259  	ReadDir(Intr) ([]fuse.Dirent, fuse.Error)
   260  }
   261  
   262  type HandleReader interface {
   263  	Read(*fuse.ReadRequest, *fuse.ReadResponse, Intr) fuse.Error
   264  }
   265  
   266  type HandleWriter interface {
   267  	Write(*fuse.WriteRequest, *fuse.WriteResponse, Intr) fuse.Error
   268  }
   269  
   270  type HandleReleaser interface {
   271  	Release(*fuse.ReleaseRequest, Intr) fuse.Error
   272  }
   273  
   274  // Serve serves the FUSE connection by making calls to the methods
   275  // of fs and the Nodes and Handles it makes available.  It returns only
   276  // when the connection has been closed or an unexpected error occurs.
   277  func Serve(c *fuse.Conn, fs FS) error {
   278  	sc := serveConn{}
   279  	sc.req = map[fuse.RequestID]*serveRequest{}
   280  
   281  	root, err := fs.Root()
   282  	if err != nil {
   283  		return fmt.Errorf("cannot obtain root node: %v", syscall.Errno(err.(fuse.Errno)).Error())
   284  	}
   285  	sc.node = append(sc.node, nil, &serveNode{name: "/", node: root, refs: 1})
   286  	sc.handle = append(sc.handle, nil)
   287  
   288  	for {
   289  		req, err := c.ReadRequest()
   290  		if err != nil {
   291  			if err == io.EOF {
   292  				break
   293  			}
   294  			return err
   295  		}
   296  
   297  		go sc.serve(fs, req)
   298  	}
   299  	return nil
   300  }
   301  
   302  type nothing struct{}
   303  
   304  type serveConn struct {
   305  	meta       sync.Mutex
   306  	req        map[fuse.RequestID]*serveRequest
   307  	node       []*serveNode
   308  	handle     []*serveHandle
   309  	freeNode   []fuse.NodeID
   310  	freeHandle []fuse.HandleID
   311  	nodeGen    uint64
   312  }
   313  
   314  type serveRequest struct {
   315  	Request fuse.Request
   316  	Intr    Intr
   317  }
   318  
   319  type serveNode struct {
   320  	name string
   321  	node Node
   322  	refs uint64
   323  }
   324  
   325  func (sn *serveNode) attr() (attr fuse.Attr) {
   326  	attr = nodeAttr(sn.node)
   327  	if attr.Inode == 0 {
   328  		attr.Inode = hash(sn.name)
   329  	}
   330  	return
   331  }
   332  
   333  func hash(s string) uint64 {
   334  	f := fnv.New64()
   335  	f.Write([]byte(s))
   336  	return f.Sum64()
   337  }
   338  
   339  type serveHandle struct {
   340  	handle   Handle
   341  	readData []byte
   342  	nodeID   fuse.NodeID
   343  }
   344  
   345  // NodeRef can be embedded in a Node to recognize the same Node being
   346  // returned from multiple Lookup, Create etc calls.
   347  //
   348  // Without this, each Node will get a new NodeID, causing spurious
   349  // cache invalidations, extra lookups and aliasing anomalies. This may
   350  // not matter for a simple, read-only filesystem.
   351  type NodeRef struct {
   352  	id         fuse.NodeID
   353  	generation uint64
   354  }
   355  
   356  // nodeRef is only ever accessed while holding serveConn.meta
   357  func (n *NodeRef) nodeRef() *NodeRef {
   358  	return n
   359  }
   360  
   361  type nodeRef interface {
   362  	nodeRef() *NodeRef
   363  }
   364  
   365  func (c *serveConn) saveNode(name string, node Node) (id fuse.NodeID, gen uint64, sn *serveNode) {
   366  	c.meta.Lock()
   367  	defer c.meta.Unlock()
   368  
   369  	var ref *NodeRef
   370  	if nodeRef, ok := node.(nodeRef); ok {
   371  		ref = nodeRef.nodeRef()
   372  
   373  		if ref.id != 0 {
   374  			// dropNode guarantees that NodeRef is zeroed at the same
   375  			// time as the NodeID is removed from serveConn.node, as
   376  			// guarded by c.meta; this means sn cannot be nil here
   377  			sn = c.node[ref.id]
   378  			sn.refs++
   379  			return ref.id, ref.generation, sn
   380  		}
   381  	}
   382  
   383  	sn = &serveNode{name: name, node: node, refs: 1}
   384  	if n := len(c.freeNode); n > 0 {
   385  		id = c.freeNode[n-1]
   386  		c.freeNode = c.freeNode[:n-1]
   387  		c.node[id] = sn
   388  		c.nodeGen++
   389  	} else {
   390  		id = fuse.NodeID(len(c.node))
   391  		c.node = append(c.node, sn)
   392  	}
   393  	gen = c.nodeGen
   394  	if ref != nil {
   395  		ref.id = id
   396  		ref.generation = gen
   397  	}
   398  	return
   399  }
   400  
   401  func (c *serveConn) saveHandle(handle Handle, nodeID fuse.NodeID) (id fuse.HandleID) {
   402  	c.meta.Lock()
   403  	shandle := &serveHandle{handle: handle, nodeID: nodeID}
   404  	if n := len(c.freeHandle); n > 0 {
   405  		id = c.freeHandle[n-1]
   406  		c.freeHandle = c.freeHandle[:n-1]
   407  		c.handle[id] = shandle
   408  	} else {
   409  		id = fuse.HandleID(len(c.handle))
   410  		c.handle = append(c.handle, shandle)
   411  	}
   412  	c.meta.Unlock()
   413  	return
   414  }
   415  
   416  type nodeRefcountDropBug struct {
   417  	N    uint64
   418  	Refs uint64
   419  	Node fuse.NodeID
   420  }
   421  
   422  func (n *nodeRefcountDropBug) String() string {
   423  	return fmt.Sprintf("bug: trying to drop %d of %d references to %v", n.N, n.Refs, n.Node)
   424  }
   425  
   426  func (c *serveConn) dropNode(id fuse.NodeID, n uint64) (forget bool) {
   427  	c.meta.Lock()
   428  	defer c.meta.Unlock()
   429  	snode := c.node[id]
   430  
   431  	if snode == nil {
   432  		// this should only happen if refcounts kernel<->us disagree
   433  		// *and* two ForgetRequests for the same node race each other;
   434  		// this indicates a bug somewhere
   435  		fuse.Debug(nodeRefcountDropBug{N: n, Node: id})
   436  
   437  		// we may end up triggering Forget twice, but that's better
   438  		// than not even once, and that's the best we can do
   439  		return true
   440  	}
   441  
   442  	if n > snode.refs {
   443  		fuse.Debug(nodeRefcountDropBug{N: n, Refs: snode.refs, Node: id})
   444  		n = snode.refs
   445  	}
   446  
   447  	snode.refs -= n
   448  	if snode.refs == 0 {
   449  		c.node[id] = nil
   450  		if nodeRef, ok := snode.node.(nodeRef); ok {
   451  			ref := nodeRef.nodeRef()
   452  			*ref = NodeRef{}
   453  		}
   454  		c.freeNode = append(c.freeNode, id)
   455  		return true
   456  	}
   457  	return false
   458  }
   459  
   460  func (c *serveConn) dropHandle(id fuse.HandleID) {
   461  	c.meta.Lock()
   462  	c.handle[id] = nil
   463  	c.freeHandle = append(c.freeHandle, id)
   464  	c.meta.Unlock()
   465  }
   466  
   467  type missingHandle struct {
   468  	Handle    fuse.HandleID
   469  	MaxHandle fuse.HandleID
   470  }
   471  
   472  func (m missingHandle) String() string {
   473  	return fmt.Sprint("missing handle", m.Handle, m.MaxHandle)
   474  }
   475  
   476  // Returns nil for invalid handles.
   477  func (c *serveConn) getHandle(id fuse.HandleID) (shandle *serveHandle) {
   478  	c.meta.Lock()
   479  	defer c.meta.Unlock()
   480  	if id < fuse.HandleID(len(c.handle)) {
   481  		shandle = c.handle[uint(id)]
   482  	}
   483  	if shandle == nil {
   484  		fuse.Debug(missingHandle{
   485  			Handle:    id,
   486  			MaxHandle: fuse.HandleID(len(c.handle)),
   487  		})
   488  	}
   489  	return
   490  }
   491  
   492  type request struct {
   493  	Op      string
   494  	Request *fuse.Header
   495  	In      interface{} `json:",omitempty"`
   496  }
   497  
   498  func (r request) String() string {
   499  	return fmt.Sprintf("<- %s", r.In)
   500  }
   501  
   502  type logResponseHeader struct {
   503  	ID fuse.RequestID
   504  }
   505  
   506  func (m logResponseHeader) String() string {
   507  	return fmt.Sprintf("ID=%#x", m.ID)
   508  }
   509  
   510  type response struct {
   511  	Op      string
   512  	Request logResponseHeader
   513  	Out     interface{} `json:",omitempty"`
   514  	Error   fuse.Error  `json:",omitempty"`
   515  }
   516  
   517  func (r response) String() string {
   518  	switch {
   519  	case r.Error != nil && r.Out != nil:
   520  		return fmt.Sprintf("-> %s error=%s %s", r.Request, r.Error, r.Out)
   521  	case r.Error != nil:
   522  		return fmt.Sprintf("-> %s error=%s", r.Request, r.Error)
   523  	case r.Out != nil:
   524  		return fmt.Sprintf("-> %s %s", r.Request, r.Out)
   525  	default:
   526  		return fmt.Sprintf("-> %s", r.Request)
   527  	}
   528  }
   529  
   530  type logMissingNode struct {
   531  	MaxNode fuse.NodeID
   532  }
   533  
   534  func opName(req fuse.Request) string {
   535  	t := reflect.Indirect(reflect.ValueOf(req)).Type()
   536  	s := t.Name()
   537  	s = strings.TrimSuffix(s, "Request")
   538  	return s
   539  }
   540  
   541  type logLinkRequestOldNodeNotFound struct {
   542  	Request *fuse.Header
   543  	In      *fuse.LinkRequest
   544  }
   545  
   546  func (m *logLinkRequestOldNodeNotFound) String() string {
   547  	return fmt.Sprintf("In LinkRequest (request %#x), node %d not found", m.Request.Hdr().ID, m.In.OldNode)
   548  }
   549  
   550  type renameNewDirNodeNotFound struct {
   551  	Request *fuse.Header
   552  	In      *fuse.RenameRequest
   553  }
   554  
   555  func (m *renameNewDirNodeNotFound) String() string {
   556  	return fmt.Sprintf("In RenameRequest (request %#x), node %d not found", m.Request.Hdr().ID, m.In.NewDir)
   557  }
   558  
   559  func (c *serveConn) serve(fs FS, r fuse.Request) {
   560  	intr := make(Intr)
   561  	req := &serveRequest{Request: r, Intr: intr}
   562  
   563  	fuse.Debug(request{
   564  		Op:      opName(r),
   565  		Request: r.Hdr(),
   566  		In:      r,
   567  	})
   568  	var node Node
   569  	var snode *serveNode
   570  	c.meta.Lock()
   571  	hdr := r.Hdr()
   572  	if id := hdr.Node; id != 0 {
   573  		if id < fuse.NodeID(len(c.node)) {
   574  			snode = c.node[uint(id)]
   575  		}
   576  		if snode == nil {
   577  			c.meta.Unlock()
   578  			fuse.Debug(response{
   579  				Op:      opName(r),
   580  				Request: logResponseHeader{ID: hdr.ID},
   581  				Error:   fuse.ESTALE,
   582  				// this is the only place that sets both Error and
   583  				// Out; not sure if i want to do that; might get rid
   584  				// of len(c.node) things altogether
   585  				Out: logMissingNode{
   586  					MaxNode: fuse.NodeID(len(c.node)),
   587  				},
   588  			})
   589  			r.RespondError(fuse.ESTALE)
   590  			return
   591  		}
   592  		node = snode.node
   593  	}
   594  	if c.req[hdr.ID] != nil {
   595  		// This happens with OSXFUSE.  Assume it's okay and
   596  		// that we'll never see an interrupt for this one.
   597  		// Otherwise everything wedges.  TODO: Report to OSXFUSE?
   598  		//
   599  		// TODO this might have been because of missing done() calls
   600  		intr = nil
   601  	} else {
   602  		c.req[hdr.ID] = req
   603  	}
   604  	c.meta.Unlock()
   605  
   606  	// Call this before responding.
   607  	// After responding is too late: we might get another request
   608  	// with the same ID and be very confused.
   609  	done := func(resp interface{}) {
   610  		msg := response{
   611  			Op:      opName(r),
   612  			Request: logResponseHeader{ID: hdr.ID},
   613  		}
   614  		if err, ok := resp.(fuse.Error); ok {
   615  			msg.Error = err
   616  		} else {
   617  			msg.Out = resp
   618  		}
   619  		fuse.Debug(msg)
   620  
   621  		c.meta.Lock()
   622  		delete(c.req, hdr.ID)
   623  		c.meta.Unlock()
   624  	}
   625  
   626  	switch r := r.(type) {
   627  	default:
   628  		// Note: To FUSE, ENOSYS means "this server never implements this request."
   629  		// It would be inappropriate to return ENOSYS for other operations in this
   630  		// switch that might only be unavailable in some contexts, not all.
   631  		done(fuse.ENOSYS)
   632  		r.RespondError(fuse.ENOSYS)
   633  
   634  	// FS operations.
   635  	case *fuse.InitRequest:
   636  		s := &fuse.InitResponse{
   637  			MaxWrite: 4096,
   638  		}
   639  		if fs, ok := fs.(FSIniter); ok {
   640  			if err := fs.Init(r, s, intr); err != nil {
   641  				done(err)
   642  				r.RespondError(err)
   643  				break
   644  			}
   645  		}
   646  		done(s)
   647  		r.Respond(s)
   648  
   649  	case *fuse.StatfsRequest:
   650  		s := &fuse.StatfsResponse{}
   651  		if fs, ok := fs.(FSStatfser); ok {
   652  			if err := fs.Statfs(r, s, intr); err != nil {
   653  				done(err)
   654  				r.RespondError(err)
   655  				break
   656  			}
   657  		}
   658  		done(s)
   659  		r.Respond(s)
   660  
   661  	// Node operations.
   662  	case *fuse.GetattrRequest:
   663  		s := &fuse.GetattrResponse{}
   664  		if n, ok := node.(NodeGetattrer); ok {
   665  			if err := n.Getattr(r, s, intr); err != nil {
   666  				done(err)
   667  				r.RespondError(err)
   668  				break
   669  			}
   670  		} else {
   671  			s.AttrValid = attrValidTime
   672  			s.Attr = snode.attr()
   673  		}
   674  		done(s)
   675  		r.Respond(s)
   676  
   677  	case *fuse.SetattrRequest:
   678  		s := &fuse.SetattrResponse{}
   679  		if n, ok := node.(NodeSetattrer); ok {
   680  			if err := n.Setattr(r, s, intr); err != nil {
   681  				done(err)
   682  				r.RespondError(err)
   683  				break
   684  			}
   685  			done(s)
   686  			r.Respond(s)
   687  			break
   688  		}
   689  
   690  		if s.AttrValid == 0 {
   691  			s.AttrValid = attrValidTime
   692  		}
   693  		s.Attr = snode.attr()
   694  		done(s)
   695  		r.Respond(s)
   696  
   697  	case *fuse.SymlinkRequest:
   698  		s := &fuse.SymlinkResponse{}
   699  		n, ok := node.(NodeSymlinker)
   700  		if !ok {
   701  			done(fuse.EIO) // XXX or EPERM like Mkdir?
   702  			r.RespondError(fuse.EIO)
   703  			break
   704  		}
   705  		n2, err := n.Symlink(r, intr)
   706  		if err != nil {
   707  			done(err)
   708  			r.RespondError(err)
   709  			break
   710  		}
   711  		c.saveLookup(&s.LookupResponse, snode, r.NewName, n2)
   712  		done(s)
   713  		r.Respond(s)
   714  
   715  	case *fuse.ReadlinkRequest:
   716  		n, ok := node.(NodeReadlinker)
   717  		if !ok {
   718  			done(fuse.EIO) /// XXX or EPERM?
   719  			r.RespondError(fuse.EIO)
   720  			break
   721  		}
   722  		target, err := n.Readlink(r, intr)
   723  		if err != nil {
   724  			done(err)
   725  			r.RespondError(err)
   726  			break
   727  		}
   728  		done(target)
   729  		r.Respond(target)
   730  
   731  	case *fuse.LinkRequest:
   732  		n, ok := node.(NodeLinker)
   733  		if !ok {
   734  			done(fuse.EIO) /// XXX or EPERM?
   735  			r.RespondError(fuse.EIO)
   736  			break
   737  		}
   738  		c.meta.Lock()
   739  		var oldNode *serveNode
   740  		if int(r.OldNode) < len(c.node) {
   741  			oldNode = c.node[r.OldNode]
   742  		}
   743  		c.meta.Unlock()
   744  		if oldNode == nil {
   745  			fuse.Debug(logLinkRequestOldNodeNotFound{
   746  				Request: r.Hdr(),
   747  				In:      r,
   748  			})
   749  			done(fuse.EIO)
   750  			r.RespondError(fuse.EIO)
   751  			break
   752  		}
   753  		n2, err := n.Link(r, oldNode.node, intr)
   754  		if err != nil {
   755  			done(err)
   756  			r.RespondError(err)
   757  			break
   758  		}
   759  		s := &fuse.LookupResponse{}
   760  		c.saveLookup(s, snode, r.NewName, n2)
   761  		done(s)
   762  		r.Respond(s)
   763  
   764  	case *fuse.RemoveRequest:
   765  		n, ok := node.(NodeRemover)
   766  		if !ok {
   767  			done(fuse.EIO) /// XXX or EPERM?
   768  			r.RespondError(fuse.EIO)
   769  			break
   770  		}
   771  		err := n.Remove(r, intr)
   772  		if err != nil {
   773  			done(err)
   774  			r.RespondError(err)
   775  			break
   776  		}
   777  		done(nil)
   778  		r.Respond()
   779  
   780  	case *fuse.AccessRequest:
   781  		if n, ok := node.(NodeAccesser); ok {
   782  			if err := n.Access(r, intr); err != nil {
   783  				done(err)
   784  				r.RespondError(err)
   785  				break
   786  			}
   787  		}
   788  		done(nil)
   789  		r.Respond()
   790  
   791  	case *fuse.LookupRequest:
   792  		var n2 Node
   793  		var err fuse.Error
   794  		s := &fuse.LookupResponse{}
   795  		if n, ok := node.(NodeStringLookuper); ok {
   796  			n2, err = n.Lookup(r.Name, intr)
   797  		} else if n, ok := node.(NodeRequestLookuper); ok {
   798  			n2, err = n.Lookup(r, s, intr)
   799  		} else {
   800  			done(fuse.ENOENT)
   801  			r.RespondError(fuse.ENOENT)
   802  			break
   803  		}
   804  		if err != nil {
   805  			done(err)
   806  			r.RespondError(err)
   807  			break
   808  		}
   809  		c.saveLookup(s, snode, r.Name, n2)
   810  		done(s)
   811  		r.Respond(s)
   812  
   813  	case *fuse.MkdirRequest:
   814  		s := &fuse.MkdirResponse{}
   815  		n, ok := node.(NodeMkdirer)
   816  		if !ok {
   817  			done(fuse.EPERM)
   818  			r.RespondError(fuse.EPERM)
   819  			break
   820  		}
   821  		n2, err := n.Mkdir(r, intr)
   822  		if err != nil {
   823  			done(err)
   824  			r.RespondError(err)
   825  			break
   826  		}
   827  		c.saveLookup(&s.LookupResponse, snode, r.Name, n2)
   828  		done(s)
   829  		r.Respond(s)
   830  
   831  	case *fuse.OpenRequest:
   832  		s := &fuse.OpenResponse{Flags: fuse.OpenDirectIO}
   833  		var h2 Handle
   834  		if n, ok := node.(NodeOpener); ok {
   835  			hh, err := n.Open(r, s, intr)
   836  			if err != nil {
   837  				done(err)
   838  				r.RespondError(err)
   839  				break
   840  			}
   841  			h2 = hh
   842  		} else {
   843  			h2 = node
   844  		}
   845  		s.Handle = c.saveHandle(h2, hdr.Node)
   846  		done(s)
   847  		r.Respond(s)
   848  
   849  	case *fuse.CreateRequest:
   850  		n, ok := node.(NodeCreater)
   851  		if !ok {
   852  			// If we send back ENOSYS, FUSE will try mknod+open.
   853  			done(fuse.EPERM)
   854  			r.RespondError(fuse.EPERM)
   855  			break
   856  		}
   857  		s := &fuse.CreateResponse{OpenResponse: fuse.OpenResponse{Flags: fuse.OpenDirectIO}}
   858  		n2, h2, err := n.Create(r, s, intr)
   859  		if err != nil {
   860  			done(err)
   861  			r.RespondError(err)
   862  			break
   863  		}
   864  		c.saveLookup(&s.LookupResponse, snode, r.Name, n2)
   865  		s.Handle = c.saveHandle(h2, hdr.Node)
   866  		done(s)
   867  		r.Respond(s)
   868  
   869  	case *fuse.GetxattrRequest:
   870  		n, ok := node.(NodeGetxattrer)
   871  		if !ok {
   872  			done(fuse.ENOTSUP)
   873  			r.RespondError(fuse.ENOTSUP)
   874  			break
   875  		}
   876  		s := &fuse.GetxattrResponse{}
   877  		err := n.Getxattr(r, s, intr)
   878  		if err != nil {
   879  			done(err)
   880  			r.RespondError(err)
   881  			break
   882  		}
   883  		if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) {
   884  			done(fuse.ERANGE)
   885  			r.RespondError(fuse.ERANGE)
   886  			break
   887  		}
   888  		done(s)
   889  		r.Respond(s)
   890  
   891  	case *fuse.ListxattrRequest:
   892  		n, ok := node.(NodeListxattrer)
   893  		if !ok {
   894  			done(fuse.ENOTSUP)
   895  			r.RespondError(fuse.ENOTSUP)
   896  			break
   897  		}
   898  		s := &fuse.ListxattrResponse{}
   899  		err := n.Listxattr(r, s, intr)
   900  		if err != nil {
   901  			done(err)
   902  			r.RespondError(err)
   903  			break
   904  		}
   905  		if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) {
   906  			done(fuse.ERANGE)
   907  			r.RespondError(fuse.ERANGE)
   908  			break
   909  		}
   910  		done(s)
   911  		r.Respond(s)
   912  
   913  	case *fuse.SetxattrRequest:
   914  		n, ok := node.(NodeSetxattrer)
   915  		if !ok {
   916  			done(fuse.ENOTSUP)
   917  			r.RespondError(fuse.ENOTSUP)
   918  			break
   919  		}
   920  		err := n.Setxattr(r, intr)
   921  		if err != nil {
   922  			done(err)
   923  			r.RespondError(err)
   924  			break
   925  		}
   926  		done(nil)
   927  		r.Respond()
   928  
   929  	case *fuse.RemovexattrRequest:
   930  		n, ok := node.(NodeRemovexattrer)
   931  		if !ok {
   932  			done(fuse.ENOTSUP)
   933  			r.RespondError(fuse.ENOTSUP)
   934  			break
   935  		}
   936  		err := n.Removexattr(r, intr)
   937  		if err != nil {
   938  			done(err)
   939  			r.RespondError(err)
   940  			break
   941  		}
   942  		done(nil)
   943  		r.Respond()
   944  
   945  	case *fuse.ForgetRequest:
   946  		forget := c.dropNode(hdr.Node, r.N)
   947  		if forget {
   948  			n, ok := node.(NodeForgetter)
   949  			if ok {
   950  				n.Forget()
   951  			}
   952  		}
   953  		done(nil)
   954  		r.Respond()
   955  
   956  	// Handle operations.
   957  	case *fuse.ReadRequest:
   958  		shandle := c.getHandle(r.Handle)
   959  		if shandle == nil {
   960  			done(fuse.ESTALE)
   961  			r.RespondError(fuse.ESTALE)
   962  			return
   963  		}
   964  		handle := shandle.handle
   965  
   966  		s := &fuse.ReadResponse{Data: make([]byte, 0, r.Size)}
   967  		if r.Dir {
   968  			if h, ok := handle.(HandleReadDirer); ok {
   969  				if shandle.readData == nil {
   970  					dirs, err := h.ReadDir(intr)
   971  					if err != nil {
   972  						done(err)
   973  						r.RespondError(err)
   974  						break
   975  					}
   976  					var data []byte
   977  					for _, dir := range dirs {
   978  						if dir.Inode == 0 {
   979  							dir.Inode = hash(path.Join(snode.name, dir.Name))
   980  						}
   981  						data = fuse.AppendDirent(data, dir)
   982  					}
   983  					shandle.readData = data
   984  				}
   985  				fuseutil.HandleRead(r, s, shandle.readData)
   986  				done(s)
   987  				r.Respond(s)
   988  				break
   989  			}
   990  		} else {
   991  			if h, ok := handle.(HandleReadAller); ok {
   992  				if shandle.readData == nil {
   993  					data, err := h.ReadAll(intr)
   994  					if err != nil {
   995  						done(err)
   996  						r.RespondError(err)
   997  						break
   998  					}
   999  					if data == nil {
  1000  						data = []byte{}
  1001  					}
  1002  					shandle.readData = data
  1003  				}
  1004  				fuseutil.HandleRead(r, s, shandle.readData)
  1005  				done(s)
  1006  				r.Respond(s)
  1007  				break
  1008  			}
  1009  			h, ok := handle.(HandleReader)
  1010  			if !ok {
  1011  				fmt.Printf("NO READ FOR %T\n", handle)
  1012  				done(fuse.EIO)
  1013  				r.RespondError(fuse.EIO)
  1014  				break
  1015  			}
  1016  			if err := h.Read(r, s, intr); err != nil {
  1017  				done(err)
  1018  				r.RespondError(err)
  1019  				break
  1020  			}
  1021  		}
  1022  		done(s)
  1023  		r.Respond(s)
  1024  
  1025  	case *fuse.WriteRequest:
  1026  		shandle := c.getHandle(r.Handle)
  1027  		if shandle == nil {
  1028  			done(fuse.ESTALE)
  1029  			r.RespondError(fuse.ESTALE)
  1030  			return
  1031  		}
  1032  
  1033  		s := &fuse.WriteResponse{}
  1034  		if h, ok := shandle.handle.(HandleWriter); ok {
  1035  			if err := h.Write(r, s, intr); err != nil {
  1036  				done(err)
  1037  				r.RespondError(err)
  1038  				break
  1039  			}
  1040  			done(s)
  1041  			r.Respond(s)
  1042  			break
  1043  		}
  1044  		done(fuse.EIO)
  1045  		r.RespondError(fuse.EIO)
  1046  
  1047  	case *fuse.FlushRequest:
  1048  		shandle := c.getHandle(r.Handle)
  1049  		if shandle == nil {
  1050  			done(fuse.ESTALE)
  1051  			r.RespondError(fuse.ESTALE)
  1052  			return
  1053  		}
  1054  		handle := shandle.handle
  1055  
  1056  		if h, ok := handle.(HandleFlusher); ok {
  1057  			if err := h.Flush(r, intr); err != nil {
  1058  				done(err)
  1059  				r.RespondError(err)
  1060  				break
  1061  			}
  1062  		}
  1063  		done(nil)
  1064  		r.Respond()
  1065  
  1066  	case *fuse.ReleaseRequest:
  1067  		shandle := c.getHandle(r.Handle)
  1068  		if shandle == nil {
  1069  			done(fuse.ESTALE)
  1070  			r.RespondError(fuse.ESTALE)
  1071  			return
  1072  		}
  1073  		handle := shandle.handle
  1074  
  1075  		// No matter what, release the handle.
  1076  		c.dropHandle(r.Handle)
  1077  
  1078  		if h, ok := handle.(HandleReleaser); ok {
  1079  			if err := h.Release(r, intr); err != nil {
  1080  				done(err)
  1081  				r.RespondError(err)
  1082  				break
  1083  			}
  1084  		}
  1085  		done(nil)
  1086  		r.Respond()
  1087  
  1088  	case *fuse.DestroyRequest:
  1089  		if fs, ok := fs.(FSDestroyer); ok {
  1090  			fs.Destroy()
  1091  		}
  1092  		done(nil)
  1093  		r.Respond()
  1094  
  1095  	case *fuse.RenameRequest:
  1096  		c.meta.Lock()
  1097  		var newDirNode *serveNode
  1098  		if int(r.NewDir) < len(c.node) {
  1099  			newDirNode = c.node[r.NewDir]
  1100  		}
  1101  		c.meta.Unlock()
  1102  		if newDirNode == nil {
  1103  			fuse.Debug(renameNewDirNodeNotFound{
  1104  				Request: r.Hdr(),
  1105  				In:      r,
  1106  			})
  1107  			done(fuse.EIO)
  1108  			r.RespondError(fuse.EIO)
  1109  			break
  1110  		}
  1111  		n, ok := node.(NodeRenamer)
  1112  		if !ok {
  1113  			done(fuse.EIO) // XXX or EPERM like Mkdir?
  1114  			r.RespondError(fuse.EIO)
  1115  			break
  1116  		}
  1117  		err := n.Rename(r, newDirNode.node, intr)
  1118  		if err != nil {
  1119  			done(err)
  1120  			r.RespondError(err)
  1121  			break
  1122  		}
  1123  		done(nil)
  1124  		r.Respond()
  1125  
  1126  	case *fuse.MknodRequest:
  1127  		n, ok := node.(NodeMknoder)
  1128  		if !ok {
  1129  			done(fuse.EIO)
  1130  			r.RespondError(fuse.EIO)
  1131  			break
  1132  		}
  1133  		n2, err := n.Mknod(r, intr)
  1134  		if err != nil {
  1135  			done(err)
  1136  			r.RespondError(err)
  1137  			break
  1138  		}
  1139  		s := &fuse.LookupResponse{}
  1140  		c.saveLookup(s, snode, r.Name, n2)
  1141  		done(s)
  1142  		r.Respond(s)
  1143  
  1144  	case *fuse.FsyncRequest:
  1145  		n, ok := node.(NodeFsyncer)
  1146  		if !ok {
  1147  			done(fuse.EIO)
  1148  			r.RespondError(fuse.EIO)
  1149  			break
  1150  		}
  1151  		err := n.Fsync(r, intr)
  1152  		if err != nil {
  1153  			done(err)
  1154  			r.RespondError(err)
  1155  			break
  1156  		}
  1157  		done(nil)
  1158  		r.Respond()
  1159  
  1160  	case *fuse.InterruptRequest:
  1161  		c.meta.Lock()
  1162  		ireq := c.req[r.IntrID]
  1163  		if ireq != nil && ireq.Intr != nil {
  1164  			close(ireq.Intr)
  1165  			ireq.Intr = nil
  1166  		}
  1167  		c.meta.Unlock()
  1168  		done(nil)
  1169  		r.Respond()
  1170  
  1171  		/*	case *FsyncdirRequest:
  1172  				done(ENOSYS)
  1173  				r.RespondError(ENOSYS)
  1174  
  1175  			case *GetlkRequest, *SetlkRequest, *SetlkwRequest:
  1176  				done(ENOSYS)
  1177  				r.RespondError(ENOSYS)
  1178  
  1179  			case *BmapRequest:
  1180  				done(ENOSYS)
  1181  				r.RespondError(ENOSYS)
  1182  
  1183  			case *SetvolnameRequest, *GetxtimesRequest, *ExchangeRequest:
  1184  				done(ENOSYS)
  1185  				r.RespondError(ENOSYS)
  1186  		*/
  1187  	}
  1188  }
  1189  
  1190  func (c *serveConn) saveLookup(s *fuse.LookupResponse, snode *serveNode, elem string, n2 Node) {
  1191  	name := path.Join(snode.name, elem)
  1192  	var sn *serveNode
  1193  	s.Node, s.Generation, sn = c.saveNode(name, n2)
  1194  	if s.EntryValid == 0 {
  1195  		s.EntryValid = entryValidTime
  1196  	}
  1197  	if s.AttrValid == 0 {
  1198  		s.AttrValid = attrValidTime
  1199  	}
  1200  	s.Attr = sn.attr()
  1201  }
  1202  
  1203  // DataHandle returns a read-only Handle that satisfies reads
  1204  // using the given data.
  1205  func DataHandle(data []byte) Handle {
  1206  	return &dataHandle{data}
  1207  }
  1208  
  1209  type dataHandle struct {
  1210  	data []byte
  1211  }
  1212  
  1213  func (d *dataHandle) ReadAll(intr Intr) ([]byte, fuse.Error) {
  1214  	return d.data, nil
  1215  }