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