1 // UserlandRequestHandler.cpp 2 3 #include "UserlandRequestHandler.h" 4 5 #include "AutoDeleter.h" 6 #include "Compatibility.h" 7 #include "Debug.h" 8 #include "FileSystem.h" 9 #include "RequestPort.h" 10 #include "Requests.h" 11 #include "RequestThread.h" 12 #include "SingleReplyRequestHandler.h" 13 #include "Volume.h" 14 15 // constructor 16 UserlandRequestHandler::UserlandRequestHandler(FileSystem* fileSystem) 17 : RequestHandler(), 18 fFileSystem(fileSystem), 19 fExpectReply(false), 20 fExpectedReply(0) 21 { 22 } 23 24 // constructor 25 UserlandRequestHandler::UserlandRequestHandler(FileSystem* fileSystem, 26 uint32 expectedReply) 27 : RequestHandler(), 28 fFileSystem(fileSystem), 29 fExpectReply(true), 30 fExpectedReply(expectedReply) 31 { 32 } 33 34 // destructor 35 UserlandRequestHandler::~UserlandRequestHandler() 36 { 37 } 38 39 // HandleRequest 40 status_t 41 UserlandRequestHandler::HandleRequest(Request* request) 42 { 43 if (fExpectReply && request->GetType() == fExpectedReply) { 44 fDone = true; 45 return B_OK; 46 } 47 switch (request->GetType()) { 48 // FS 49 case MOUNT_VOLUME_REQUEST: 50 return _HandleRequest((MountVolumeRequest*)request); 51 case UNMOUNT_VOLUME_REQUEST: 52 return _HandleRequest((UnmountVolumeRequest*)request); 53 case SYNC_VOLUME_REQUEST: 54 return _HandleRequest((SyncVolumeRequest*)request); 55 case READ_FS_INFO_REQUEST: 56 return _HandleRequest((ReadFSInfoRequest*)request); 57 case WRITE_FS_INFO_REQUEST: 58 return _HandleRequest((WriteFSInfoRequest*)request); 59 60 // vnodes 61 case LOOKUP_REQUEST: 62 return _HandleRequest((LookupRequest*)request); 63 case GET_VNODE_NAME_REQUEST: 64 return _HandleRequest((GetVNodeNameRequest*)request); 65 case READ_VNODE_REQUEST: 66 return _HandleRequest((ReadVNodeRequest*)request); 67 case WRITE_VNODE_REQUEST: 68 return _HandleRequest((WriteVNodeRequest*)request); 69 case FS_REMOVE_VNODE_REQUEST: 70 return _HandleRequest((FSRemoveVNodeRequest*)request); 71 72 // nodes 73 case IOCTL_REQUEST: 74 return _HandleRequest((IOCtlRequest*)request); 75 case SET_FLAGS_REQUEST: 76 return _HandleRequest((SetFlagsRequest*)request); 77 case SELECT_REQUEST: 78 return _HandleRequest((SelectRequest*)request); 79 case DESELECT_REQUEST: 80 return _HandleRequest((DeselectRequest*)request); 81 case FSYNC_REQUEST: 82 return _HandleRequest((FSyncRequest*)request); 83 case READ_SYMLINK_REQUEST: 84 return _HandleRequest((ReadSymlinkRequest*)request); 85 case CREATE_SYMLINK_REQUEST: 86 return _HandleRequest((CreateSymlinkRequest*)request); 87 case LINK_REQUEST: 88 return _HandleRequest((LinkRequest*)request); 89 case UNLINK_REQUEST: 90 return _HandleRequest((UnlinkRequest*)request); 91 case RENAME_REQUEST: 92 return _HandleRequest((RenameRequest*)request); 93 case ACCESS_REQUEST: 94 return _HandleRequest((AccessRequest*)request); 95 case READ_STAT_REQUEST: 96 return _HandleRequest((ReadStatRequest*)request); 97 case WRITE_STAT_REQUEST: 98 return _HandleRequest((WriteStatRequest*)request); 99 100 // files 101 case CREATE_REQUEST: 102 return _HandleRequest((CreateRequest*)request); 103 case OPEN_REQUEST: 104 return _HandleRequest((OpenRequest*)request); 105 case CLOSE_REQUEST: 106 return _HandleRequest((CloseRequest*)request); 107 case FREE_COOKIE_REQUEST: 108 return _HandleRequest((FreeCookieRequest*)request); 109 case READ_REQUEST: 110 return _HandleRequest((ReadRequest*)request); 111 case WRITE_REQUEST: 112 return _HandleRequest((WriteRequest*)request); 113 114 // directories 115 case CREATE_DIR_REQUEST: 116 return _HandleRequest((CreateDirRequest*)request); 117 case REMOVE_DIR_REQUEST: 118 return _HandleRequest((RemoveDirRequest*)request); 119 case OPEN_DIR_REQUEST: 120 return _HandleRequest((OpenDirRequest*)request); 121 case CLOSE_DIR_REQUEST: 122 return _HandleRequest((CloseDirRequest*)request); 123 case FREE_DIR_COOKIE_REQUEST: 124 return _HandleRequest((FreeDirCookieRequest*)request); 125 case READ_DIR_REQUEST: 126 return _HandleRequest((ReadDirRequest*)request); 127 case REWIND_DIR_REQUEST: 128 return _HandleRequest((RewindDirRequest*)request); 129 130 // attribute directories 131 case OPEN_ATTR_DIR_REQUEST: 132 return _HandleRequest((OpenAttrDirRequest*)request); 133 case CLOSE_ATTR_DIR_REQUEST: 134 return _HandleRequest((CloseAttrDirRequest*)request); 135 case FREE_ATTR_DIR_COOKIE_REQUEST: 136 return _HandleRequest((FreeAttrDirCookieRequest*)request); 137 case READ_ATTR_DIR_REQUEST: 138 return _HandleRequest((ReadAttrDirRequest*)request); 139 case REWIND_ATTR_DIR_REQUEST: 140 return _HandleRequest((RewindAttrDirRequest*)request); 141 142 // attributes 143 case CREATE_ATTR_REQUEST: 144 return _HandleRequest((CreateAttrRequest*)request); 145 case OPEN_ATTR_REQUEST: 146 return _HandleRequest((OpenAttrRequest*)request); 147 case CLOSE_ATTR_REQUEST: 148 return _HandleRequest((CloseAttrRequest*)request); 149 case FREE_ATTR_COOKIE_REQUEST: 150 return _HandleRequest((FreeAttrCookieRequest*)request); 151 case READ_ATTR_REQUEST: 152 return _HandleRequest((ReadAttrRequest*)request); 153 case WRITE_ATTR_REQUEST: 154 return _HandleRequest((WriteAttrRequest*)request); 155 case READ_ATTR_STAT_REQUEST: 156 return _HandleRequest((ReadAttrStatRequest*)request); 157 case WRITE_ATTR_STAT_REQUEST: 158 return _HandleRequest((WriteAttrStatRequest*)request); 159 case RENAME_ATTR_REQUEST: 160 return _HandleRequest((RenameAttrRequest*)request); 161 case REMOVE_ATTR_REQUEST: 162 return _HandleRequest((RemoveAttrRequest*)request); 163 164 // indices 165 case OPEN_INDEX_DIR_REQUEST: 166 return _HandleRequest((OpenIndexDirRequest*)request); 167 case CLOSE_INDEX_DIR_REQUEST: 168 return _HandleRequest((CloseIndexDirRequest*)request); 169 case FREE_INDEX_DIR_COOKIE_REQUEST: 170 return _HandleRequest((FreeIndexDirCookieRequest*)request); 171 case READ_INDEX_DIR_REQUEST: 172 return _HandleRequest((ReadIndexDirRequest*)request); 173 case REWIND_INDEX_DIR_REQUEST: 174 return _HandleRequest((RewindIndexDirRequest*)request); 175 case CREATE_INDEX_REQUEST: 176 return _HandleRequest((CreateIndexRequest*)request); 177 case REMOVE_INDEX_REQUEST: 178 return _HandleRequest((RemoveIndexRequest*)request); 179 case READ_INDEX_STAT_REQUEST: 180 return _HandleRequest((ReadIndexStatRequest*)request); 181 182 // queries 183 case OPEN_QUERY_REQUEST: 184 return _HandleRequest((OpenQueryRequest*)request); 185 case CLOSE_QUERY_REQUEST: 186 return _HandleRequest((CloseQueryRequest*)request); 187 case FREE_QUERY_COOKIE_REQUEST: 188 return _HandleRequest((FreeQueryCookieRequest*)request); 189 case READ_QUERY_REQUEST: 190 return _HandleRequest((ReadQueryRequest*)request); 191 case REWIND_QUERY_REQUEST: 192 return _HandleRequest((RewindQueryRequest*)request); 193 } 194 PRINT(("UserlandRequestHandler::HandleRequest(): unexpected request: %lu\n", 195 request->GetType())); 196 return B_BAD_DATA; 197 } 198 199 200 // #pragma mark - FS 201 202 203 // _HandleRequest 204 status_t 205 UserlandRequestHandler::_HandleRequest(MountVolumeRequest* request) 206 { 207 // check and execute the request 208 status_t result = B_OK; 209 210 // if the device path is relative, make it absolute by appending the 211 // provided CWD 212 const char* device = (const char*)request->device.GetData(); 213 char stackDevice[B_PATH_NAME_LENGTH]; 214 if (result == B_OK) { 215 if (device && device[0] != '/') { 216 if (const char* cwd = (const char*)request->cwd.GetData()) { 217 int32 deviceLen = strlen(device); 218 int32 cwdLen = strlen(cwd); 219 if (cwdLen + 1 + deviceLen < (int32)sizeof(stackDevice)) { 220 strcpy(stackDevice, cwd); 221 strcat(stackDevice, "/"); 222 strcat(stackDevice, device); 223 device = stackDevice; 224 } else 225 result = B_NAME_TOO_LONG; 226 } else 227 result = B_BAD_VALUE; 228 } 229 } 230 231 // create the volume 232 Volume* volume = NULL; 233 if (result == B_OK) 234 result = fFileSystem->CreateVolume(&volume, request->nsid); 235 236 // mount it 237 ino_t rootID; 238 if (result == B_OK) { 239 RequestThreadContext context(volume); 240 result = volume->Mount(device, request->flags, 241 (const char*)request->parameters.GetData(), &rootID); 242 if (result != B_OK) 243 fFileSystem->DeleteVolume(volume); 244 } 245 if (result != B_OK) 246 volume = NULL; 247 248 // prepare the reply 249 RequestAllocator allocator(fPort->GetPort()); 250 MountVolumeReply* reply; 251 status_t error = AllocateRequest(allocator, &reply); 252 if (error != B_OK) 253 RETURN_ERROR(error); 254 reply->error = result; 255 reply->volume = volume; 256 reply->rootID = rootID; 257 volume->GetCapabilities(reply->capabilities); 258 259 // send the reply 260 return _SendReply(allocator, false); 261 } 262 263 // _HandleRequest 264 status_t 265 UserlandRequestHandler::_HandleRequest(UnmountVolumeRequest* request) 266 { 267 // check and execute the request 268 status_t result = B_OK; 269 Volume* volume = (Volume*)request->volume; 270 if (!volume) 271 result = B_BAD_VALUE; 272 if (result == B_OK) { 273 RequestThreadContext context(volume); 274 result = volume->Unmount(); 275 } 276 277 // prepare the reply 278 RequestAllocator allocator(fPort->GetPort()); 279 UnmountVolumeReply* reply; 280 status_t error = AllocateRequest(allocator, &reply); 281 if (error != B_OK) 282 RETURN_ERROR(error); 283 reply->error = result; 284 285 // send the reply 286 return _SendReply(allocator, false); 287 } 288 289 // _HandleRequest 290 status_t 291 UserlandRequestHandler::_HandleRequest(SyncVolumeRequest* request) 292 { 293 // check and execute the request 294 status_t result = B_OK; 295 Volume* volume = (Volume*)request->volume; 296 if (!volume) 297 result = B_BAD_VALUE; 298 if (result == B_OK) { 299 RequestThreadContext context(volume); 300 result = volume->Sync(); 301 } 302 // prepare the reply 303 RequestAllocator allocator(fPort->GetPort()); 304 SyncVolumeReply* reply; 305 status_t error = AllocateRequest(allocator, &reply); 306 if (error != B_OK) 307 RETURN_ERROR(error); 308 reply->error = result; 309 310 // send the reply 311 return _SendReply(allocator, false); 312 } 313 314 // _HandleRequest 315 status_t 316 UserlandRequestHandler::_HandleRequest(ReadFSInfoRequest* request) 317 { 318 // check and execute the request 319 status_t result = B_OK; 320 Volume* volume = (Volume*)request->volume; 321 if (!volume) 322 result = B_BAD_VALUE; 323 fs_info info; 324 if (result == B_OK) { 325 RequestThreadContext context(volume); 326 result = volume->ReadFSInfo(&info); 327 } 328 // prepare the reply 329 RequestAllocator allocator(fPort->GetPort()); 330 ReadFSInfoReply* reply; 331 status_t error = AllocateRequest(allocator, &reply); 332 if (error != B_OK) 333 RETURN_ERROR(error); 334 reply->error = result; 335 reply->info = info; 336 337 // send the reply 338 return _SendReply(allocator, false); 339 } 340 341 // _HandleRequest 342 status_t 343 UserlandRequestHandler::_HandleRequest(WriteFSInfoRequest* request) 344 { 345 // check and execute the request 346 status_t result = B_OK; 347 Volume* volume = (Volume*)request->volume; 348 if (!volume) 349 result = B_BAD_VALUE; 350 if (result == B_OK) { 351 RequestThreadContext context(volume); 352 result = volume->WriteFSInfo(&request->info, request->mask); 353 } 354 355 // prepare the reply 356 RequestAllocator allocator(fPort->GetPort()); 357 WriteFSInfoReply* reply; 358 status_t error = AllocateRequest(allocator, &reply); 359 if (error != B_OK) 360 RETURN_ERROR(error); 361 reply->error = result; 362 363 // send the reply 364 return _SendReply(allocator, false); 365 } 366 367 368 // #pragma mark - vnodes 369 370 371 // _HandleRequest 372 status_t 373 UserlandRequestHandler::_HandleRequest(LookupRequest* request) 374 { 375 // check and execute the request 376 status_t result = B_OK; 377 Volume* volume = (Volume*)request->volume; 378 if (!volume) 379 result = B_BAD_VALUE; 380 381 ino_t vnid = 0; 382 if (result == B_OK) { 383 RequestThreadContext context(volume); 384 result = volume->Lookup(request->node, 385 (const char*)request->entryName.GetData(), &vnid); 386 } 387 388 // prepare the reply 389 RequestAllocator allocator(fPort->GetPort()); 390 LookupReply* reply; 391 status_t error = AllocateRequest(allocator, &reply); 392 if (error != B_OK) 393 RETURN_ERROR(error); 394 395 reply->vnid = vnid; 396 reply->error = result; 397 398 // send the reply 399 return _SendReply(allocator, false); 400 } 401 402 // _HandleRequest 403 status_t 404 UserlandRequestHandler::_HandleRequest(GetVNodeNameRequest* request) 405 { 406 // check and execute the request 407 status_t result = B_OK; 408 Volume* volume = (Volume*)request->volume; 409 if (!volume) 410 result = B_BAD_VALUE; 411 412 void* node = request->node; 413 size_t bufferSize = request->size; 414 415 // allocate the reply 416 RequestAllocator allocator(fPort->GetPort()); 417 GetVNodeNameReply* reply; 418 status_t error = AllocateRequest(allocator, &reply); 419 if (error != B_OK) 420 RETURN_ERROR(error); 421 char* buffer; 422 if (result == B_OK) { 423 result = allocator.AllocateAddress(reply->buffer, bufferSize, 1, 424 (void**)&buffer, true); 425 } 426 427 // execute the request 428 if (result == B_OK) { 429 RequestThreadContext context(volume); 430 result = volume->GetVNodeName(node, buffer, bufferSize); 431 } 432 433 // reconstruct the reply, in case it has been overwritten 434 reply = new(reply) GetVNodeNameReply; 435 436 // send the reply 437 reply->error = result; 438 return _SendReply(allocator, (result == B_OK)); 439 } 440 441 // _HandleRequest 442 status_t 443 UserlandRequestHandler::_HandleRequest(ReadVNodeRequest* request) 444 { 445 // check and execute the request 446 status_t result = B_OK; 447 Volume* volume = (Volume*)request->volume; 448 if (!volume) 449 result = B_BAD_VALUE; 450 451 void* node; 452 int type; 453 uint32 flags; 454 if (result == B_OK) { 455 RequestThreadContext context(volume); 456 result = volume->ReadVNode(request->vnid, request->reenter, &node, 457 &type, &flags); 458 } 459 460 // prepare the reply 461 RequestAllocator allocator(fPort->GetPort()); 462 ReadVNodeReply* reply; 463 status_t error = AllocateRequest(allocator, &reply); 464 if (error != B_OK) 465 RETURN_ERROR(error); 466 467 reply->error = result; 468 reply->node = node; 469 reply->type = type; 470 reply->flags = flags; 471 472 // send the reply 473 return _SendReply(allocator, false); 474 } 475 476 // _HandleRequest 477 status_t 478 UserlandRequestHandler::_HandleRequest(WriteVNodeRequest* request) 479 { 480 // check and execute the request 481 status_t result = B_OK; 482 Volume* volume = (Volume*)request->volume; 483 if (!volume) 484 result = B_BAD_VALUE; 485 486 if (result == B_OK) { 487 RequestThreadContext context(volume); 488 result = volume->WriteVNode(request->node, request->reenter); 489 } 490 491 // prepare the reply 492 RequestAllocator allocator(fPort->GetPort()); 493 WriteVNodeReply* reply; 494 status_t error = AllocateRequest(allocator, &reply); 495 if (error != B_OK) 496 RETURN_ERROR(error); 497 498 reply->error = result; 499 500 // send the reply 501 return _SendReply(allocator, false); 502 } 503 504 // _HandleRequest 505 status_t 506 UserlandRequestHandler::_HandleRequest(FSRemoveVNodeRequest* request) 507 { 508 // check and execute the request 509 status_t result = B_OK; 510 Volume* volume = (Volume*)request->volume; 511 if (!volume) 512 result = B_BAD_VALUE; 513 514 if (result == B_OK) { 515 RequestThreadContext context(volume); 516 result = volume->RemoveVNode(request->node, request->reenter); 517 } 518 519 // prepare the reply 520 RequestAllocator allocator(fPort->GetPort()); 521 FSRemoveVNodeReply* reply; 522 status_t error = AllocateRequest(allocator, &reply); 523 if (error != B_OK) 524 RETURN_ERROR(error); 525 526 reply->error = result; 527 528 // send the reply 529 return _SendReply(allocator, false); 530 } 531 532 533 // #pragma mark - nodes 534 535 536 // _HandleRequest 537 status_t 538 UserlandRequestHandler::_HandleRequest(IOCtlRequest* request) 539 { 540 // get the request parameters 541 status_t result = B_OK; 542 Volume* volume = (Volume*)request->volume; 543 if (!volume) 544 result = B_BAD_VALUE; 545 546 void* buffer = request->bufferParameter; 547 size_t len = request->lenParameter; 548 bool isBuffer = request->isBuffer; 549 int32 bufferSize = 0; 550 int32 writeSize = request->writeSize; 551 if (isBuffer) { 552 buffer = request->buffer.GetData(); 553 bufferSize = request->buffer.GetSize(); 554 } 555 556 // allocate the reply 557 RequestAllocator allocator(fPort->GetPort()); 558 IOCtlReply* reply; 559 status_t error = AllocateRequest(allocator, &reply); 560 if (error != B_OK) 561 RETURN_ERROR(error); 562 563 // allocate the writable buffer for the call 564 void* writeBuffer = NULL; 565 if (result == B_OK && isBuffer && writeSize > 0) { 566 if (writeSize < bufferSize) 567 writeSize = bufferSize; 568 result = allocator.AllocateAddress(reply->buffer, writeSize, 8, 569 (void**)&writeBuffer, true); 570 if (result == B_OK && bufferSize > 0) 571 memcpy(writeBuffer, buffer, bufferSize); 572 buffer = writeBuffer; 573 } 574 575 // execute the request 576 status_t ioctlError = B_OK; 577 if (result == B_OK) { 578 RequestThreadContext context(volume); 579 ioctlError = volume->IOCtl(request->node, request->fileCookie, 580 request->command, buffer, len); 581 } 582 583 // reconstruct the reply, in case it has been overwritten 584 reply = new(reply) IOCtlReply; 585 586 // send the reply 587 reply->error = result; 588 reply->ioctlError = ioctlError; 589 return _SendReply(allocator, (result == B_OK && writeBuffer)); 590 } 591 592 // _HandleRequest 593 status_t 594 UserlandRequestHandler::_HandleRequest(SetFlagsRequest* request) 595 { 596 // check and execute the request 597 status_t result = B_OK; 598 Volume* volume = (Volume*)request->volume; 599 if (!volume) 600 result = B_BAD_VALUE; 601 602 if (result == B_OK) { 603 RequestThreadContext context(volume); 604 result = volume->SetFlags(request->node, request->fileCookie, 605 request->flags); 606 } 607 608 // prepare the reply 609 RequestAllocator allocator(fPort->GetPort()); 610 SetFlagsReply* reply; 611 status_t error = AllocateRequest(allocator, &reply); 612 if (error != B_OK) 613 RETURN_ERROR(error); 614 615 reply->error = result; 616 617 // send the reply 618 return _SendReply(allocator, false); 619 } 620 621 // _HandleRequest 622 status_t 623 UserlandRequestHandler::_HandleRequest(SelectRequest* request) 624 { 625 // check and execute the request 626 status_t result = B_OK; 627 Volume* volume = (Volume*)request->volume; 628 if (!volume) 629 result = B_BAD_VALUE; 630 631 if (result == B_OK) { 632 RequestThreadContext context(volume); 633 result = volume->Select(request->node, request->fileCookie, 634 request->event, request->sync); 635 } 636 637 // prepare the reply 638 RequestAllocator allocator(fPort->GetPort()); 639 SelectReply* reply; 640 status_t error = AllocateRequest(allocator, &reply); 641 if (error != B_OK) 642 RETURN_ERROR(error); 643 644 reply->error = result; 645 646 // send the reply 647 return _SendReply(allocator, false); 648 } 649 650 // _HandleRequest 651 status_t 652 UserlandRequestHandler::_HandleRequest(DeselectRequest* request) 653 { 654 // check and execute the request 655 status_t result = B_OK; 656 Volume* volume = (Volume*)request->volume; 657 if (!volume) 658 result = B_BAD_VALUE; 659 660 if (result == B_OK) { 661 RequestThreadContext context(volume); 662 result = volume->Deselect(request->node, request->fileCookie, 663 request->event, request->sync); 664 } 665 666 // prepare the reply 667 RequestAllocator allocator(fPort->GetPort()); 668 DeselectReply* reply; 669 status_t error = AllocateRequest(allocator, &reply); 670 if (error != B_OK) 671 RETURN_ERROR(error); 672 673 reply->error = result; 674 675 // send the reply 676 return _SendReply(allocator, false); 677 } 678 679 // _HandleRequest 680 status_t 681 UserlandRequestHandler::_HandleRequest(FSyncRequest* request) 682 { 683 // check and execute the request 684 status_t result = B_OK; 685 Volume* volume = (Volume*)request->volume; 686 if (!volume) 687 result = B_BAD_VALUE; 688 689 if (result == B_OK) { 690 RequestThreadContext context(volume); 691 result = volume->FSync(request->node); 692 } 693 694 // prepare the reply 695 RequestAllocator allocator(fPort->GetPort()); 696 FSyncReply* reply; 697 status_t error = AllocateRequest(allocator, &reply); 698 if (error != B_OK) 699 RETURN_ERROR(error); 700 701 reply->error = result; 702 703 // send the reply 704 return _SendReply(allocator, false); 705 } 706 707 // _HandleRequest 708 status_t 709 UserlandRequestHandler::_HandleRequest(ReadSymlinkRequest* request) 710 { 711 // check and execute the request 712 status_t result = B_OK; 713 Volume* volume = (Volume*)request->volume; 714 if (!volume) 715 result = B_BAD_VALUE; 716 717 void* node = request->node; 718 size_t bufferSize = request->size; 719 720 // allocate the reply 721 RequestAllocator allocator(fPort->GetPort()); 722 ReadSymlinkReply* reply; 723 status_t error = AllocateRequest(allocator, &reply); 724 if (error != B_OK) 725 RETURN_ERROR(error); 726 char* buffer; 727 if (result == B_OK) { 728 result = allocator.AllocateAddress(reply->buffer, bufferSize, 1, 729 (void**)&buffer, true); 730 } 731 732 // execute the request 733 size_t bytesRead; 734 if (result == B_OK) { 735 RequestThreadContext context(volume); 736 result = volume->ReadSymlink(node, buffer, bufferSize, &bytesRead); 737 } 738 739 // reconstruct the reply, in case it has been overwritten 740 reply = new(reply) ReadSymlinkReply; 741 742 // send the reply 743 reply->error = result; 744 reply->bytesRead = bytesRead; 745 return _SendReply(allocator, (result == B_OK)); 746 } 747 748 // _HandleRequest 749 status_t 750 UserlandRequestHandler::_HandleRequest(CreateSymlinkRequest* request) 751 { 752 // check and execute the request 753 status_t result = B_OK; 754 Volume* volume = (Volume*)request->volume; 755 if (!volume) 756 result = B_BAD_VALUE; 757 758 if (result == B_OK) { 759 RequestThreadContext context(volume); 760 result = volume->CreateSymlink(request->node, 761 (const char*)request->name.GetData(), 762 (const char*)request->target.GetData(), request->mode); 763 } 764 765 // prepare the reply 766 RequestAllocator allocator(fPort->GetPort()); 767 CreateSymlinkReply* reply; 768 status_t error = AllocateRequest(allocator, &reply); 769 if (error != B_OK) 770 RETURN_ERROR(error); 771 772 reply->error = result; 773 774 // send the reply 775 return _SendReply(allocator, false); 776 } 777 778 // _HandleRequest 779 status_t 780 UserlandRequestHandler::_HandleRequest(LinkRequest* request) 781 { 782 // check and execute the request 783 status_t result = B_OK; 784 Volume* volume = (Volume*)request->volume; 785 if (!volume) 786 result = B_BAD_VALUE; 787 788 if (result == B_OK) { 789 RequestThreadContext context(volume); 790 result = volume->Link(request->node, 791 (const char*)request->name.GetData(), request->target); 792 } 793 794 // prepare the reply 795 RequestAllocator allocator(fPort->GetPort()); 796 LinkReply* reply; 797 status_t error = AllocateRequest(allocator, &reply); 798 if (error != B_OK) 799 RETURN_ERROR(error); 800 801 reply->error = result; 802 803 // send the reply 804 return _SendReply(allocator, false); 805 } 806 807 // _HandleRequest 808 status_t 809 UserlandRequestHandler::_HandleRequest(UnlinkRequest* request) 810 { 811 // check and execute the request 812 status_t result = B_OK; 813 Volume* volume = (Volume*)request->volume; 814 if (!volume) 815 result = B_BAD_VALUE; 816 817 if (result == B_OK) { 818 RequestThreadContext context(volume); 819 result = volume->Unlink(request->node, 820 (const char*)request->name.GetData()); 821 } 822 823 // prepare the reply 824 RequestAllocator allocator(fPort->GetPort()); 825 UnlinkReply* reply; 826 status_t error = AllocateRequest(allocator, &reply); 827 if (error != B_OK) 828 RETURN_ERROR(error); 829 830 reply->error = result; 831 832 // send the reply 833 return _SendReply(allocator, false); 834 } 835 836 // _HandleRequest 837 status_t 838 UserlandRequestHandler::_HandleRequest(RenameRequest* request) 839 { 840 // check and execute the request 841 status_t result = B_OK; 842 Volume* volume = (Volume*)request->volume; 843 if (!volume) 844 result = B_BAD_VALUE; 845 846 if (result == B_OK) { 847 RequestThreadContext context(volume); 848 result = volume->Rename(request->oldDir, 849 (const char*)request->oldName.GetData(), request->newDir, 850 (const char*)request->newName.GetData()); 851 } 852 853 // prepare the reply 854 RequestAllocator allocator(fPort->GetPort()); 855 RenameReply* reply; 856 status_t error = AllocateRequest(allocator, &reply); 857 if (error != B_OK) 858 RETURN_ERROR(error); 859 860 reply->error = result; 861 862 // send the reply 863 return _SendReply(allocator, false); 864 } 865 866 // _HandleRequest 867 status_t 868 UserlandRequestHandler::_HandleRequest(AccessRequest* request) 869 { 870 // check and execute the request 871 status_t result = B_OK; 872 Volume* volume = (Volume*)request->volume; 873 if (!volume) 874 result = B_BAD_VALUE; 875 876 if (result == B_OK) { 877 RequestThreadContext context(volume); 878 result = volume->Access(request->node, request->mode); 879 } 880 881 // prepare the reply 882 RequestAllocator allocator(fPort->GetPort()); 883 AccessReply* reply; 884 status_t error = AllocateRequest(allocator, &reply); 885 if (error != B_OK) 886 RETURN_ERROR(error); 887 888 reply->error = result; 889 890 // send the reply 891 return _SendReply(allocator, false); 892 } 893 894 // _HandleRequest 895 status_t 896 UserlandRequestHandler::_HandleRequest(ReadStatRequest* request) 897 { 898 // check and execute the request 899 status_t result = B_OK; 900 Volume* volume = (Volume*)request->volume; 901 if (!volume) 902 result = B_BAD_VALUE; 903 904 struct stat st; 905 if (result == B_OK) { 906 RequestThreadContext context(volume); 907 result = volume->ReadStat(request->node, &st); 908 } 909 910 // prepare the reply 911 RequestAllocator allocator(fPort->GetPort()); 912 ReadStatReply* reply; 913 status_t error = AllocateRequest(allocator, &reply); 914 if (error != B_OK) 915 RETURN_ERROR(error); 916 917 reply->error = result; 918 reply->st = st; 919 920 // send the reply 921 return _SendReply(allocator, false); 922 } 923 924 // _HandleRequest 925 status_t 926 UserlandRequestHandler::_HandleRequest(WriteStatRequest* request) 927 { 928 // check and execute the request 929 status_t result = B_OK; 930 Volume* volume = (Volume*)request->volume; 931 if (!volume) 932 result = B_BAD_VALUE; 933 934 if (result == B_OK) { 935 RequestThreadContext context(volume); 936 result = volume->WriteStat(request->node, &request->st, request->mask); 937 } 938 939 // prepare the reply 940 RequestAllocator allocator(fPort->GetPort()); 941 WriteStatReply* reply; 942 status_t error = AllocateRequest(allocator, &reply); 943 if (error != B_OK) 944 RETURN_ERROR(error); 945 946 reply->error = result; 947 948 // send the reply 949 return _SendReply(allocator, false); 950 } 951 952 953 // #pragma mark - files 954 955 956 // _HandleRequest 957 status_t 958 UserlandRequestHandler::_HandleRequest(CreateRequest* request) 959 { 960 // check and execute the request 961 status_t result = B_OK; 962 Volume* volume = (Volume*)request->volume; 963 if (!volume) 964 result = B_BAD_VALUE; 965 966 ino_t vnid; 967 void* fileCookie; 968 if (result == B_OK) { 969 RequestThreadContext context(volume); 970 result = volume->Create(request->node, 971 (const char*)request->name.GetData(), request->openMode, 972 request->mode, &fileCookie, &vnid); 973 } 974 975 // prepare the reply 976 RequestAllocator allocator(fPort->GetPort()); 977 CreateReply* reply; 978 status_t error = AllocateRequest(allocator, &reply); 979 if (error != B_OK) 980 RETURN_ERROR(error); 981 982 reply->error = result; 983 reply->vnid = vnid; 984 reply->fileCookie = fileCookie; 985 986 // send the reply 987 return _SendReply(allocator, false); 988 } 989 990 // _HandleRequest 991 status_t 992 UserlandRequestHandler::_HandleRequest(OpenRequest* request) 993 { 994 // check and execute the request 995 status_t result = B_OK; 996 Volume* volume = (Volume*)request->volume; 997 if (!volume) 998 result = B_BAD_VALUE; 999 1000 void* fileCookie; 1001 if (result == B_OK) { 1002 RequestThreadContext context(volume); 1003 result = volume->Open(request->node, request->openMode, &fileCookie); 1004 } 1005 1006 // prepare the reply 1007 RequestAllocator allocator(fPort->GetPort()); 1008 OpenReply* reply; 1009 status_t error = AllocateRequest(allocator, &reply); 1010 if (error != B_OK) 1011 RETURN_ERROR(error); 1012 1013 reply->error = result; 1014 reply->fileCookie = fileCookie; 1015 1016 // send the reply 1017 return _SendReply(allocator, false); 1018 } 1019 1020 // _HandleRequest 1021 status_t 1022 UserlandRequestHandler::_HandleRequest(CloseRequest* request) 1023 { 1024 // check and execute the request 1025 status_t result = B_OK; 1026 Volume* volume = (Volume*)request->volume; 1027 if (!volume) 1028 result = B_BAD_VALUE; 1029 1030 if (result == B_OK) { 1031 RequestThreadContext context(volume); 1032 result = volume->Close(request->node, request->fileCookie); 1033 } 1034 1035 // prepare the reply 1036 RequestAllocator allocator(fPort->GetPort()); 1037 CloseReply* reply; 1038 status_t error = AllocateRequest(allocator, &reply); 1039 if (error != B_OK) 1040 RETURN_ERROR(error); 1041 1042 reply->error = result; 1043 1044 // send the reply 1045 return _SendReply(allocator, false); 1046 } 1047 1048 // _HandleRequest 1049 status_t 1050 UserlandRequestHandler::_HandleRequest(FreeCookieRequest* request) 1051 { 1052 // check and execute the request 1053 status_t result = B_OK; 1054 Volume* volume = (Volume*)request->volume; 1055 if (!volume) 1056 result = B_BAD_VALUE; 1057 1058 if (result == B_OK) { 1059 RequestThreadContext context(volume); 1060 result = volume->FreeCookie(request->node, request->fileCookie); 1061 } 1062 1063 // prepare the reply 1064 RequestAllocator allocator(fPort->GetPort()); 1065 FreeCookieReply* reply; 1066 status_t error = AllocateRequest(allocator, &reply); 1067 if (error != B_OK) 1068 RETURN_ERROR(error); 1069 1070 reply->error = result; 1071 1072 // send the reply 1073 return _SendReply(allocator, false); 1074 } 1075 1076 // _HandleRequest 1077 status_t 1078 UserlandRequestHandler::_HandleRequest(ReadRequest* request) 1079 { 1080 // check and execute the request 1081 status_t result = B_OK; 1082 Volume* volume = (Volume*)request->volume; 1083 if (!volume) 1084 result = B_BAD_VALUE; 1085 1086 void* node = request->node; 1087 void* fileCookie = request->fileCookie; 1088 off_t pos = request->pos; 1089 size_t size = request->size; 1090 1091 // allocate the reply 1092 RequestAllocator allocator(fPort->GetPort()); 1093 ReadReply* reply; 1094 status_t error = AllocateRequest(allocator, &reply); 1095 if (error != B_OK) 1096 RETURN_ERROR(error); 1097 1098 void* buffer; 1099 if (result == B_OK) { 1100 result = allocator.AllocateAddress(reply->buffer, size, 1, &buffer, 1101 true); 1102 } 1103 1104 // execute the request 1105 size_t bytesRead; 1106 if (result == B_OK) { 1107 RequestThreadContext context(volume); 1108 result = volume->Read(node, fileCookie, pos, buffer, size, &bytesRead); 1109 } 1110 1111 // reconstruct the reply, in case it has been overwritten 1112 reply = new(reply) ReadReply; 1113 1114 // send the reply 1115 reply->error = result; 1116 reply->bytesRead = bytesRead; 1117 return _SendReply(allocator, (result == B_OK)); 1118 } 1119 1120 // _HandleRequest 1121 status_t 1122 UserlandRequestHandler::_HandleRequest(WriteRequest* request) 1123 { 1124 // check and execute the request 1125 status_t result = B_OK; 1126 Volume* volume = (Volume*)request->volume; 1127 if (!volume) 1128 result = B_BAD_VALUE; 1129 1130 size_t bytesWritten; 1131 if (result == B_OK) { 1132 RequestThreadContext context(volume); 1133 result = volume->Write(request->node, request->fileCookie, 1134 request->pos, request->buffer.GetData(), request->buffer.GetSize(), 1135 &bytesWritten); 1136 } 1137 1138 // prepare the reply 1139 RequestAllocator allocator(fPort->GetPort()); 1140 WriteReply* reply; 1141 status_t error = AllocateRequest(allocator, &reply); 1142 if (error != B_OK) 1143 RETURN_ERROR(error); 1144 1145 reply->error = result; 1146 reply->bytesWritten = bytesWritten; 1147 1148 // send the reply 1149 return _SendReply(allocator, false); 1150 } 1151 1152 1153 // #pragma mark - directories 1154 1155 1156 // _HandleRequest 1157 status_t 1158 UserlandRequestHandler::_HandleRequest(CreateDirRequest* request) 1159 { 1160 // check and execute the request 1161 status_t result = B_OK; 1162 Volume* volume = (Volume*)request->volume; 1163 if (!volume) 1164 result = B_BAD_VALUE; 1165 1166 ino_t newDir = 0; 1167 if (result == B_OK) { 1168 RequestThreadContext context(volume); 1169 result = volume->CreateDir(request->node, 1170 (const char*)request->name.GetData(), request->mode, &newDir); 1171 } 1172 1173 // prepare the reply 1174 RequestAllocator allocator(fPort->GetPort()); 1175 CreateDirReply* reply; 1176 status_t error = AllocateRequest(allocator, &reply); 1177 if (error != B_OK) 1178 RETURN_ERROR(error); 1179 1180 reply->error = result; 1181 reply->newDir = newDir; 1182 1183 // send the reply 1184 return _SendReply(allocator, false); 1185 } 1186 1187 // _HandleRequest 1188 status_t 1189 UserlandRequestHandler::_HandleRequest(RemoveDirRequest* request) 1190 { 1191 // check and execute the request 1192 status_t result = B_OK; 1193 Volume* volume = (Volume*)request->volume; 1194 if (!volume) 1195 result = B_BAD_VALUE; 1196 1197 if (result == B_OK) { 1198 RequestThreadContext context(volume); 1199 result = volume->RemoveDir(request->node, 1200 (const char*)request->name.GetData()); 1201 } 1202 1203 // prepare the reply 1204 RequestAllocator allocator(fPort->GetPort()); 1205 RemoveDirReply* reply; 1206 status_t error = AllocateRequest(allocator, &reply); 1207 if (error != B_OK) 1208 RETURN_ERROR(error); 1209 1210 reply->error = result; 1211 1212 // send the reply 1213 return _SendReply(allocator, false); 1214 } 1215 1216 // _HandleRequest 1217 status_t 1218 UserlandRequestHandler::_HandleRequest(OpenDirRequest* request) 1219 { 1220 // check and execute the request 1221 status_t result = B_OK; 1222 Volume* volume = (Volume*)request->volume; 1223 if (!volume) 1224 result = B_BAD_VALUE; 1225 1226 void* dirCookie = NULL; 1227 if (result == B_OK) { 1228 RequestThreadContext context(volume); 1229 result = volume->OpenDir(request->node, &dirCookie); 1230 } 1231 1232 // prepare the reply 1233 RequestAllocator allocator(fPort->GetPort()); 1234 OpenDirReply* reply; 1235 status_t error = AllocateRequest(allocator, &reply); 1236 if (error != B_OK) 1237 RETURN_ERROR(error); 1238 1239 reply->error = result; 1240 reply->dirCookie = dirCookie; 1241 1242 // send the reply 1243 return _SendReply(allocator, false); 1244 } 1245 1246 // _HandleRequest 1247 status_t 1248 UserlandRequestHandler::_HandleRequest(CloseDirRequest* request) 1249 { 1250 // check and execute the request 1251 status_t result = B_OK; 1252 Volume* volume = (Volume*)request->volume; 1253 if (!volume) 1254 result = B_BAD_VALUE; 1255 1256 if (result == B_OK) { 1257 RequestThreadContext context(volume); 1258 result = volume->CloseDir(request->node, request->dirCookie); 1259 } 1260 1261 // prepare the reply 1262 RequestAllocator allocator(fPort->GetPort()); 1263 CloseDirReply* reply; 1264 status_t error = AllocateRequest(allocator, &reply); 1265 if (error != B_OK) 1266 RETURN_ERROR(error); 1267 1268 reply->error = result; 1269 1270 // send the reply 1271 return _SendReply(allocator, false); 1272 } 1273 1274 // _HandleRequest 1275 status_t 1276 UserlandRequestHandler::_HandleRequest(FreeDirCookieRequest* request) 1277 { 1278 // check and execute the request 1279 status_t result = B_OK; 1280 Volume* volume = (Volume*)request->volume; 1281 if (!volume) 1282 result = B_BAD_VALUE; 1283 1284 if (result == B_OK) { 1285 RequestThreadContext context(volume); 1286 result = volume->FreeDirCookie(request->node, request->dirCookie); 1287 } 1288 1289 // prepare the reply 1290 RequestAllocator allocator(fPort->GetPort()); 1291 FreeDirCookieReply* reply; 1292 status_t error = AllocateRequest(allocator, &reply); 1293 if (error != B_OK) 1294 RETURN_ERROR(error); 1295 1296 reply->error = result; 1297 1298 // send the reply 1299 return _SendReply(allocator, false); 1300 } 1301 1302 // _HandleRequest 1303 status_t 1304 UserlandRequestHandler::_HandleRequest(ReadDirRequest* request) 1305 { 1306 // check the request 1307 status_t result = B_OK; 1308 Volume* volume = (Volume*)request->volume; 1309 if (!volume) 1310 result = B_BAD_VALUE; 1311 1312 void* node = request->node; 1313 void* dirCookie = request->dirCookie; 1314 size_t bufferSize = request->bufferSize; 1315 uint32 count = request->count; 1316 1317 // allocate the reply 1318 RequestAllocator allocator(fPort->GetPort()); 1319 ReadDirReply* reply; 1320 status_t error = AllocateRequest(allocator, &reply); 1321 if (error != B_OK) 1322 RETURN_ERROR(error); 1323 1324 void* buffer; 1325 if (result == B_OK) { 1326 result = allocator.AllocateAddress(reply->buffer, bufferSize, 1, 1327 &buffer, true); 1328 } 1329 1330 // execute the request 1331 uint32 countRead; 1332 if (result == B_OK) { 1333 RequestThreadContext context(volume); 1334 result = volume->ReadDir(node, dirCookie, buffer, bufferSize, count, 1335 &countRead); 1336 } 1337 1338 D( 1339 if (result == B_OK && countRead > 0) { 1340 dirent* entry = (dirent*)buffer; 1341 PRINT((" entry: d_dev: %ld, d_pdev: %ld, d_ino: %Ld, d_pino: %Ld, " 1342 "d_reclen: %hu, d_name: %.32s\n", 1343 entry->d_dev, entry->d_pdev, entry->d_ino, entry->d_pino, 1344 entry->d_reclen, entry->d_name)); 1345 } 1346 ) 1347 1348 // reconstruct the reply, in case it has been overwritten 1349 reply = new(reply) ReadDirReply; 1350 1351 // send the reply 1352 reply->error = result; 1353 reply->count = countRead; 1354 return _SendReply(allocator, (result == B_OK)); 1355 } 1356 1357 // _HandleRequest 1358 status_t 1359 UserlandRequestHandler::_HandleRequest(RewindDirRequest* request) 1360 { 1361 // check and execute the request 1362 status_t result = B_OK; 1363 Volume* volume = (Volume*)request->volume; 1364 if (!volume) 1365 result = B_BAD_VALUE; 1366 1367 if (result == B_OK) { 1368 RequestThreadContext context(volume); 1369 result = volume->RewindDir(request->node, request->dirCookie); 1370 } 1371 1372 // prepare the reply 1373 RequestAllocator allocator(fPort->GetPort()); 1374 RewindDirReply* reply; 1375 status_t error = AllocateRequest(allocator, &reply); 1376 if (error != B_OK) 1377 RETURN_ERROR(error); 1378 1379 reply->error = result; 1380 1381 // send the reply 1382 return _SendReply(allocator, false); 1383 } 1384 1385 1386 // #pragma mark - attribute directories 1387 1388 1389 // _HandleRequest 1390 status_t 1391 UserlandRequestHandler::_HandleRequest(OpenAttrDirRequest* request) 1392 { 1393 // check and execute the request 1394 status_t result = B_OK; 1395 Volume* volume = (Volume*)request->volume; 1396 if (!volume) 1397 result = B_BAD_VALUE; 1398 1399 void* attrDirCookie; 1400 if (result == B_OK) { 1401 RequestThreadContext context(volume); 1402 result = volume->OpenAttrDir(request->node, &attrDirCookie); 1403 } 1404 1405 // prepare the reply 1406 RequestAllocator allocator(fPort->GetPort()); 1407 OpenAttrDirReply* reply; 1408 status_t error = AllocateRequest(allocator, &reply); 1409 if (error != B_OK) 1410 RETURN_ERROR(error); 1411 1412 reply->error = result; 1413 reply->attrDirCookie = attrDirCookie; 1414 1415 // send the reply 1416 return _SendReply(allocator, false); 1417 } 1418 1419 // _HandleRequest 1420 status_t 1421 UserlandRequestHandler::_HandleRequest(CloseAttrDirRequest* request) 1422 { 1423 // check and execute the request 1424 status_t result = B_OK; 1425 Volume* volume = (Volume*)request->volume; 1426 if (!volume) 1427 result = B_BAD_VALUE; 1428 1429 if (result == B_OK) { 1430 RequestThreadContext context(volume); 1431 result = volume->CloseAttrDir(request->node, request->attrDirCookie); 1432 } 1433 1434 // prepare the reply 1435 RequestAllocator allocator(fPort->GetPort()); 1436 CloseAttrDirReply* reply; 1437 status_t error = AllocateRequest(allocator, &reply); 1438 if (error != B_OK) 1439 RETURN_ERROR(error); 1440 1441 reply->error = result; 1442 1443 // send the reply 1444 return _SendReply(allocator, false); 1445 } 1446 1447 // _HandleRequest 1448 status_t 1449 UserlandRequestHandler::_HandleRequest(FreeAttrDirCookieRequest* request) 1450 { 1451 // check and execute the request 1452 status_t result = B_OK; 1453 Volume* volume = (Volume*)request->volume; 1454 if (!volume) 1455 result = B_BAD_VALUE; 1456 1457 if (result == B_OK) { 1458 RequestThreadContext context(volume); 1459 result = volume->FreeAttrDirCookie(request->node, 1460 request->attrDirCookie); 1461 } 1462 1463 // prepare the reply 1464 RequestAllocator allocator(fPort->GetPort()); 1465 FreeAttrDirCookieReply* reply; 1466 status_t error = AllocateRequest(allocator, &reply); 1467 if (error != B_OK) 1468 RETURN_ERROR(error); 1469 1470 reply->error = result; 1471 1472 // send the reply 1473 return _SendReply(allocator, false); 1474 } 1475 1476 // _HandleRequest 1477 status_t 1478 UserlandRequestHandler::_HandleRequest(ReadAttrDirRequest* request) 1479 { 1480 // check and execute the request 1481 status_t result = B_OK; 1482 Volume* volume = (Volume*)request->volume; 1483 if (!volume) 1484 result = B_BAD_VALUE; 1485 1486 void* node = request->node; 1487 void* attrDirCookie = request->attrDirCookie; 1488 size_t bufferSize = request->bufferSize; 1489 uint32 count = request->count; 1490 1491 // allocate the reply 1492 RequestAllocator allocator(fPort->GetPort()); 1493 ReadAttrDirReply* reply; 1494 status_t error = AllocateRequest(allocator, &reply); 1495 if (error != B_OK) 1496 RETURN_ERROR(error); 1497 1498 void* buffer; 1499 if (result == B_OK) { 1500 result = allocator.AllocateAddress(reply->buffer, bufferSize, 1, 1501 &buffer, true); 1502 } 1503 1504 // execute the request 1505 uint32 countRead; 1506 if (result == B_OK) { 1507 RequestThreadContext context(volume); 1508 result = volume->ReadAttrDir(node, attrDirCookie, buffer, bufferSize, 1509 count, &countRead); 1510 } 1511 1512 // reconstruct the reply, in case it has been overwritten 1513 reply = new(reply) ReadAttrDirReply; 1514 1515 // send the reply 1516 reply->error = result; 1517 reply->count = countRead; 1518 return _SendReply(allocator, (result == B_OK)); 1519 } 1520 1521 // _HandleRequest 1522 status_t 1523 UserlandRequestHandler::_HandleRequest(RewindAttrDirRequest* request) 1524 { 1525 // check and execute the request 1526 status_t result = B_OK; 1527 Volume* volume = (Volume*)request->volume; 1528 if (!volume) 1529 result = B_BAD_VALUE; 1530 1531 if (result == B_OK) { 1532 RequestThreadContext context(volume); 1533 result = volume->RewindAttrDir(request->node, request->attrDirCookie); 1534 } 1535 1536 // prepare the reply 1537 RequestAllocator allocator(fPort->GetPort()); 1538 RewindAttrDirReply* reply; 1539 status_t error = AllocateRequest(allocator, &reply); 1540 if (error != B_OK) 1541 RETURN_ERROR(error); 1542 1543 reply->error = result; 1544 1545 // send the reply 1546 return _SendReply(allocator, false); 1547 } 1548 1549 1550 // #pragma mark - attributes 1551 1552 1553 // _HandleRequest 1554 status_t 1555 UserlandRequestHandler::_HandleRequest(CreateAttrRequest* request) 1556 { 1557 // check and execute the request 1558 status_t result = B_OK; 1559 Volume* volume = (Volume*)request->volume; 1560 if (!volume) 1561 result = B_BAD_VALUE; 1562 1563 void* attrCookie; 1564 if (result == B_OK) { 1565 RequestThreadContext context(volume); 1566 result = volume->CreateAttr(request->node, 1567 (const char*)request->name.GetData(), request->type, 1568 request->openMode, &attrCookie); 1569 } 1570 1571 // prepare the reply 1572 RequestAllocator allocator(fPort->GetPort()); 1573 CreateAttrReply* reply; 1574 status_t error = AllocateRequest(allocator, &reply); 1575 if (error != B_OK) 1576 RETURN_ERROR(error); 1577 1578 reply->error = result; 1579 reply->attrCookie = attrCookie; 1580 1581 // send the reply 1582 return _SendReply(allocator, false); 1583 } 1584 1585 // _HandleRequest 1586 status_t 1587 UserlandRequestHandler::_HandleRequest(OpenAttrRequest* request) 1588 { 1589 // check and execute the request 1590 status_t result = B_OK; 1591 Volume* volume = (Volume*)request->volume; 1592 if (!volume) 1593 result = B_BAD_VALUE; 1594 1595 void* attrCookie; 1596 if (result == B_OK) { 1597 RequestThreadContext context(volume); 1598 result = volume->OpenAttr(request->node, 1599 (const char*)request->name.GetData(), request->openMode, 1600 &attrCookie); 1601 } 1602 1603 // prepare the reply 1604 RequestAllocator allocator(fPort->GetPort()); 1605 OpenAttrReply* reply; 1606 status_t error = AllocateRequest(allocator, &reply); 1607 if (error != B_OK) 1608 RETURN_ERROR(error); 1609 1610 reply->error = result; 1611 reply->attrCookie = attrCookie; 1612 1613 // send the reply 1614 return _SendReply(allocator, false); 1615 } 1616 1617 // _HandleRequest 1618 status_t 1619 UserlandRequestHandler::_HandleRequest(CloseAttrRequest* request) 1620 { 1621 // check and execute the request 1622 status_t result = B_OK; 1623 Volume* volume = (Volume*)request->volume; 1624 if (!volume) 1625 result = B_BAD_VALUE; 1626 1627 if (result == B_OK) { 1628 RequestThreadContext context(volume); 1629 result = volume->CloseAttr(request->node, request->attrCookie); 1630 } 1631 1632 // prepare the reply 1633 RequestAllocator allocator(fPort->GetPort()); 1634 CloseAttrReply* reply; 1635 status_t error = AllocateRequest(allocator, &reply); 1636 if (error != B_OK) 1637 RETURN_ERROR(error); 1638 1639 reply->error = result; 1640 1641 // send the reply 1642 return _SendReply(allocator, false); 1643 } 1644 1645 // _HandleRequest 1646 status_t 1647 UserlandRequestHandler::_HandleRequest(FreeAttrCookieRequest* request) 1648 { 1649 // check and execute the request 1650 status_t result = B_OK; 1651 Volume* volume = (Volume*)request->volume; 1652 if (!volume) 1653 result = B_BAD_VALUE; 1654 1655 if (result == B_OK) { 1656 RequestThreadContext context(volume); 1657 result = volume->FreeAttrCookie(request->node, request->attrCookie); 1658 } 1659 1660 // prepare the reply 1661 RequestAllocator allocator(fPort->GetPort()); 1662 FreeAttrCookieReply* reply; 1663 status_t error = AllocateRequest(allocator, &reply); 1664 if (error != B_OK) 1665 RETURN_ERROR(error); 1666 1667 reply->error = result; 1668 1669 // send the reply 1670 return _SendReply(allocator, false); 1671 } 1672 1673 // _HandleRequest 1674 status_t 1675 UserlandRequestHandler::_HandleRequest(ReadAttrRequest* request) 1676 { 1677 // check and execute the request 1678 status_t result = B_OK; 1679 Volume* volume = (Volume*)request->volume; 1680 if (!volume) 1681 result = B_BAD_VALUE; 1682 1683 void* node = request->node; 1684 void* attrCookie = request->attrCookie; 1685 off_t pos = request->pos; 1686 size_t size = request->size; 1687 1688 // allocate the reply 1689 RequestAllocator allocator(fPort->GetPort()); 1690 ReadAttrReply* reply; 1691 status_t error = AllocateRequest(allocator, &reply); 1692 if (error != B_OK) 1693 RETURN_ERROR(error); 1694 1695 void* buffer; 1696 if (result == B_OK) { 1697 result = allocator.AllocateAddress(reply->buffer, size, 1, &buffer, 1698 true); 1699 } 1700 1701 // execute the request 1702 size_t bytesRead; 1703 if (result == B_OK) { 1704 RequestThreadContext context(volume); 1705 result = volume->ReadAttr(node, attrCookie, pos, buffer, size, 1706 &bytesRead); 1707 } 1708 1709 // reconstruct the reply, in case it has been overwritten 1710 reply = new(reply) ReadAttrReply; 1711 1712 // send the reply 1713 reply->error = result; 1714 reply->bytesRead = bytesRead; 1715 return _SendReply(allocator, (result == B_OK)); 1716 } 1717 1718 // _HandleRequest 1719 status_t 1720 UserlandRequestHandler::_HandleRequest(WriteAttrRequest* request) 1721 { 1722 // check and execute the request 1723 status_t result = B_OK; 1724 Volume* volume = (Volume*)request->volume; 1725 if (!volume) 1726 result = B_BAD_VALUE; 1727 1728 size_t bytesWritten; 1729 if (result == B_OK) { 1730 RequestThreadContext context(volume); 1731 result = volume->WriteAttr(request->node, request->attrCookie, 1732 request->pos, request->buffer.GetData(), request->buffer.GetSize(), 1733 &bytesWritten); 1734 } 1735 1736 // prepare the reply 1737 RequestAllocator allocator(fPort->GetPort()); 1738 WriteAttrReply* reply; 1739 status_t error = AllocateRequest(allocator, &reply); 1740 if (error != B_OK) 1741 RETURN_ERROR(error); 1742 1743 reply->error = result; 1744 reply->bytesWritten = bytesWritten; 1745 1746 // send the reply 1747 return _SendReply(allocator, false); 1748 } 1749 1750 // _HandleRequest 1751 status_t 1752 UserlandRequestHandler::_HandleRequest(ReadAttrStatRequest* request) 1753 { 1754 // check and execute the request 1755 status_t result = B_OK; 1756 Volume* volume = (Volume*)request->volume; 1757 if (!volume) 1758 result = B_BAD_VALUE; 1759 1760 struct stat st; 1761 if (result == B_OK) { 1762 RequestThreadContext context(volume); 1763 result = volume->ReadAttrStat(request->node, request->attrCookie, 1764 &st); 1765 } 1766 1767 // prepare the reply 1768 RequestAllocator allocator(fPort->GetPort()); 1769 ReadAttrStatReply* reply; 1770 status_t error = AllocateRequest(allocator, &reply); 1771 if (error != B_OK) 1772 RETURN_ERROR(error); 1773 1774 reply->error = result; 1775 reply->st = st; 1776 1777 // send the reply 1778 return _SendReply(allocator, false); 1779 } 1780 1781 // _HandleRequest 1782 status_t 1783 UserlandRequestHandler::_HandleRequest(WriteAttrStatRequest* request) 1784 { 1785 // check and execute the request 1786 status_t result = B_OK; 1787 Volume* volume = (Volume*)request->volume; 1788 if (!volume) 1789 result = B_BAD_VALUE; 1790 1791 if (result == B_OK) { 1792 RequestThreadContext context(volume); 1793 result = volume->WriteAttrStat(request->node, request->attrCookie, 1794 &request->st, request->mask); 1795 } 1796 1797 // prepare the reply 1798 RequestAllocator allocator(fPort->GetPort()); 1799 WriteAttrStatReply* reply; 1800 status_t error = AllocateRequest(allocator, &reply); 1801 if (error != B_OK) 1802 RETURN_ERROR(error); 1803 1804 reply->error = result; 1805 1806 // send the reply 1807 return _SendReply(allocator, false); 1808 } 1809 1810 // _HandleRequest 1811 status_t 1812 UserlandRequestHandler::_HandleRequest(RenameAttrRequest* request) 1813 { 1814 // check and execute the request 1815 status_t result = B_OK; 1816 Volume* volume = (Volume*)request->volume; 1817 if (!volume) 1818 result = B_BAD_VALUE; 1819 1820 if (result == B_OK) { 1821 RequestThreadContext context(volume); 1822 result = volume->RenameAttr( 1823 request->oldNode, (const char*)request->oldName.GetData(), 1824 request->newNode, (const char*)request->newName.GetData()); 1825 } 1826 1827 // prepare the reply 1828 RequestAllocator allocator(fPort->GetPort()); 1829 RenameAttrReply* reply; 1830 status_t error = AllocateRequest(allocator, &reply); 1831 if (error != B_OK) 1832 RETURN_ERROR(error); 1833 1834 reply->error = result; 1835 1836 // send the reply 1837 return _SendReply(allocator, false); 1838 } 1839 1840 // _HandleRequest 1841 status_t 1842 UserlandRequestHandler::_HandleRequest(RemoveAttrRequest* request) 1843 { 1844 // check and execute the request 1845 status_t result = B_OK; 1846 Volume* volume = (Volume*)request->volume; 1847 if (!volume) 1848 result = B_BAD_VALUE; 1849 1850 if (result == B_OK) { 1851 RequestThreadContext context(volume); 1852 result = volume->RemoveAttr(request->node, 1853 (const char*)request->name.GetData()); 1854 } 1855 1856 // prepare the reply 1857 RequestAllocator allocator(fPort->GetPort()); 1858 RemoveAttrReply* reply; 1859 status_t error = AllocateRequest(allocator, &reply); 1860 if (error != B_OK) 1861 RETURN_ERROR(error); 1862 1863 reply->error = result; 1864 1865 // send the reply 1866 return _SendReply(allocator, false); 1867 } 1868 1869 1870 // #pragma mark - indices 1871 1872 1873 // _HandleRequest 1874 status_t 1875 UserlandRequestHandler::_HandleRequest(OpenIndexDirRequest* request) 1876 { 1877 // check and execute the request 1878 status_t result = B_OK; 1879 Volume* volume = (Volume*)request->volume; 1880 if (!volume) 1881 result = B_BAD_VALUE; 1882 1883 void* indexDirCookie; 1884 if (result == B_OK) { 1885 RequestThreadContext context(volume); 1886 result = volume->OpenIndexDir(&indexDirCookie); 1887 } 1888 1889 // prepare the reply 1890 RequestAllocator allocator(fPort->GetPort()); 1891 OpenIndexDirReply* reply; 1892 status_t error = AllocateRequest(allocator, &reply); 1893 if (error != B_OK) 1894 RETURN_ERROR(error); 1895 1896 reply->error = result; 1897 reply->indexDirCookie = indexDirCookie; 1898 1899 // send the reply 1900 return _SendReply(allocator, false); 1901 } 1902 1903 // _HandleRequest 1904 status_t 1905 UserlandRequestHandler::_HandleRequest(CloseIndexDirRequest* request) 1906 { 1907 // check and execute the request 1908 status_t result = B_OK; 1909 Volume* volume = (Volume*)request->volume; 1910 if (!volume) 1911 result = B_BAD_VALUE; 1912 1913 if (result == B_OK) { 1914 RequestThreadContext context(volume); 1915 result = volume->CloseIndexDir(request->indexDirCookie); 1916 } 1917 1918 // prepare the reply 1919 RequestAllocator allocator(fPort->GetPort()); 1920 CloseIndexDirReply* reply; 1921 status_t error = AllocateRequest(allocator, &reply); 1922 if (error != B_OK) 1923 RETURN_ERROR(error); 1924 1925 reply->error = result; 1926 1927 // send the reply 1928 return _SendReply(allocator, false); 1929 } 1930 1931 // _HandleRequest 1932 status_t 1933 UserlandRequestHandler::_HandleRequest(FreeIndexDirCookieRequest* request) 1934 { 1935 // check and execute the request 1936 status_t result = B_OK; 1937 Volume* volume = (Volume*)request->volume; 1938 if (!volume) 1939 result = B_BAD_VALUE; 1940 1941 if (result == B_OK) { 1942 RequestThreadContext context(volume); 1943 result = volume->FreeIndexDirCookie(request->indexDirCookie); 1944 } 1945 1946 // prepare the reply 1947 RequestAllocator allocator(fPort->GetPort()); 1948 FreeIndexDirCookieReply* reply; 1949 status_t error = AllocateRequest(allocator, &reply); 1950 if (error != B_OK) 1951 RETURN_ERROR(error); 1952 1953 reply->error = result; 1954 1955 // send the reply 1956 return _SendReply(allocator, false); 1957 } 1958 1959 // _HandleRequest 1960 status_t 1961 UserlandRequestHandler::_HandleRequest(ReadIndexDirRequest* request) 1962 { 1963 // check and execute the request 1964 status_t result = B_OK; 1965 Volume* volume = (Volume*)request->volume; 1966 if (!volume) 1967 result = B_BAD_VALUE; 1968 1969 void* indexDirCookie = request->indexDirCookie; 1970 size_t bufferSize = request->bufferSize; 1971 uint32 count = request->count; 1972 1973 // allocate the reply 1974 RequestAllocator allocator(fPort->GetPort()); 1975 ReadIndexDirReply* reply; 1976 status_t error = AllocateRequest(allocator, &reply); 1977 if (error != B_OK) 1978 RETURN_ERROR(error); 1979 1980 void* buffer; 1981 if (result == B_OK) { 1982 result = allocator.AllocateAddress(reply->buffer, bufferSize, 1, 1983 &buffer, true); 1984 } 1985 1986 // execute the request 1987 uint32 countRead; 1988 if (result == B_OK) { 1989 RequestThreadContext context(volume); 1990 result = volume->ReadIndexDir(indexDirCookie, buffer, bufferSize, 1991 count, &countRead); 1992 } 1993 1994 // reconstruct the reply, in case it has been overwritten 1995 reply = new(reply) ReadIndexDirReply; 1996 1997 // send the reply 1998 reply->error = result; 1999 reply->count = countRead; 2000 return _SendReply(allocator, (result == B_OK)); 2001 } 2002 2003 // _HandleRequest 2004 status_t 2005 UserlandRequestHandler::_HandleRequest(RewindIndexDirRequest* request) 2006 { 2007 // check and execute the request 2008 status_t result = B_OK; 2009 Volume* volume = (Volume*)request->volume; 2010 if (!volume) 2011 result = B_BAD_VALUE; 2012 2013 if (result == B_OK) { 2014 RequestThreadContext context(volume); 2015 result = volume->RewindIndexDir(request->indexDirCookie); 2016 } 2017 2018 // prepare the reply 2019 RequestAllocator allocator(fPort->GetPort()); 2020 RewindIndexDirReply* reply; 2021 status_t error = AllocateRequest(allocator, &reply); 2022 if (error != B_OK) 2023 RETURN_ERROR(error); 2024 2025 reply->error = result; 2026 2027 // send the reply 2028 return _SendReply(allocator, false); 2029 } 2030 2031 // _HandleRequest 2032 status_t 2033 UserlandRequestHandler::_HandleRequest(CreateIndexRequest* request) 2034 { 2035 // check and execute the request 2036 status_t result = B_OK; 2037 Volume* volume = (Volume*)request->volume; 2038 if (!volume) 2039 result = B_BAD_VALUE; 2040 2041 if (result == B_OK) { 2042 RequestThreadContext context(volume); 2043 result = volume->CreateIndex((const char*)request->name.GetData(), 2044 request->type, request->flags); 2045 } 2046 2047 // prepare the reply 2048 RequestAllocator allocator(fPort->GetPort()); 2049 CreateIndexReply* reply; 2050 status_t error = AllocateRequest(allocator, &reply); 2051 if (error != B_OK) 2052 RETURN_ERROR(error); 2053 2054 reply->error = result; 2055 2056 // send the reply 2057 return _SendReply(allocator, false); 2058 } 2059 2060 // _HandleRequest 2061 status_t 2062 UserlandRequestHandler::_HandleRequest(RemoveIndexRequest* request) 2063 { 2064 // check and execute the request 2065 status_t result = B_OK; 2066 Volume* volume = (Volume*)request->volume; 2067 if (!volume) 2068 result = B_BAD_VALUE; 2069 2070 if (result == B_OK) { 2071 RequestThreadContext context(volume); 2072 result = volume->RemoveIndex((const char*)request->name.GetData()); 2073 } 2074 2075 // prepare the reply 2076 RequestAllocator allocator(fPort->GetPort()); 2077 RemoveIndexReply* reply; 2078 status_t error = AllocateRequest(allocator, &reply); 2079 if (error != B_OK) 2080 RETURN_ERROR(error); 2081 2082 reply->error = result; 2083 2084 // send the reply 2085 return _SendReply(allocator, false); 2086 } 2087 2088 // _HandleRequest 2089 status_t 2090 UserlandRequestHandler::_HandleRequest(ReadIndexStatRequest* request) 2091 { 2092 // check and execute the request 2093 status_t result = B_OK; 2094 Volume* volume = (Volume*)request->volume; 2095 if (!volume) 2096 result = B_BAD_VALUE; 2097 2098 struct stat st; 2099 if (result == B_OK) { 2100 RequestThreadContext context(volume); 2101 result = volume->ReadIndexStat((const char*)request->name.GetData(), 2102 &st); 2103 } 2104 2105 // prepare the reply 2106 RequestAllocator allocator(fPort->GetPort()); 2107 ReadIndexStatReply* reply; 2108 status_t error = AllocateRequest(allocator, &reply); 2109 if (error != B_OK) 2110 RETURN_ERROR(error); 2111 2112 reply->error = result; 2113 reply->st = st; 2114 2115 // send the reply 2116 return _SendReply(allocator, false); 2117 } 2118 2119 2120 // #pragma mark - queries 2121 2122 2123 // _HandleRequest 2124 status_t 2125 UserlandRequestHandler::_HandleRequest(OpenQueryRequest* request) 2126 { 2127 // check and execute the request 2128 status_t result = B_OK; 2129 Volume* volume = (Volume*)request->volume; 2130 if (!volume) 2131 result = B_BAD_VALUE; 2132 2133 void* queryCookie; 2134 if (result == B_OK) { 2135 RequestThreadContext context(volume); 2136 result = volume->OpenQuery((const char*)request->queryString.GetData(), 2137 request->flags, request->port, request->token, &queryCookie); 2138 } 2139 2140 // prepare the reply 2141 RequestAllocator allocator(fPort->GetPort()); 2142 OpenQueryReply* reply; 2143 status_t error = AllocateRequest(allocator, &reply); 2144 if (error != B_OK) 2145 RETURN_ERROR(error); 2146 2147 reply->error = result; 2148 reply->queryCookie = queryCookie; 2149 2150 // send the reply 2151 return _SendReply(allocator, false); 2152 } 2153 2154 // _HandleRequest 2155 status_t 2156 UserlandRequestHandler::_HandleRequest(CloseQueryRequest* request) 2157 { 2158 // check and execute the request 2159 status_t result = B_OK; 2160 Volume* volume = (Volume*)request->volume; 2161 if (!volume) 2162 result = B_BAD_VALUE; 2163 2164 if (result == B_OK) { 2165 RequestThreadContext context(volume); 2166 result = volume->CloseQuery(request->queryCookie); 2167 } 2168 2169 // prepare the reply 2170 RequestAllocator allocator(fPort->GetPort()); 2171 CloseQueryReply* reply; 2172 status_t error = AllocateRequest(allocator, &reply); 2173 if (error != B_OK) 2174 RETURN_ERROR(error); 2175 2176 reply->error = result; 2177 2178 // send the reply 2179 return _SendReply(allocator, false); 2180 } 2181 2182 // _HandleRequest 2183 status_t 2184 UserlandRequestHandler::_HandleRequest(FreeQueryCookieRequest* request) 2185 { 2186 // check and execute the request 2187 status_t result = B_OK; 2188 Volume* volume = (Volume*)request->volume; 2189 if (!volume) 2190 result = B_BAD_VALUE; 2191 2192 if (result == B_OK) { 2193 RequestThreadContext context(volume); 2194 result = volume->FreeQueryCookie(request->queryCookie); 2195 } 2196 2197 // prepare the reply 2198 RequestAllocator allocator(fPort->GetPort()); 2199 FreeQueryCookieReply* reply; 2200 status_t error = AllocateRequest(allocator, &reply); 2201 if (error != B_OK) 2202 RETURN_ERROR(error); 2203 2204 reply->error = result; 2205 2206 // send the reply 2207 return _SendReply(allocator, false); 2208 } 2209 2210 // _HandleRequest 2211 status_t 2212 UserlandRequestHandler::_HandleRequest(ReadQueryRequest* request) 2213 { 2214 // check and execute the request 2215 status_t result = B_OK; 2216 Volume* volume = (Volume*)request->volume; 2217 if (!volume) 2218 result = B_BAD_VALUE; 2219 2220 void* queryCookie = request->queryCookie; 2221 size_t bufferSize = request->bufferSize; 2222 uint32 count = request->count; 2223 2224 // allocate the reply 2225 RequestAllocator allocator(fPort->GetPort()); 2226 ReadQueryReply* reply; 2227 status_t error = AllocateRequest(allocator, &reply); 2228 if (error != B_OK) 2229 RETURN_ERROR(error); 2230 2231 void* buffer; 2232 if (result == B_OK) { 2233 result = allocator.AllocateAddress(reply->buffer, bufferSize, 1, 2234 &buffer, true); 2235 } 2236 2237 // execute the request 2238 uint32 countRead; 2239 if (result == B_OK) { 2240 RequestThreadContext context(volume); 2241 result = volume->ReadQuery(queryCookie, buffer, bufferSize, 2242 count, &countRead); 2243 } 2244 2245 // reconstruct the reply, in case it has been overwritten 2246 reply = new(reply) ReadQueryReply; 2247 2248 // send the reply 2249 reply->error = result; 2250 reply->count = countRead; 2251 return _SendReply(allocator, (result == B_OK)); 2252 } 2253 2254 // _HandleRequest 2255 status_t 2256 UserlandRequestHandler::_HandleRequest(RewindQueryRequest* request) 2257 { 2258 // check and execute the request 2259 status_t result = B_OK; 2260 Volume* volume = (Volume*)request->volume; 2261 if (!volume) 2262 result = B_BAD_VALUE; 2263 2264 if (result == B_OK) { 2265 RequestThreadContext context(volume); 2266 result = volume->RewindQuery(request->queryCookie); 2267 } 2268 2269 // prepare the reply 2270 RequestAllocator allocator(fPort->GetPort()); 2271 RewindQueryReply* reply; 2272 status_t error = AllocateRequest(allocator, &reply); 2273 if (error != B_OK) 2274 RETURN_ERROR(error); 2275 2276 reply->error = result; 2277 2278 // send the reply 2279 return _SendReply(allocator, false); 2280 } 2281 2282 2283 // #pragma mark - other 2284 2285 2286 // _SendReply 2287 status_t 2288 UserlandRequestHandler::_SendReply(RequestAllocator& allocator, 2289 bool expectsReceipt) 2290 { 2291 if (expectsReceipt) { 2292 SingleReplyRequestHandler handler(RECEIPT_ACK_REPLY); 2293 return fPort->SendRequest(&allocator, &handler); 2294 } else 2295 return fPort->SendRequest(&allocator); 2296 } 2297 2298