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