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