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: %" 221 B_PRIu32 "\n", 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, request->isVIP); 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 (size_t)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: %" B_PRIdDEV ", d_pdev: %" B_PRIdDEV ", " 1501 "d_ino: %" B_PRIdINO ", d_pino: %" B_PRIdINO ", " 1502 "d_reclen: %hu, d_name: %.32s\n", 1503 entry->d_dev, entry->d_pdev, 1504 entry->d_ino, entry->d_pino, 1505 entry->d_reclen, entry->d_name)); 1506 } 1507 ) 1508 1509 // reconstruct the reply, in case it has been overwritten 1510 reply = new(reply) ReadDirReply; 1511 1512 // send the reply 1513 reply->error = result; 1514 reply->count = countRead; 1515 return _SendReply(allocator, (result == B_OK)); 1516 } 1517 1518 // _HandleRequest 1519 status_t 1520 UserlandRequestHandler::_HandleRequest(RewindDirRequest* request) 1521 { 1522 // check and execute the request 1523 status_t result = B_OK; 1524 Volume* volume = (Volume*)request->volume; 1525 if (!volume) 1526 result = B_BAD_VALUE; 1527 1528 if (result == B_OK) { 1529 RequestThreadContext context(volume, request); 1530 result = volume->RewindDir(request->node, request->dirCookie); 1531 } 1532 1533 // prepare the reply 1534 RequestAllocator allocator(fPort->GetPort()); 1535 RewindDirReply* reply; 1536 status_t error = AllocateRequest(allocator, &reply); 1537 if (error != B_OK) 1538 RETURN_ERROR(error); 1539 1540 reply->error = result; 1541 1542 // send the reply 1543 return _SendReply(allocator, false); 1544 } 1545 1546 1547 // #pragma mark - attribute directories 1548 1549 1550 // _HandleRequest 1551 status_t 1552 UserlandRequestHandler::_HandleRequest(OpenAttrDirRequest* request) 1553 { 1554 // check and execute the request 1555 status_t result = B_OK; 1556 Volume* volume = (Volume*)request->volume; 1557 if (!volume) 1558 result = B_BAD_VALUE; 1559 1560 void* attrDirCookie; 1561 if (result == B_OK) { 1562 RequestThreadContext context(volume, request); 1563 result = volume->OpenAttrDir(request->node, &attrDirCookie); 1564 } 1565 1566 // prepare the reply 1567 RequestAllocator allocator(fPort->GetPort()); 1568 OpenAttrDirReply* reply; 1569 status_t error = AllocateRequest(allocator, &reply); 1570 if (error != B_OK) 1571 RETURN_ERROR(error); 1572 1573 reply->error = result; 1574 reply->attrDirCookie = attrDirCookie; 1575 1576 // send the reply 1577 return _SendReply(allocator, false); 1578 } 1579 1580 // _HandleRequest 1581 status_t 1582 UserlandRequestHandler::_HandleRequest(CloseAttrDirRequest* request) 1583 { 1584 // check and execute the request 1585 status_t result = B_OK; 1586 Volume* volume = (Volume*)request->volume; 1587 if (!volume) 1588 result = B_BAD_VALUE; 1589 1590 if (result == B_OK) { 1591 RequestThreadContext context(volume, request); 1592 result = volume->CloseAttrDir(request->node, request->attrDirCookie); 1593 } 1594 1595 // prepare the reply 1596 RequestAllocator allocator(fPort->GetPort()); 1597 CloseAttrDirReply* reply; 1598 status_t error = AllocateRequest(allocator, &reply); 1599 if (error != B_OK) 1600 RETURN_ERROR(error); 1601 1602 reply->error = result; 1603 1604 // send the reply 1605 return _SendReply(allocator, false); 1606 } 1607 1608 // _HandleRequest 1609 status_t 1610 UserlandRequestHandler::_HandleRequest(FreeAttrDirCookieRequest* request) 1611 { 1612 // check and execute the request 1613 status_t result = B_OK; 1614 Volume* volume = (Volume*)request->volume; 1615 if (!volume) 1616 result = B_BAD_VALUE; 1617 1618 if (result == B_OK) { 1619 RequestThreadContext context(volume, request); 1620 result = volume->FreeAttrDirCookie(request->node, 1621 request->attrDirCookie); 1622 } 1623 1624 // prepare the reply 1625 RequestAllocator allocator(fPort->GetPort()); 1626 FreeAttrDirCookieReply* reply; 1627 status_t error = AllocateRequest(allocator, &reply); 1628 if (error != B_OK) 1629 RETURN_ERROR(error); 1630 1631 reply->error = result; 1632 1633 // send the reply 1634 return _SendReply(allocator, false); 1635 } 1636 1637 // _HandleRequest 1638 status_t 1639 UserlandRequestHandler::_HandleRequest(ReadAttrDirRequest* request) 1640 { 1641 // check and execute the request 1642 status_t result = B_OK; 1643 Volume* volume = (Volume*)request->volume; 1644 if (!volume) 1645 result = B_BAD_VALUE; 1646 1647 void* node = request->node; 1648 void* attrDirCookie = request->attrDirCookie; 1649 size_t bufferSize = request->bufferSize; 1650 uint32 count = request->count; 1651 1652 // allocate the reply 1653 RequestAllocator allocator(fPort->GetPort()); 1654 ReadAttrDirReply* reply; 1655 status_t error = AllocateRequest(allocator, &reply); 1656 if (error != B_OK) 1657 RETURN_ERROR(error); 1658 1659 void* buffer; 1660 if (result == B_OK) { 1661 result = allocator.AllocateAddress(reply->buffer, bufferSize, 1, 1662 &buffer, true); 1663 } 1664 1665 // execute the request 1666 uint32 countRead; 1667 if (result == B_OK) { 1668 RequestThreadContext context(volume, request); 1669 result = volume->ReadAttrDir(node, attrDirCookie, buffer, bufferSize, 1670 count, &countRead); 1671 } 1672 1673 // reconstruct the reply, in case it has been overwritten 1674 reply = new(reply) ReadAttrDirReply; 1675 1676 // send the reply 1677 reply->error = result; 1678 reply->count = countRead; 1679 return _SendReply(allocator, (result == B_OK)); 1680 } 1681 1682 // _HandleRequest 1683 status_t 1684 UserlandRequestHandler::_HandleRequest(RewindAttrDirRequest* request) 1685 { 1686 // check and execute the request 1687 status_t result = B_OK; 1688 Volume* volume = (Volume*)request->volume; 1689 if (!volume) 1690 result = B_BAD_VALUE; 1691 1692 if (result == B_OK) { 1693 RequestThreadContext context(volume, request); 1694 result = volume->RewindAttrDir(request->node, request->attrDirCookie); 1695 } 1696 1697 // prepare the reply 1698 RequestAllocator allocator(fPort->GetPort()); 1699 RewindAttrDirReply* reply; 1700 status_t error = AllocateRequest(allocator, &reply); 1701 if (error != B_OK) 1702 RETURN_ERROR(error); 1703 1704 reply->error = result; 1705 1706 // send the reply 1707 return _SendReply(allocator, false); 1708 } 1709 1710 1711 // #pragma mark - attributes 1712 1713 1714 // _HandleRequest 1715 status_t 1716 UserlandRequestHandler::_HandleRequest(CreateAttrRequest* 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 void* attrCookie; 1725 if (result == B_OK) { 1726 RequestThreadContext context(volume, request); 1727 result = volume->CreateAttr(request->node, 1728 (const char*)request->name.GetData(), request->type, 1729 request->openMode, &attrCookie); 1730 } 1731 1732 // prepare the reply 1733 RequestAllocator allocator(fPort->GetPort()); 1734 CreateAttrReply* reply; 1735 status_t error = AllocateRequest(allocator, &reply); 1736 if (error != B_OK) 1737 RETURN_ERROR(error); 1738 1739 reply->error = result; 1740 reply->attrCookie = attrCookie; 1741 1742 // send the reply 1743 return _SendReply(allocator, false); 1744 } 1745 1746 // _HandleRequest 1747 status_t 1748 UserlandRequestHandler::_HandleRequest(OpenAttrRequest* 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 void* attrCookie; 1757 if (result == B_OK) { 1758 RequestThreadContext context(volume, request); 1759 result = volume->OpenAttr(request->node, 1760 (const char*)request->name.GetData(), request->openMode, 1761 &attrCookie); 1762 } 1763 1764 // prepare the reply 1765 RequestAllocator allocator(fPort->GetPort()); 1766 OpenAttrReply* reply; 1767 status_t error = AllocateRequest(allocator, &reply); 1768 if (error != B_OK) 1769 RETURN_ERROR(error); 1770 1771 reply->error = result; 1772 reply->attrCookie = attrCookie; 1773 1774 // send the reply 1775 return _SendReply(allocator, false); 1776 } 1777 1778 // _HandleRequest 1779 status_t 1780 UserlandRequestHandler::_HandleRequest(CloseAttrRequest* request) 1781 { 1782 // check and execute the request 1783 status_t result = B_OK; 1784 Volume* volume = (Volume*)request->volume; 1785 if (!volume) 1786 result = B_BAD_VALUE; 1787 1788 if (result == B_OK) { 1789 RequestThreadContext context(volume, request); 1790 result = volume->CloseAttr(request->node, request->attrCookie); 1791 } 1792 1793 // prepare the reply 1794 RequestAllocator allocator(fPort->GetPort()); 1795 CloseAttrReply* 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(FreeAttrCookieRequest* 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, request); 1818 result = volume->FreeAttrCookie(request->node, request->attrCookie); 1819 } 1820 1821 // prepare the reply 1822 RequestAllocator allocator(fPort->GetPort()); 1823 FreeAttrCookieReply* reply; 1824 status_t error = AllocateRequest(allocator, &reply); 1825 if (error != B_OK) 1826 RETURN_ERROR(error); 1827 1828 reply->error = result; 1829 1830 // send the reply 1831 return _SendReply(allocator, false); 1832 } 1833 1834 // _HandleRequest 1835 status_t 1836 UserlandRequestHandler::_HandleRequest(ReadAttrRequest* request) 1837 { 1838 // check and execute the request 1839 status_t result = B_OK; 1840 Volume* volume = (Volume*)request->volume; 1841 if (!volume) 1842 result = B_BAD_VALUE; 1843 1844 void* node = request->node; 1845 void* attrCookie = request->attrCookie; 1846 off_t pos = request->pos; 1847 size_t size = request->size; 1848 1849 // allocate the reply 1850 RequestAllocator allocator(fPort->GetPort()); 1851 ReadAttrReply* reply; 1852 status_t error = AllocateRequest(allocator, &reply); 1853 if (error != B_OK) 1854 RETURN_ERROR(error); 1855 1856 void* buffer; 1857 if (result == B_OK) { 1858 result = allocator.AllocateAddress(reply->buffer, size, 1, &buffer, 1859 true); 1860 } 1861 1862 // execute the request 1863 size_t bytesRead; 1864 if (result == B_OK) { 1865 RequestThreadContext context(volume, request); 1866 result = volume->ReadAttr(node, attrCookie, pos, buffer, size, 1867 &bytesRead); 1868 } 1869 1870 // reconstruct the reply, in case it has been overwritten 1871 reply = new(reply) ReadAttrReply; 1872 1873 // send the reply 1874 reply->error = result; 1875 reply->bytesRead = bytesRead; 1876 return _SendReply(allocator, (result == B_OK)); 1877 } 1878 1879 // _HandleRequest 1880 status_t 1881 UserlandRequestHandler::_HandleRequest(WriteAttrRequest* request) 1882 { 1883 // check and execute the request 1884 status_t result = B_OK; 1885 Volume* volume = (Volume*)request->volume; 1886 if (!volume) 1887 result = B_BAD_VALUE; 1888 1889 size_t bytesWritten; 1890 if (result == B_OK) { 1891 RequestThreadContext context(volume, request); 1892 result = volume->WriteAttr(request->node, request->attrCookie, 1893 request->pos, request->buffer.GetData(), request->buffer.GetSize(), 1894 &bytesWritten); 1895 } 1896 1897 // prepare the reply 1898 RequestAllocator allocator(fPort->GetPort()); 1899 WriteAttrReply* reply; 1900 status_t error = AllocateRequest(allocator, &reply); 1901 if (error != B_OK) 1902 RETURN_ERROR(error); 1903 1904 reply->error = result; 1905 reply->bytesWritten = bytesWritten; 1906 1907 // send the reply 1908 return _SendReply(allocator, false); 1909 } 1910 1911 // _HandleRequest 1912 status_t 1913 UserlandRequestHandler::_HandleRequest(ReadAttrStatRequest* request) 1914 { 1915 // check and execute the request 1916 status_t result = B_OK; 1917 Volume* volume = (Volume*)request->volume; 1918 if (!volume) 1919 result = B_BAD_VALUE; 1920 1921 struct stat st; 1922 if (result == B_OK) { 1923 RequestThreadContext context(volume, request); 1924 result = volume->ReadAttrStat(request->node, request->attrCookie, 1925 &st); 1926 } 1927 1928 // prepare the reply 1929 RequestAllocator allocator(fPort->GetPort()); 1930 ReadAttrStatReply* reply; 1931 status_t error = AllocateRequest(allocator, &reply); 1932 if (error != B_OK) 1933 RETURN_ERROR(error); 1934 1935 reply->error = result; 1936 reply->st = st; 1937 1938 // send the reply 1939 return _SendReply(allocator, false); 1940 } 1941 1942 // _HandleRequest 1943 status_t 1944 UserlandRequestHandler::_HandleRequest(WriteAttrStatRequest* request) 1945 { 1946 // check and execute the request 1947 status_t result = B_OK; 1948 Volume* volume = (Volume*)request->volume; 1949 if (!volume) 1950 result = B_BAD_VALUE; 1951 1952 if (result == B_OK) { 1953 RequestThreadContext context(volume, request); 1954 result = volume->WriteAttrStat(request->node, request->attrCookie, 1955 &request->st, request->mask); 1956 } 1957 1958 // prepare the reply 1959 RequestAllocator allocator(fPort->GetPort()); 1960 WriteAttrStatReply* reply; 1961 status_t error = AllocateRequest(allocator, &reply); 1962 if (error != B_OK) 1963 RETURN_ERROR(error); 1964 1965 reply->error = result; 1966 1967 // send the reply 1968 return _SendReply(allocator, false); 1969 } 1970 1971 // _HandleRequest 1972 status_t 1973 UserlandRequestHandler::_HandleRequest(RenameAttrRequest* request) 1974 { 1975 // check and execute the request 1976 status_t result = B_OK; 1977 Volume* volume = (Volume*)request->volume; 1978 if (!volume) 1979 result = B_BAD_VALUE; 1980 1981 if (result == B_OK) { 1982 RequestThreadContext context(volume, request); 1983 result = volume->RenameAttr( 1984 request->oldNode, (const char*)request->oldName.GetData(), 1985 request->newNode, (const char*)request->newName.GetData()); 1986 } 1987 1988 // prepare the reply 1989 RequestAllocator allocator(fPort->GetPort()); 1990 RenameAttrReply* reply; 1991 status_t error = AllocateRequest(allocator, &reply); 1992 if (error != B_OK) 1993 RETURN_ERROR(error); 1994 1995 reply->error = result; 1996 1997 // send the reply 1998 return _SendReply(allocator, false); 1999 } 2000 2001 // _HandleRequest 2002 status_t 2003 UserlandRequestHandler::_HandleRequest(RemoveAttrRequest* request) 2004 { 2005 // check and execute the request 2006 status_t result = B_OK; 2007 Volume* volume = (Volume*)request->volume; 2008 if (!volume) 2009 result = B_BAD_VALUE; 2010 2011 if (result == B_OK) { 2012 RequestThreadContext context(volume, request); 2013 result = volume->RemoveAttr(request->node, 2014 (const char*)request->name.GetData()); 2015 } 2016 2017 // prepare the reply 2018 RequestAllocator allocator(fPort->GetPort()); 2019 RemoveAttrReply* reply; 2020 status_t error = AllocateRequest(allocator, &reply); 2021 if (error != B_OK) 2022 RETURN_ERROR(error); 2023 2024 reply->error = result; 2025 2026 // send the reply 2027 return _SendReply(allocator, false); 2028 } 2029 2030 2031 // #pragma mark - indices 2032 2033 2034 // _HandleRequest 2035 status_t 2036 UserlandRequestHandler::_HandleRequest(OpenIndexDirRequest* request) 2037 { 2038 // check and execute the request 2039 status_t result = B_OK; 2040 Volume* volume = (Volume*)request->volume; 2041 if (!volume) 2042 result = B_BAD_VALUE; 2043 2044 void* indexDirCookie; 2045 if (result == B_OK) { 2046 RequestThreadContext context(volume, request); 2047 result = volume->OpenIndexDir(&indexDirCookie); 2048 } 2049 2050 // prepare the reply 2051 RequestAllocator allocator(fPort->GetPort()); 2052 OpenIndexDirReply* reply; 2053 status_t error = AllocateRequest(allocator, &reply); 2054 if (error != B_OK) 2055 RETURN_ERROR(error); 2056 2057 reply->error = result; 2058 reply->indexDirCookie = indexDirCookie; 2059 2060 // send the reply 2061 return _SendReply(allocator, false); 2062 } 2063 2064 // _HandleRequest 2065 status_t 2066 UserlandRequestHandler::_HandleRequest(CloseIndexDirRequest* request) 2067 { 2068 // check and execute the request 2069 status_t result = B_OK; 2070 Volume* volume = (Volume*)request->volume; 2071 if (!volume) 2072 result = B_BAD_VALUE; 2073 2074 if (result == B_OK) { 2075 RequestThreadContext context(volume, request); 2076 result = volume->CloseIndexDir(request->indexDirCookie); 2077 } 2078 2079 // prepare the reply 2080 RequestAllocator allocator(fPort->GetPort()); 2081 CloseIndexDirReply* reply; 2082 status_t error = AllocateRequest(allocator, &reply); 2083 if (error != B_OK) 2084 RETURN_ERROR(error); 2085 2086 reply->error = result; 2087 2088 // send the reply 2089 return _SendReply(allocator, false); 2090 } 2091 2092 // _HandleRequest 2093 status_t 2094 UserlandRequestHandler::_HandleRequest(FreeIndexDirCookieRequest* request) 2095 { 2096 // check and execute the request 2097 status_t result = B_OK; 2098 Volume* volume = (Volume*)request->volume; 2099 if (!volume) 2100 result = B_BAD_VALUE; 2101 2102 if (result == B_OK) { 2103 RequestThreadContext context(volume, request); 2104 result = volume->FreeIndexDirCookie(request->indexDirCookie); 2105 } 2106 2107 // prepare the reply 2108 RequestAllocator allocator(fPort->GetPort()); 2109 FreeIndexDirCookieReply* reply; 2110 status_t error = AllocateRequest(allocator, &reply); 2111 if (error != B_OK) 2112 RETURN_ERROR(error); 2113 2114 reply->error = result; 2115 2116 // send the reply 2117 return _SendReply(allocator, false); 2118 } 2119 2120 // _HandleRequest 2121 status_t 2122 UserlandRequestHandler::_HandleRequest(ReadIndexDirRequest* request) 2123 { 2124 // check and execute the request 2125 status_t result = B_OK; 2126 Volume* volume = (Volume*)request->volume; 2127 if (!volume) 2128 result = B_BAD_VALUE; 2129 2130 void* indexDirCookie = request->indexDirCookie; 2131 size_t bufferSize = request->bufferSize; 2132 uint32 count = request->count; 2133 2134 // allocate the reply 2135 RequestAllocator allocator(fPort->GetPort()); 2136 ReadIndexDirReply* reply; 2137 status_t error = AllocateRequest(allocator, &reply); 2138 if (error != B_OK) 2139 RETURN_ERROR(error); 2140 2141 void* buffer; 2142 if (result == B_OK) { 2143 result = allocator.AllocateAddress(reply->buffer, bufferSize, 1, 2144 &buffer, true); 2145 } 2146 2147 // execute the request 2148 uint32 countRead; 2149 if (result == B_OK) { 2150 RequestThreadContext context(volume, request); 2151 result = volume->ReadIndexDir(indexDirCookie, buffer, bufferSize, 2152 count, &countRead); 2153 } 2154 2155 // reconstruct the reply, in case it has been overwritten 2156 reply = new(reply) ReadIndexDirReply; 2157 2158 // send the reply 2159 reply->error = result; 2160 reply->count = countRead; 2161 return _SendReply(allocator, (result == B_OK)); 2162 } 2163 2164 // _HandleRequest 2165 status_t 2166 UserlandRequestHandler::_HandleRequest(RewindIndexDirRequest* request) 2167 { 2168 // check and execute the request 2169 status_t result = B_OK; 2170 Volume* volume = (Volume*)request->volume; 2171 if (!volume) 2172 result = B_BAD_VALUE; 2173 2174 if (result == B_OK) { 2175 RequestThreadContext context(volume, request); 2176 result = volume->RewindIndexDir(request->indexDirCookie); 2177 } 2178 2179 // prepare the reply 2180 RequestAllocator allocator(fPort->GetPort()); 2181 RewindIndexDirReply* reply; 2182 status_t error = AllocateRequest(allocator, &reply); 2183 if (error != B_OK) 2184 RETURN_ERROR(error); 2185 2186 reply->error = result; 2187 2188 // send the reply 2189 return _SendReply(allocator, false); 2190 } 2191 2192 // _HandleRequest 2193 status_t 2194 UserlandRequestHandler::_HandleRequest(CreateIndexRequest* request) 2195 { 2196 // check and execute the request 2197 status_t result = B_OK; 2198 Volume* volume = (Volume*)request->volume; 2199 if (!volume) 2200 result = B_BAD_VALUE; 2201 2202 if (result == B_OK) { 2203 RequestThreadContext context(volume, request); 2204 result = volume->CreateIndex((const char*)request->name.GetData(), 2205 request->type, request->flags); 2206 } 2207 2208 // prepare the reply 2209 RequestAllocator allocator(fPort->GetPort()); 2210 CreateIndexReply* reply; 2211 status_t error = AllocateRequest(allocator, &reply); 2212 if (error != B_OK) 2213 RETURN_ERROR(error); 2214 2215 reply->error = result; 2216 2217 // send the reply 2218 return _SendReply(allocator, false); 2219 } 2220 2221 // _HandleRequest 2222 status_t 2223 UserlandRequestHandler::_HandleRequest(RemoveIndexRequest* request) 2224 { 2225 // check and execute the request 2226 status_t result = B_OK; 2227 Volume* volume = (Volume*)request->volume; 2228 if (!volume) 2229 result = B_BAD_VALUE; 2230 2231 if (result == B_OK) { 2232 RequestThreadContext context(volume, request); 2233 result = volume->RemoveIndex((const char*)request->name.GetData()); 2234 } 2235 2236 // prepare the reply 2237 RequestAllocator allocator(fPort->GetPort()); 2238 RemoveIndexReply* reply; 2239 status_t error = AllocateRequest(allocator, &reply); 2240 if (error != B_OK) 2241 RETURN_ERROR(error); 2242 2243 reply->error = result; 2244 2245 // send the reply 2246 return _SendReply(allocator, false); 2247 } 2248 2249 // _HandleRequest 2250 status_t 2251 UserlandRequestHandler::_HandleRequest(ReadIndexStatRequest* request) 2252 { 2253 // check and execute the request 2254 status_t result = B_OK; 2255 Volume* volume = (Volume*)request->volume; 2256 if (!volume) 2257 result = B_BAD_VALUE; 2258 2259 struct stat st; 2260 if (result == B_OK) { 2261 RequestThreadContext context(volume, request); 2262 result = volume->ReadIndexStat((const char*)request->name.GetData(), 2263 &st); 2264 } 2265 2266 // prepare the reply 2267 RequestAllocator allocator(fPort->GetPort()); 2268 ReadIndexStatReply* reply; 2269 status_t error = AllocateRequest(allocator, &reply); 2270 if (error != B_OK) 2271 RETURN_ERROR(error); 2272 2273 reply->error = result; 2274 reply->st = st; 2275 2276 // send the reply 2277 return _SendReply(allocator, false); 2278 } 2279 2280 2281 // #pragma mark - queries 2282 2283 2284 // _HandleRequest 2285 status_t 2286 UserlandRequestHandler::_HandleRequest(OpenQueryRequest* request) 2287 { 2288 // check and execute the request 2289 status_t result = B_OK; 2290 Volume* volume = (Volume*)request->volume; 2291 if (!volume) 2292 result = B_BAD_VALUE; 2293 2294 void* queryCookie; 2295 if (result == B_OK) { 2296 RequestThreadContext context(volume, request); 2297 result = volume->OpenQuery((const char*)request->queryString.GetData(), 2298 request->flags, request->port, request->token, &queryCookie); 2299 } 2300 2301 // prepare the reply 2302 RequestAllocator allocator(fPort->GetPort()); 2303 OpenQueryReply* reply; 2304 status_t error = AllocateRequest(allocator, &reply); 2305 if (error != B_OK) 2306 RETURN_ERROR(error); 2307 2308 reply->error = result; 2309 reply->queryCookie = queryCookie; 2310 2311 // send the reply 2312 return _SendReply(allocator, false); 2313 } 2314 2315 // _HandleRequest 2316 status_t 2317 UserlandRequestHandler::_HandleRequest(CloseQueryRequest* request) 2318 { 2319 // check and execute the request 2320 status_t result = B_OK; 2321 Volume* volume = (Volume*)request->volume; 2322 if (!volume) 2323 result = B_BAD_VALUE; 2324 2325 if (result == B_OK) { 2326 RequestThreadContext context(volume, request); 2327 result = volume->CloseQuery(request->queryCookie); 2328 } 2329 2330 // prepare the reply 2331 RequestAllocator allocator(fPort->GetPort()); 2332 CloseQueryReply* reply; 2333 status_t error = AllocateRequest(allocator, &reply); 2334 if (error != B_OK) 2335 RETURN_ERROR(error); 2336 2337 reply->error = result; 2338 2339 // send the reply 2340 return _SendReply(allocator, false); 2341 } 2342 2343 // _HandleRequest 2344 status_t 2345 UserlandRequestHandler::_HandleRequest(FreeQueryCookieRequest* request) 2346 { 2347 // check and execute the request 2348 status_t result = B_OK; 2349 Volume* volume = (Volume*)request->volume; 2350 if (!volume) 2351 result = B_BAD_VALUE; 2352 2353 if (result == B_OK) { 2354 RequestThreadContext context(volume, request); 2355 result = volume->FreeQueryCookie(request->queryCookie); 2356 } 2357 2358 // prepare the reply 2359 RequestAllocator allocator(fPort->GetPort()); 2360 FreeQueryCookieReply* reply; 2361 status_t error = AllocateRequest(allocator, &reply); 2362 if (error != B_OK) 2363 RETURN_ERROR(error); 2364 2365 reply->error = result; 2366 2367 // send the reply 2368 return _SendReply(allocator, false); 2369 } 2370 2371 // _HandleRequest 2372 status_t 2373 UserlandRequestHandler::_HandleRequest(ReadQueryRequest* request) 2374 { 2375 // check and execute the request 2376 status_t result = B_OK; 2377 Volume* volume = (Volume*)request->volume; 2378 if (!volume) 2379 result = B_BAD_VALUE; 2380 2381 void* queryCookie = request->queryCookie; 2382 size_t bufferSize = request->bufferSize; 2383 uint32 count = request->count; 2384 2385 // allocate the reply 2386 RequestAllocator allocator(fPort->GetPort()); 2387 ReadQueryReply* reply; 2388 status_t error = AllocateRequest(allocator, &reply); 2389 if (error != B_OK) 2390 RETURN_ERROR(error); 2391 2392 void* buffer; 2393 if (result == B_OK) { 2394 result = allocator.AllocateAddress(reply->buffer, bufferSize, 1, 2395 &buffer, true); 2396 } 2397 2398 // execute the request 2399 uint32 countRead; 2400 if (result == B_OK) { 2401 RequestThreadContext context(volume, request); 2402 result = volume->ReadQuery(queryCookie, buffer, bufferSize, 2403 count, &countRead); 2404 } 2405 2406 // reconstruct the reply, in case it has been overwritten 2407 reply = new(reply) ReadQueryReply; 2408 2409 // send the reply 2410 reply->error = result; 2411 reply->count = countRead; 2412 return _SendReply(allocator, (result == B_OK)); 2413 } 2414 2415 // _HandleRequest 2416 status_t 2417 UserlandRequestHandler::_HandleRequest(RewindQueryRequest* request) 2418 { 2419 // check and execute the request 2420 status_t result = B_OK; 2421 Volume* volume = (Volume*)request->volume; 2422 if (!volume) 2423 result = B_BAD_VALUE; 2424 2425 if (result == B_OK) { 2426 RequestThreadContext context(volume, request); 2427 result = volume->RewindQuery(request->queryCookie); 2428 } 2429 2430 // prepare the reply 2431 RequestAllocator allocator(fPort->GetPort()); 2432 RewindQueryReply* reply; 2433 status_t error = AllocateRequest(allocator, &reply); 2434 if (error != B_OK) 2435 RETURN_ERROR(error); 2436 2437 reply->error = result; 2438 2439 // send the reply 2440 return _SendReply(allocator, false); 2441 } 2442 2443 2444 // #pragma mark - node monitoring 2445 2446 2447 // _HandleRequest 2448 status_t 2449 UserlandRequestHandler::_HandleRequest(NodeMonitoringEventRequest* request) 2450 { 2451 // check and execute the request 2452 KMessage event; 2453 event.SetTo(request->event.GetData(), request->event.GetSize()); 2454 ((NotificationListener*)request->listener)->EventOccurred( 2455 *(NotificationService*)NULL, &event); 2456 2457 // prepare the reply 2458 RequestAllocator allocator(fPort->GetPort()); 2459 NodeMonitoringEventReply* reply; 2460 status_t error = AllocateRequest(allocator, &reply); 2461 if (error != B_OK) 2462 RETURN_ERROR(error); 2463 2464 reply->error = B_OK; 2465 2466 // send the reply 2467 return _SendReply(allocator, false); 2468 } 2469 2470 2471 // #pragma mark - other 2472 2473 2474 // _SendReply 2475 status_t 2476 UserlandRequestHandler::_SendReply(RequestAllocator& allocator, 2477 bool expectsReceipt) 2478 { 2479 if (expectsReceipt) { 2480 SingleReplyRequestHandler handler(RECEIPT_ACK_REPLY); 2481 return fPort->SendRequest(&allocator, &handler); 2482 } else 2483 return fPort->SendRequest(&allocator); 2484 } 2485 2486