github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/third_party/code.google.com/p/rsc/fuse/serve.go (about)

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