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