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