1// FUSE service loop, for servers that wish to use it.
2
3package fs // import "bazil.org/fuse/fs"
4
5import (
6	"encoding/binary"
7	"fmt"
8	"hash/fnv"
9	"io"
10	"log"
11	"reflect"
12	"runtime"
13	"strings"
14	"sync"
15	"time"
16
17	"golang.org/x/net/context"
18)
19
20import (
21	"bytes"
22
23	"bazil.org/fuse"
24	"bazil.org/fuse/fuseutil"
25)
26
27const (
28	attrValidTime  = 1 * time.Minute
29	entryValidTime = 1 * time.Minute
30)
31
32// TODO: FINISH DOCS
33
34// An FS is the interface required of a file system.
35//
36// Other FUSE requests can be handled by implementing methods from the
37// FS* interfaces, for example FSStatfser.
38type FS interface {
39	// Root is called to obtain the Node for the file system root.
40	Root() (Node, error)
41}
42
43type FSStatfser interface {
44	// Statfs is called to obtain file system metadata.
45	// It should write that data to resp.
46	Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error
47}
48
49type FSDestroyer interface {
50	// Destroy is called when the file system is shutting down.
51	//
52	// Linux only sends this request for block device backed (fuseblk)
53	// filesystems, to allow them to flush writes to disk before the
54	// unmount completes.
55	Destroy()
56}
57
58type FSInodeGenerator interface {
59	// GenerateInode is called to pick a dynamic inode number when it
60	// would otherwise be 0.
61	//
62	// Not all filesystems bother tracking inodes, but FUSE requires
63	// the inode to be set, and fewer duplicates in general makes UNIX
64	// tools work better.
65	//
66	// Operations where the nodes may return 0 inodes include Getattr,
67	// Setattr and ReadDir.
68	//
69	// If FS does not implement FSInodeGenerator, GenerateDynamicInode
70	// is used.
71	//
72	// Implementing this is useful to e.g. constrain the range of
73	// inode values used for dynamic inodes.
74	GenerateInode(parentInode uint64, name string) uint64
75}
76
77// A Node is the interface required of a file or directory.
78// See the documentation for type FS for general information
79// pertaining to all methods.
80//
81// A Node must be usable as a map key, that is, it cannot be a
82// function, map or slice.
83//
84// Other FUSE requests can be handled by implementing methods from the
85// Node* interfaces, for example NodeOpener.
86//
87// Methods returning Node should take care to return the same Node
88// when the result is logically the same instance. Without this, each
89// Node will get a new NodeID, causing spurious cache invalidations,
90// extra lookups and aliasing anomalies. This may not matter for a
91// simple, read-only filesystem.
92type Node interface {
93	// Attr fills attr with the standard metadata for the node.
94	//
95	// Fields with reasonable defaults are prepopulated. For example,
96	// all times are set to a fixed moment when the program started.
97	//
98	// If Inode is left as 0, a dynamic inode number is chosen.
99	//
100	// The result may be cached for the duration set in Valid.
101	Attr(ctx context.Context, attr *fuse.Attr) error
102}
103
104type NodeGetattrer interface {
105	// Getattr obtains the standard metadata for the receiver.
106	// It should store that metadata in resp.
107	//
108	// If this method is not implemented, the attributes will be
109	// generated based on Attr(), with zero values filled in.
110	Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error
111}
112
113type NodeSetattrer interface {
114	// Setattr sets the standard metadata for the receiver.
115	//
116	// Note, this is also used to communicate changes in the size of
117	// the file, outside of Writes.
118	//
119	// req.Valid is a bitmask of what fields are actually being set.
120	// For example, the method should not change the mode of the file
121	// unless req.Valid.Mode() is true.
122	Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error
123}
124
125type NodeSymlinker interface {
126	// Symlink creates a new symbolic link in the receiver, which must be a directory.
127	//
128	// TODO is the above true about directories?
129	Symlink(ctx context.Context, req *fuse.SymlinkRequest) (Node, error)
130}
131
132// This optional request will be called only for symbolic link nodes.
133type NodeReadlinker interface {
134	// Readlink reads a symbolic link.
135	Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error)
136}
137
138type NodeLinker interface {
139	// Link creates a new directory entry in the receiver based on an
140	// existing Node. Receiver must be a directory.
141	Link(ctx context.Context, req *fuse.LinkRequest, old Node) (Node, error)
142}
143
144type NodeRemover interface {
145	// Remove removes the entry with the given name from
146	// the receiver, which must be a directory.  The entry to be removed
147	// may correspond to a file (unlink) or to a directory (rmdir).
148	Remove(ctx context.Context, req *fuse.RemoveRequest) error
149}
150
151type NodeAccesser interface {
152	// Access checks whether the calling context has permission for
153	// the given operations on the receiver. If so, Access should
154	// return nil. If not, Access should return EPERM.
155	//
156	// Note that this call affects the result of the access(2) system
157	// call but not the open(2) system call. If Access is not
158	// implemented, the Node behaves as if it always returns nil
159	// (permission granted), relying on checks in Open instead.
160	Access(ctx context.Context, req *fuse.AccessRequest) error
161}
162
163type NodeStringLookuper interface {
164	// Lookup looks up a specific entry in the receiver,
165	// which must be a directory.  Lookup should return a Node
166	// corresponding to the entry.  If the name does not exist in
167	// the directory, Lookup should return ENOENT.
168	//
169	// Lookup need not to handle the names "." and "..".
170	Lookup(ctx context.Context, name string) (Node, error)
171}
172
173type NodeRequestLookuper interface {
174	// Lookup looks up a specific entry in the receiver.
175	// See NodeStringLookuper for more.
176	Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (Node, error)
177}
178
179type NodeMkdirer interface {
180	Mkdir(ctx context.Context, req *fuse.MkdirRequest) (Node, error)
181}
182
183type NodeOpener interface {
184	// Open opens the receiver. After a successful open, a client
185	// process has a file descriptor referring to this Handle.
186	//
187	// Open can also be also called on non-files. For example,
188	// directories are Opened for ReadDir or fchdir(2).
189	//
190	// If this method is not implemented, the open will always
191	// succeed, and the Node itself will be used as the Handle.
192	//
193	// XXX note about access.  XXX OpenFlags.
194	Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (Handle, error)
195}
196
197type NodeCreater interface {
198	// Create creates a new directory entry in the receiver, which
199	// must be a directory.
200	Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (Node, Handle, error)
201}
202
203type NodeForgetter interface {
204	// Forget about this node. This node will not receive further
205	// method calls.
206	//
207	// Forget is not necessarily seen on unmount, as all nodes are
208	// implicitly forgotten as part part of the unmount.
209	Forget()
210}
211
212type NodeRenamer interface {
213	Rename(ctx context.Context, req *fuse.RenameRequest, newDir Node) error
214}
215
216type NodeMknoder interface {
217	Mknod(ctx context.Context, req *fuse.MknodRequest) (Node, error)
218}
219
220// TODO this should be on Handle not Node
221type NodeFsyncer interface {
222	Fsync(ctx context.Context, req *fuse.FsyncRequest) error
223}
224
225type NodeGetxattrer interface {
226	// Getxattr gets an extended attribute by the given name from the
227	// node.
228	//
229	// If there is no xattr by that name, returns fuse.ErrNoXattr.
230	Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error
231}
232
233type NodeListxattrer interface {
234	// Listxattr lists the extended attributes recorded for the node.
235	Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error
236}
237
238type NodeSetxattrer interface {
239	// Setxattr sets an extended attribute with the given name and
240	// value for the node.
241	Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error
242}
243
244type NodeRemovexattrer interface {
245	// Removexattr removes an extended attribute for the name.
246	//
247	// If there is no xattr by that name, returns fuse.ErrNoXattr.
248	Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error
249}
250
251var startTime = time.Now()
252
253func nodeAttr(ctx context.Context, n Node, attr *fuse.Attr) error {
254	attr.Valid = attrValidTime
255	attr.Nlink = 1
256	attr.Atime = startTime
257	attr.Mtime = startTime
258	attr.Ctime = startTime
259	attr.Crtime = startTime
260	if err := n.Attr(ctx, attr); err != nil {
261		return err
262	}
263	return nil
264}
265
266// A Handle is the interface required of an opened file or directory.
267// See the documentation for type FS for general information
268// pertaining to all methods.
269//
270// Other FUSE requests can be handled by implementing methods from the
271// Handle* interfaces. The most common to implement are HandleReader,
272// HandleReadDirer, and HandleWriter.
273//
274// TODO implement methods: Getlk, Setlk, Setlkw
275type Handle interface {
276}
277
278type HandleFlusher interface {
279	// Flush is called each time the file or directory is closed.
280	// Because there can be multiple file descriptors referring to a
281	// single opened file, Flush can be called multiple times.
282	Flush(ctx context.Context, req *fuse.FlushRequest) error
283}
284
285type HandleReadAller interface {
286	ReadAll(ctx context.Context) ([]byte, error)
287}
288
289type HandleReadDirAller interface {
290	ReadDirAll(ctx context.Context) ([]fuse.Dirent, error)
291}
292
293type HandleReader interface {
294	// Read requests to read data from the handle.
295	//
296	// There is a page cache in the kernel that normally submits only
297	// page-aligned reads spanning one or more pages. However, you
298	// should not rely on this. To see individual requests as
299	// submitted by the file system clients, set OpenDirectIO.
300	//
301	// Note that reads beyond the size of the file as reported by Attr
302	// are not even attempted (except in OpenDirectIO mode).
303	Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error
304}
305
306type HandleWriter interface {
307	// Write requests to write data into the handle at the given offset.
308	// Store the amount of data written in resp.Size.
309	//
310	// There is a writeback page cache in the kernel that normally submits
311	// only page-aligned writes spanning one or more pages. However,
312	// you should not rely on this. To see individual requests as
313	// submitted by the file system clients, set OpenDirectIO.
314	//
315	// Writes that grow the file are expected to update the file size
316	// (as seen through Attr). Note that file size changes are
317	// communicated also through Setattr.
318	Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error
319}
320
321type HandleReleaser interface {
322	Release(ctx context.Context, req *fuse.ReleaseRequest) error
323}
324
325type Config struct {
326	// Function to send debug log messages to. If nil, use fuse.Debug.
327	// Note that changing this or fuse.Debug may not affect existing
328	// calls to Serve.
329	//
330	// See fuse.Debug for the rules that log functions must follow.
331	Debug func(msg interface{})
332
333	// Function to put things into context for processing the request.
334	// The returned context must have ctx as its parent.
335	//
336	// Note that changing this may not affect existing calls to Serve.
337	//
338	// Must not retain req.
339	WithContext func(ctx context.Context, req fuse.Request) context.Context
340}
341
342// New returns a new FUSE server ready to serve this kernel FUSE
343// connection.
344//
345// Config may be nil.
346func New(conn *fuse.Conn, config *Config) *Server {
347	s := &Server{
348		conn:         conn,
349		req:          map[fuse.RequestID]*serveRequest{},
350		nodeRef:      map[Node]fuse.NodeID{},
351		dynamicInode: GenerateDynamicInode,
352	}
353	if config != nil {
354		s.debug = config.Debug
355		s.context = config.WithContext
356	}
357	if s.debug == nil {
358		s.debug = fuse.Debug
359	}
360	return s
361}
362
363type Server struct {
364	// set in New
365	conn    *fuse.Conn
366	debug   func(msg interface{})
367	context func(ctx context.Context, req fuse.Request) context.Context
368
369	// set once at Serve time
370	fs           FS
371	dynamicInode func(parent uint64, name string) uint64
372
373	// state, protected by meta
374	meta       sync.Mutex
375	req        map[fuse.RequestID]*serveRequest
376	node       []*serveNode
377	nodeRef    map[Node]fuse.NodeID
378	handle     []*serveHandle
379	freeNode   []fuse.NodeID
380	freeHandle []fuse.HandleID
381	nodeGen    uint64
382
383	// Used to ensure worker goroutines finish before Serve returns
384	wg sync.WaitGroup
385}
386
387// Serve serves the FUSE connection by making calls to the methods
388// of fs and the Nodes and Handles it makes available.  It returns only
389// when the connection has been closed or an unexpected error occurs.
390func (s *Server) Serve(fs FS) error {
391	defer s.wg.Wait() // Wait for worker goroutines to complete before return
392
393	s.fs = fs
394	if dyn, ok := fs.(FSInodeGenerator); ok {
395		s.dynamicInode = dyn.GenerateInode
396	}
397
398	root, err := fs.Root()
399	if err != nil {
400		return fmt.Errorf("cannot obtain root node: %v", err)
401	}
402	// Recognize the root node if it's ever returned from Lookup,
403	// passed to Invalidate, etc.
404	s.nodeRef[root] = 1
405	s.node = append(s.node, nil, &serveNode{
406		inode:      1,
407		generation: s.nodeGen,
408		node:       root,
409		refs:       1,
410	})
411	s.handle = append(s.handle, nil)
412
413	for {
414		req, err := s.conn.ReadRequest()
415		if err != nil {
416			if err == io.EOF {
417				break
418			}
419			return err
420		}
421
422		s.wg.Add(1)
423		go func() {
424			defer s.wg.Done()
425			s.serve(req)
426		}()
427	}
428	return nil
429}
430
431// Serve serves a FUSE connection with the default settings. See
432// Server.Serve.
433func Serve(c *fuse.Conn, fs FS) error {
434	server := New(c, nil)
435	return server.Serve(fs)
436}
437
438type nothing struct{}
439
440type serveRequest struct {
441	Request fuse.Request
442	cancel  func()
443}
444
445type serveNode struct {
446	inode      uint64
447	generation uint64
448	node       Node
449	refs       uint64
450
451	// Delay freeing the NodeID until waitgroup is done. This allows
452	// using the NodeID for short periods of time without holding the
453	// Server.meta lock.
454	//
455	// Rules:
456	//
457	//     - hold Server.meta while calling wg.Add, then unlock
458	//     - do NOT try to reacquire Server.meta
459	wg sync.WaitGroup
460}
461
462func (sn *serveNode) attr(ctx context.Context, attr *fuse.Attr) error {
463	err := nodeAttr(ctx, sn.node, attr)
464	if attr.Inode == 0 {
465		attr.Inode = sn.inode
466	}
467	return err
468}
469
470type serveHandle struct {
471	handle   Handle
472	readData []byte
473	nodeID   fuse.NodeID
474}
475
476// NodeRef is deprecated. It remains here to decrease code churn on
477// FUSE library users. You may remove it from your program now;
478// returning the same Node values are now recognized automatically,
479// without needing NodeRef.
480type NodeRef struct{}
481
482func (c *Server) saveNode(inode uint64, node Node) (id fuse.NodeID, gen uint64) {
483	c.meta.Lock()
484	defer c.meta.Unlock()
485
486	if id, ok := c.nodeRef[node]; ok {
487		sn := c.node[id]
488		sn.refs++
489		return id, sn.generation
490	}
491
492	sn := &serveNode{inode: inode, node: node, refs: 1}
493	if n := len(c.freeNode); n > 0 {
494		id = c.freeNode[n-1]
495		c.freeNode = c.freeNode[:n-1]
496		c.node[id] = sn
497		c.nodeGen++
498	} else {
499		id = fuse.NodeID(len(c.node))
500		c.node = append(c.node, sn)
501	}
502	sn.generation = c.nodeGen
503	c.nodeRef[node] = id
504	return id, sn.generation
505}
506
507func (c *Server) saveHandle(handle Handle, nodeID fuse.NodeID) (id fuse.HandleID) {
508	c.meta.Lock()
509	shandle := &serveHandle{handle: handle, nodeID: nodeID}
510	if n := len(c.freeHandle); n > 0 {
511		id = c.freeHandle[n-1]
512		c.freeHandle = c.freeHandle[:n-1]
513		c.handle[id] = shandle
514	} else {
515		id = fuse.HandleID(len(c.handle))
516		c.handle = append(c.handle, shandle)
517	}
518	c.meta.Unlock()
519	return
520}
521
522type nodeRefcountDropBug struct {
523	N    uint64
524	Refs uint64
525	Node fuse.NodeID
526}
527
528func (n *nodeRefcountDropBug) String() string {
529	return fmt.Sprintf("bug: trying to drop %d of %d references to %v", n.N, n.Refs, n.Node)
530}
531
532func (c *Server) dropNode(id fuse.NodeID, n uint64) (forget bool) {
533	c.meta.Lock()
534	defer c.meta.Unlock()
535	snode := c.node[id]
536
537	if snode == nil {
538		// this should only happen if refcounts kernel<->us disagree
539		// *and* two ForgetRequests for the same node race each other;
540		// this indicates a bug somewhere
541		c.debug(nodeRefcountDropBug{N: n, Node: id})
542
543		// we may end up triggering Forget twice, but that's better
544		// than not even once, and that's the best we can do
545		return true
546	}
547
548	if n > snode.refs {
549		c.debug(nodeRefcountDropBug{N: n, Refs: snode.refs, Node: id})
550		n = snode.refs
551	}
552
553	snode.refs -= n
554	if snode.refs == 0 {
555		snode.wg.Wait()
556		c.node[id] = nil
557		delete(c.nodeRef, snode.node)
558		c.freeNode = append(c.freeNode, id)
559		return true
560	}
561	return false
562}
563
564func (c *Server) dropHandle(id fuse.HandleID) {
565	c.meta.Lock()
566	c.handle[id] = nil
567	c.freeHandle = append(c.freeHandle, id)
568	c.meta.Unlock()
569}
570
571type missingHandle struct {
572	Handle    fuse.HandleID
573	MaxHandle fuse.HandleID
574}
575
576func (m missingHandle) String() string {
577	return fmt.Sprint("missing handle: ", m.Handle, m.MaxHandle)
578}
579
580// Returns nil for invalid handles.
581func (c *Server) getHandle(id fuse.HandleID) (shandle *serveHandle) {
582	c.meta.Lock()
583	defer c.meta.Unlock()
584	if id < fuse.HandleID(len(c.handle)) {
585		shandle = c.handle[uint(id)]
586	}
587	if shandle == nil {
588		c.debug(missingHandle{
589			Handle:    id,
590			MaxHandle: fuse.HandleID(len(c.handle)),
591		})
592	}
593	return
594}
595
596type request struct {
597	Op      string
598	Request *fuse.Header
599	In      interface{} `json:",omitempty"`
600}
601
602func (r request) String() string {
603	return fmt.Sprintf("<- %s", r.In)
604}
605
606type logResponseHeader struct {
607	ID fuse.RequestID
608}
609
610func (m logResponseHeader) String() string {
611	return fmt.Sprintf("ID=%v", m.ID)
612}
613
614type response struct {
615	Op      string
616	Request logResponseHeader
617	Out     interface{} `json:",omitempty"`
618	// Errno contains the errno value as a string, for example "EPERM".
619	Errno string `json:",omitempty"`
620	// Error may contain a free form error message.
621	Error string `json:",omitempty"`
622}
623
624func (r response) errstr() string {
625	s := r.Errno
626	if r.Error != "" {
627		// prefix the errno constant to the long form message
628		s = s + ": " + r.Error
629	}
630	return s
631}
632
633func (r response) String() string {
634	switch {
635	case r.Errno != "" && r.Out != nil:
636		return fmt.Sprintf("-> [%v] %v error=%s", r.Request, r.Out, r.errstr())
637	case r.Errno != "":
638		return fmt.Sprintf("-> [%v] %s error=%s", r.Request, r.Op, r.errstr())
639	case r.Out != nil:
640		// make sure (seemingly) empty values are readable
641		switch r.Out.(type) {
642		case string:
643			return fmt.Sprintf("-> [%v] %s %q", r.Request, r.Op, r.Out)
644		case []byte:
645			return fmt.Sprintf("-> [%v] %s [% x]", r.Request, r.Op, r.Out)
646		default:
647			return fmt.Sprintf("-> [%v] %v", r.Request, r.Out)
648		}
649	default:
650		return fmt.Sprintf("-> [%v] %s", r.Request, r.Op)
651	}
652}
653
654type notification struct {
655	Op   string
656	Node fuse.NodeID
657	Out  interface{} `json:",omitempty"`
658	Err  string      `json:",omitempty"`
659}
660
661func (n notification) String() string {
662	var buf bytes.Buffer
663	fmt.Fprintf(&buf, "=> %s %v", n.Op, n.Node)
664	if n.Out != nil {
665		// make sure (seemingly) empty values are readable
666		switch n.Out.(type) {
667		case string:
668			fmt.Fprintf(&buf, " %q", n.Out)
669		case []byte:
670			fmt.Fprintf(&buf, " [% x]", n.Out)
671		default:
672			fmt.Fprintf(&buf, " %s", n.Out)
673		}
674	}
675	if n.Err != "" {
676		fmt.Fprintf(&buf, " Err:%v", n.Err)
677	}
678	return buf.String()
679}
680
681type logMissingNode struct {
682	MaxNode fuse.NodeID
683}
684
685func opName(req fuse.Request) string {
686	t := reflect.Indirect(reflect.ValueOf(req)).Type()
687	s := t.Name()
688	s = strings.TrimSuffix(s, "Request")
689	return s
690}
691
692type logLinkRequestOldNodeNotFound struct {
693	Request *fuse.Header
694	In      *fuse.LinkRequest
695}
696
697func (m *logLinkRequestOldNodeNotFound) String() string {
698	return fmt.Sprintf("In LinkRequest (request %v), node %d not found", m.Request.Hdr().ID, m.In.OldNode)
699}
700
701type renameNewDirNodeNotFound struct {
702	Request *fuse.Header
703	In      *fuse.RenameRequest
704}
705
706func (m *renameNewDirNodeNotFound) String() string {
707	return fmt.Sprintf("In RenameRequest (request %v), node %d not found", m.Request.Hdr().ID, m.In.NewDir)
708}
709
710type handlerPanickedError struct {
711	Request interface{}
712	Err     interface{}
713}
714
715var _ error = handlerPanickedError{}
716
717func (h handlerPanickedError) Error() string {
718	return fmt.Sprintf("handler panicked: %v", h.Err)
719}
720
721var _ fuse.ErrorNumber = handlerPanickedError{}
722
723func (h handlerPanickedError) Errno() fuse.Errno {
724	if err, ok := h.Err.(fuse.ErrorNumber); ok {
725		return err.Errno()
726	}
727	return fuse.DefaultErrno
728}
729
730// handlerTerminatedError happens when a handler terminates itself
731// with runtime.Goexit. This is most commonly because of incorrect use
732// of testing.TB.FailNow, typically via t.Fatal.
733type handlerTerminatedError struct {
734	Request interface{}
735}
736
737var _ error = handlerTerminatedError{}
738
739func (h handlerTerminatedError) Error() string {
740	return fmt.Sprintf("handler terminated (called runtime.Goexit)")
741}
742
743var _ fuse.ErrorNumber = handlerTerminatedError{}
744
745func (h handlerTerminatedError) Errno() fuse.Errno {
746	return fuse.DefaultErrno
747}
748
749type handleNotReaderError struct {
750	handle Handle
751}
752
753var _ error = handleNotReaderError{}
754
755func (e handleNotReaderError) Error() string {
756	return fmt.Sprintf("handle has no Read: %T", e.handle)
757}
758
759var _ fuse.ErrorNumber = handleNotReaderError{}
760
761func (e handleNotReaderError) Errno() fuse.Errno {
762	return fuse.ENOTSUP
763}
764
765func initLookupResponse(s *fuse.LookupResponse) {
766	s.EntryValid = entryValidTime
767}
768
769func (c *Server) serve(r fuse.Request) {
770	ctx, cancel := context.WithCancel(context.Background())
771	defer cancel()
772	parentCtx := ctx
773	if c.context != nil {
774		ctx = c.context(ctx, r)
775	}
776
777	req := &serveRequest{Request: r, cancel: cancel}
778
779	c.debug(request{
780		Op:      opName(r),
781		Request: r.Hdr(),
782		In:      r,
783	})
784	var node Node
785	var snode *serveNode
786	c.meta.Lock()
787	hdr := r.Hdr()
788	if id := hdr.Node; id != 0 {
789		if id < fuse.NodeID(len(c.node)) {
790			snode = c.node[uint(id)]
791		}
792		if snode == nil {
793			c.meta.Unlock()
794			c.debug(response{
795				Op:      opName(r),
796				Request: logResponseHeader{ID: hdr.ID},
797				Error:   fuse.ESTALE.ErrnoName(),
798				// this is the only place that sets both Error and
799				// Out; not sure if i want to do that; might get rid
800				// of len(c.node) things altogether
801				Out: logMissingNode{
802					MaxNode: fuse.NodeID(len(c.node)),
803				},
804			})
805			r.RespondError(fuse.ESTALE)
806			return
807		}
808		node = snode.node
809	}
810	if c.req[hdr.ID] != nil {
811		// This happens with OSXFUSE.  Assume it's okay and
812		// that we'll never see an interrupt for this one.
813		// Otherwise everything wedges.  TODO: Report to OSXFUSE?
814		//
815		// TODO this might have been because of missing done() calls
816	} else {
817		c.req[hdr.ID] = req
818	}
819	c.meta.Unlock()
820
821	// Call this before responding.
822	// After responding is too late: we might get another request
823	// with the same ID and be very confused.
824	done := func(resp interface{}) {
825		msg := response{
826			Op:      opName(r),
827			Request: logResponseHeader{ID: hdr.ID},
828		}
829		if err, ok := resp.(error); ok {
830			msg.Error = err.Error()
831			if ferr, ok := err.(fuse.ErrorNumber); ok {
832				errno := ferr.Errno()
833				msg.Errno = errno.ErrnoName()
834				if errno == err {
835					// it's just a fuse.Errno with no extra detail;
836					// skip the textual message for log readability
837					msg.Error = ""
838				}
839			} else {
840				msg.Errno = fuse.DefaultErrno.ErrnoName()
841			}
842		} else {
843			msg.Out = resp
844		}
845		c.debug(msg)
846
847		c.meta.Lock()
848		delete(c.req, hdr.ID)
849		c.meta.Unlock()
850	}
851
852	var responded bool
853	defer func() {
854		if rec := recover(); rec != nil {
855			const size = 1 << 16
856			buf := make([]byte, size)
857			n := runtime.Stack(buf, false)
858			buf = buf[:n]
859			log.Printf("fuse: panic in handler for %v: %v\n%s", r, rec, buf)
860			err := handlerPanickedError{
861				Request: r,
862				Err:     rec,
863			}
864			done(err)
865			r.RespondError(err)
866			return
867		}
868
869		if !responded {
870			err := handlerTerminatedError{
871				Request: r,
872			}
873			done(err)
874			r.RespondError(err)
875		}
876	}()
877
878	if err := c.handleRequest(ctx, node, snode, r, done); err != nil {
879		if err == context.Canceled {
880			select {
881			case <-parentCtx.Done():
882				// We canceled the parent context because of an
883				// incoming interrupt request, so return EINTR
884				// to trigger the right behavior in the client app.
885				//
886				// Only do this when it's the parent context that was
887				// canceled, not a context controlled by the program
888				// using this library, so we don't return EINTR too
889				// eagerly -- it might cause busy loops.
890				//
891				// Decent write-up on role of EINTR:
892				// http://250bpm.com/blog:12
893				err = fuse.EINTR
894			default:
895				// nothing
896			}
897		}
898		done(err)
899		r.RespondError(err)
900	}
901
902	// disarm runtime.Goexit protection
903	responded = true
904}
905
906// handleRequest will either a) call done(s) and r.Respond(s) OR b) return an error.
907func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode, r fuse.Request, done func(resp interface{})) error {
908	switch r := r.(type) {
909	default:
910		// Note: To FUSE, ENOSYS means "this server never implements this request."
911		// It would be inappropriate to return ENOSYS for other operations in this
912		// switch that might only be unavailable in some contexts, not all.
913		return fuse.ENOSYS
914
915	case *fuse.StatfsRequest:
916		s := &fuse.StatfsResponse{}
917		if fs, ok := c.fs.(FSStatfser); ok {
918			if err := fs.Statfs(ctx, r, s); err != nil {
919				return err
920			}
921		}
922		done(s)
923		r.Respond(s)
924		return nil
925
926	// Node operations.
927	case *fuse.GetattrRequest:
928		s := &fuse.GetattrResponse{}
929		if n, ok := node.(NodeGetattrer); ok {
930			if err := n.Getattr(ctx, r, s); err != nil {
931				return err
932			}
933		} else {
934			if err := snode.attr(ctx, &s.Attr); err != nil {
935				return err
936			}
937		}
938		done(s)
939		r.Respond(s)
940		return nil
941
942	case *fuse.SetattrRequest:
943		s := &fuse.SetattrResponse{}
944		if n, ok := node.(NodeSetattrer); ok {
945			if err := n.Setattr(ctx, r, s); err != nil {
946				return err
947			}
948		}
949
950		if err := snode.attr(ctx, &s.Attr); err != nil {
951			return err
952		}
953		done(s)
954		r.Respond(s)
955		return nil
956
957	case *fuse.SymlinkRequest:
958		s := &fuse.SymlinkResponse{}
959		initLookupResponse(&s.LookupResponse)
960		n, ok := node.(NodeSymlinker)
961		if !ok {
962			return fuse.EIO // XXX or EPERM like Mkdir?
963		}
964		n2, err := n.Symlink(ctx, r)
965		if err != nil {
966			return err
967		}
968		if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.NewName, n2); err != nil {
969			return err
970		}
971		done(s)
972		r.Respond(s)
973		return nil
974
975	case *fuse.ReadlinkRequest:
976		n, ok := node.(NodeReadlinker)
977		if !ok {
978			return fuse.EIO /// XXX or EPERM?
979		}
980		target, err := n.Readlink(ctx, r)
981		if err != nil {
982			return err
983		}
984		done(target)
985		r.Respond(target)
986		return nil
987
988	case *fuse.LinkRequest:
989		n, ok := node.(NodeLinker)
990		if !ok {
991			return fuse.EIO /// XXX or EPERM?
992		}
993		c.meta.Lock()
994		var oldNode *serveNode
995		if int(r.OldNode) < len(c.node) {
996			oldNode = c.node[r.OldNode]
997		}
998		c.meta.Unlock()
999		if oldNode == nil {
1000			c.debug(logLinkRequestOldNodeNotFound{
1001				Request: r.Hdr(),
1002				In:      r,
1003			})
1004			return fuse.EIO
1005		}
1006		n2, err := n.Link(ctx, r, oldNode.node)
1007		if err != nil {
1008			return err
1009		}
1010		s := &fuse.LookupResponse{}
1011		initLookupResponse(s)
1012		if err := c.saveLookup(ctx, s, snode, r.NewName, n2); err != nil {
1013			return err
1014		}
1015		done(s)
1016		r.Respond(s)
1017		return nil
1018
1019	case *fuse.RemoveRequest:
1020		n, ok := node.(NodeRemover)
1021		if !ok {
1022			return fuse.EIO /// XXX or EPERM?
1023		}
1024		err := n.Remove(ctx, r)
1025		if err != nil {
1026			return err
1027		}
1028		done(nil)
1029		r.Respond()
1030		return nil
1031
1032	case *fuse.AccessRequest:
1033		if n, ok := node.(NodeAccesser); ok {
1034			if err := n.Access(ctx, r); err != nil {
1035				return err
1036			}
1037		}
1038		done(nil)
1039		r.Respond()
1040		return nil
1041
1042	case *fuse.LookupRequest:
1043		var n2 Node
1044		var err error
1045		s := &fuse.LookupResponse{}
1046		initLookupResponse(s)
1047		if n, ok := node.(NodeStringLookuper); ok {
1048			n2, err = n.Lookup(ctx, r.Name)
1049		} else if n, ok := node.(NodeRequestLookuper); ok {
1050			n2, err = n.Lookup(ctx, r, s)
1051		} else {
1052			return fuse.ENOENT
1053		}
1054		if err != nil {
1055			return err
1056		}
1057		if err := c.saveLookup(ctx, s, snode, r.Name, n2); err != nil {
1058			return err
1059		}
1060		done(s)
1061		r.Respond(s)
1062		return nil
1063
1064	case *fuse.MkdirRequest:
1065		s := &fuse.MkdirResponse{}
1066		initLookupResponse(&s.LookupResponse)
1067		n, ok := node.(NodeMkdirer)
1068		if !ok {
1069			return fuse.EPERM
1070		}
1071		n2, err := n.Mkdir(ctx, r)
1072		if err != nil {
1073			return err
1074		}
1075		if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil {
1076			return err
1077		}
1078		done(s)
1079		r.Respond(s)
1080		return nil
1081
1082	case *fuse.OpenRequest:
1083		s := &fuse.OpenResponse{}
1084		var h2 Handle
1085		if n, ok := node.(NodeOpener); ok {
1086			hh, err := n.Open(ctx, r, s)
1087			if err != nil {
1088				return err
1089			}
1090			h2 = hh
1091		} else {
1092			h2 = node
1093		}
1094		s.Handle = c.saveHandle(h2, r.Hdr().Node)
1095		done(s)
1096		r.Respond(s)
1097		return nil
1098
1099	case *fuse.CreateRequest:
1100		n, ok := node.(NodeCreater)
1101		if !ok {
1102			// If we send back ENOSYS, FUSE will try mknod+open.
1103			return fuse.EPERM
1104		}
1105		s := &fuse.CreateResponse{OpenResponse: fuse.OpenResponse{}}
1106		initLookupResponse(&s.LookupResponse)
1107		n2, h2, err := n.Create(ctx, r, s)
1108		if err != nil {
1109			return err
1110		}
1111		if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil {
1112			return err
1113		}
1114		s.Handle = c.saveHandle(h2, r.Hdr().Node)
1115		done(s)
1116		r.Respond(s)
1117		return nil
1118
1119	case *fuse.GetxattrRequest:
1120		n, ok := node.(NodeGetxattrer)
1121		if !ok {
1122			return fuse.ENOTSUP
1123		}
1124		s := &fuse.GetxattrResponse{}
1125		err := n.Getxattr(ctx, r, s)
1126		if err != nil {
1127			return err
1128		}
1129		if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) {
1130			return fuse.ERANGE
1131		}
1132		done(s)
1133		r.Respond(s)
1134		return nil
1135
1136	case *fuse.ListxattrRequest:
1137		n, ok := node.(NodeListxattrer)
1138		if !ok {
1139			return fuse.ENOTSUP
1140		}
1141		s := &fuse.ListxattrResponse{}
1142		err := n.Listxattr(ctx, r, s)
1143		if err != nil {
1144			return err
1145		}
1146		if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) {
1147			return fuse.ERANGE
1148		}
1149		done(s)
1150		r.Respond(s)
1151		return nil
1152
1153	case *fuse.SetxattrRequest:
1154		n, ok := node.(NodeSetxattrer)
1155		if !ok {
1156			return fuse.ENOTSUP
1157		}
1158		err := n.Setxattr(ctx, r)
1159		if err != nil {
1160			return err
1161		}
1162		done(nil)
1163		r.Respond()
1164		return nil
1165
1166	case *fuse.RemovexattrRequest:
1167		n, ok := node.(NodeRemovexattrer)
1168		if !ok {
1169			return fuse.ENOTSUP
1170		}
1171		err := n.Removexattr(ctx, r)
1172		if err != nil {
1173			return err
1174		}
1175		done(nil)
1176		r.Respond()
1177		return nil
1178
1179	case *fuse.ForgetRequest:
1180		forget := c.dropNode(r.Hdr().Node, r.N)
1181		if forget {
1182			n, ok := node.(NodeForgetter)
1183			if ok {
1184				n.Forget()
1185			}
1186		}
1187		done(nil)
1188		r.Respond()
1189		return nil
1190
1191	// Handle operations.
1192	case *fuse.ReadRequest:
1193		shandle := c.getHandle(r.Handle)
1194		if shandle == nil {
1195			return fuse.ESTALE
1196		}
1197		handle := shandle.handle
1198
1199		s := &fuse.ReadResponse{Data: make([]byte, 0, r.Size)}
1200		if r.Dir {
1201			if h, ok := handle.(HandleReadDirAller); ok {
1202				// detect rewinddir(3) or similar seek and refresh
1203				// contents
1204				if r.Offset == 0 {
1205					shandle.readData = nil
1206				}
1207
1208				if shandle.readData == nil {
1209					dirs, err := h.ReadDirAll(ctx)
1210					if err != nil {
1211						return err
1212					}
1213					var data []byte
1214					for _, dir := range dirs {
1215						if dir.Inode == 0 {
1216							dir.Inode = c.dynamicInode(snode.inode, dir.Name)
1217						}
1218						data = fuse.AppendDirent(data, dir)
1219					}
1220					shandle.readData = data
1221				}
1222				fuseutil.HandleRead(r, s, shandle.readData)
1223				done(s)
1224				r.Respond(s)
1225				return nil
1226			}
1227		} else {
1228			if h, ok := handle.(HandleReadAller); ok {
1229				if shandle.readData == nil {
1230					data, err := h.ReadAll(ctx)
1231					if err != nil {
1232						return err
1233					}
1234					if data == nil {
1235						data = []byte{}
1236					}
1237					shandle.readData = data
1238				}
1239				fuseutil.HandleRead(r, s, shandle.readData)
1240				done(s)
1241				r.Respond(s)
1242				return nil
1243			}
1244			h, ok := handle.(HandleReader)
1245			if !ok {
1246				err := handleNotReaderError{handle: handle}
1247				return err
1248			}
1249			if err := h.Read(ctx, r, s); err != nil {
1250				return err
1251			}
1252		}
1253		done(s)
1254		r.Respond(s)
1255		return nil
1256
1257	case *fuse.WriteRequest:
1258		shandle := c.getHandle(r.Handle)
1259		if shandle == nil {
1260			return fuse.ESTALE
1261		}
1262
1263		s := &fuse.WriteResponse{}
1264		if h, ok := shandle.handle.(HandleWriter); ok {
1265			if err := h.Write(ctx, r, s); err != nil {
1266				return err
1267			}
1268			done(s)
1269			r.Respond(s)
1270			return nil
1271		}
1272		return fuse.EIO
1273
1274	case *fuse.FlushRequest:
1275		shandle := c.getHandle(r.Handle)
1276		if shandle == nil {
1277			return fuse.ESTALE
1278		}
1279		handle := shandle.handle
1280
1281		if h, ok := handle.(HandleFlusher); ok {
1282			if err := h.Flush(ctx, r); err != nil {
1283				return err
1284			}
1285		}
1286		done(nil)
1287		r.Respond()
1288		return nil
1289
1290	case *fuse.ReleaseRequest:
1291		shandle := c.getHandle(r.Handle)
1292		if shandle == nil {
1293			return fuse.ESTALE
1294		}
1295		handle := shandle.handle
1296
1297		// No matter what, release the handle.
1298		c.dropHandle(r.Handle)
1299
1300		if h, ok := handle.(HandleReleaser); ok {
1301			if err := h.Release(ctx, r); err != nil {
1302				return err
1303			}
1304		}
1305		done(nil)
1306		r.Respond()
1307		return nil
1308
1309	case *fuse.DestroyRequest:
1310		if fs, ok := c.fs.(FSDestroyer); ok {
1311			fs.Destroy()
1312		}
1313		done(nil)
1314		r.Respond()
1315		return nil
1316
1317	case *fuse.RenameRequest:
1318		c.meta.Lock()
1319		var newDirNode *serveNode
1320		if int(r.NewDir) < len(c.node) {
1321			newDirNode = c.node[r.NewDir]
1322		}
1323		c.meta.Unlock()
1324		if newDirNode == nil {
1325			c.debug(renameNewDirNodeNotFound{
1326				Request: r.Hdr(),
1327				In:      r,
1328			})
1329			return fuse.EIO
1330		}
1331		n, ok := node.(NodeRenamer)
1332		if !ok {
1333			return fuse.EIO // XXX or EPERM like Mkdir?
1334		}
1335		err := n.Rename(ctx, r, newDirNode.node)
1336		if err != nil {
1337			return err
1338		}
1339		done(nil)
1340		r.Respond()
1341		return nil
1342
1343	case *fuse.MknodRequest:
1344		n, ok := node.(NodeMknoder)
1345		if !ok {
1346			return fuse.EIO
1347		}
1348		n2, err := n.Mknod(ctx, r)
1349		if err != nil {
1350			return err
1351		}
1352		s := &fuse.LookupResponse{}
1353		initLookupResponse(s)
1354		if err := c.saveLookup(ctx, s, snode, r.Name, n2); err != nil {
1355			return err
1356		}
1357		done(s)
1358		r.Respond(s)
1359		return nil
1360
1361	case *fuse.FsyncRequest:
1362		n, ok := node.(NodeFsyncer)
1363		if !ok {
1364			return fuse.EIO
1365		}
1366		err := n.Fsync(ctx, r)
1367		if err != nil {
1368			return err
1369		}
1370		done(nil)
1371		r.Respond()
1372		return nil
1373
1374	case *fuse.InterruptRequest:
1375		c.meta.Lock()
1376		ireq := c.req[r.IntrID]
1377		if ireq != nil && ireq.cancel != nil {
1378			ireq.cancel()
1379			ireq.cancel = nil
1380		}
1381		c.meta.Unlock()
1382		done(nil)
1383		r.Respond()
1384		return nil
1385
1386		/*	case *FsyncdirRequest:
1387				return ENOSYS
1388
1389			case *GetlkRequest, *SetlkRequest, *SetlkwRequest:
1390				return ENOSYS
1391
1392			case *BmapRequest:
1393				return ENOSYS
1394
1395			case *SetvolnameRequest, *GetxtimesRequest, *ExchangeRequest:
1396				return ENOSYS
1397		*/
1398	}
1399
1400	panic("not reached")
1401}
1402
1403func (c *Server) saveLookup(ctx context.Context, s *fuse.LookupResponse, snode *serveNode, elem string, n2 Node) error {
1404	if err := nodeAttr(ctx, n2, &s.Attr); err != nil {
1405		return err
1406	}
1407	if s.Attr.Inode == 0 {
1408		s.Attr.Inode = c.dynamicInode(snode.inode, elem)
1409	}
1410
1411	s.Node, s.Generation = c.saveNode(s.Attr.Inode, n2)
1412	return nil
1413}
1414
1415type invalidateNodeDetail struct {
1416	Off  int64
1417	Size int64
1418}
1419
1420func (i invalidateNodeDetail) String() string {
1421	return fmt.Sprintf("Off:%d Size:%d", i.Off, i.Size)
1422}
1423
1424func errstr(err error) string {
1425	if err == nil {
1426		return ""
1427	}
1428	return err.Error()
1429}
1430
1431func (s *Server) invalidateNode(node Node, off int64, size int64) error {
1432	s.meta.Lock()
1433	id, ok := s.nodeRef[node]
1434	if ok {
1435		snode := s.node[id]
1436		snode.wg.Add(1)
1437		defer snode.wg.Done()
1438	}
1439	s.meta.Unlock()
1440	if !ok {
1441		// This is what the kernel would have said, if we had been
1442		// able to send this message; it's not cached.
1443		return fuse.ErrNotCached
1444	}
1445	// Delay logging until after we can record the error too. We
1446	// consider a /dev/fuse write to be instantaneous enough to not
1447	// need separate before and after messages.
1448	err := s.conn.InvalidateNode(id, off, size)
1449	s.debug(notification{
1450		Op:   "InvalidateNode",
1451		Node: id,
1452		Out: invalidateNodeDetail{
1453			Off:  off,
1454			Size: size,
1455		},
1456		Err: errstr(err),
1457	})
1458	return err
1459}
1460
1461// InvalidateNodeAttr invalidates the kernel cache of the attributes
1462// of node.
1463//
1464// Returns fuse.ErrNotCached if the kernel is not currently caching
1465// the node.
1466func (s *Server) InvalidateNodeAttr(node Node) error {
1467	return s.invalidateNode(node, 0, 0)
1468}
1469
1470// InvalidateNodeData invalidates the kernel cache of the attributes
1471// and data of node.
1472//
1473// Returns fuse.ErrNotCached if the kernel is not currently caching
1474// the node.
1475func (s *Server) InvalidateNodeData(node Node) error {
1476	return s.invalidateNode(node, 0, -1)
1477}
1478
1479// InvalidateNodeDataRange invalidates the kernel cache of the
1480// attributes and a range of the data of node.
1481//
1482// Returns fuse.ErrNotCached if the kernel is not currently caching
1483// the node.
1484func (s *Server) InvalidateNodeDataRange(node Node, off int64, size int64) error {
1485	return s.invalidateNode(node, off, size)
1486}
1487
1488type invalidateEntryDetail struct {
1489	Name string
1490}
1491
1492func (i invalidateEntryDetail) String() string {
1493	return fmt.Sprintf("%q", i.Name)
1494}
1495
1496// InvalidateEntry invalidates the kernel cache of the directory entry
1497// identified by parent node and entry basename.
1498//
1499// Kernel may or may not cache directory listings. To invalidate
1500// those, use InvalidateNode to invalidate all of the data for a
1501// directory. (As of 2015-06, Linux FUSE does not cache directory
1502// listings.)
1503//
1504// Returns ErrNotCached if the kernel is not currently caching the
1505// node.
1506func (s *Server) InvalidateEntry(parent Node, name string) error {
1507	s.meta.Lock()
1508	id, ok := s.nodeRef[parent]
1509	if ok {
1510		snode := s.node[id]
1511		snode.wg.Add(1)
1512		defer snode.wg.Done()
1513	}
1514	s.meta.Unlock()
1515	if !ok {
1516		// This is what the kernel would have said, if we had been
1517		// able to send this message; it's not cached.
1518		return fuse.ErrNotCached
1519	}
1520	err := s.conn.InvalidateEntry(id, name)
1521	s.debug(notification{
1522		Op:   "InvalidateEntry",
1523		Node: id,
1524		Out: invalidateEntryDetail{
1525			Name: name,
1526		},
1527		Err: errstr(err),
1528	})
1529	return err
1530}
1531
1532// DataHandle returns a read-only Handle that satisfies reads
1533// using the given data.
1534func DataHandle(data []byte) Handle {
1535	return &dataHandle{data}
1536}
1537
1538type dataHandle struct {
1539	data []byte
1540}
1541
1542func (d *dataHandle) ReadAll(ctx context.Context) ([]byte, error) {
1543	return d.data, nil
1544}
1545
1546// GenerateDynamicInode returns a dynamic inode.
1547//
1548// The parent inode and current entry name are used as the criteria
1549// for choosing a pseudorandom inode. This makes it likely the same
1550// entry will get the same inode on multiple runs.
1551func GenerateDynamicInode(parent uint64, name string) uint64 {
1552	h := fnv.New64a()
1553	var buf [8]byte
1554	binary.LittleEndian.PutUint64(buf[:], parent)
1555	_, _ = h.Write(buf[:])
1556	_, _ = h.Write([]byte(name))
1557	var inode uint64
1558	for {
1559		inode = h.Sum64()
1560		if inode != 0 {
1561			break
1562		}
1563		// there's a tiny probability that result is zero; change the
1564		// input a little and try again
1565		_, _ = h.Write([]byte{'x'})
1566	}
1567	return inode
1568}
1569