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