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