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
UserlandRequestHandler(FileSystem * fileSystem)27 UserlandRequestHandler::UserlandRequestHandler(FileSystem* fileSystem)
28 : RequestHandler(),
29 fFileSystem(fileSystem),
30 fExpectReply(false),
31 fExpectedReply(0)
32 {
33 }
34
35 // constructor
UserlandRequestHandler(FileSystem * fileSystem,uint32 expectedReply)36 UserlandRequestHandler::UserlandRequestHandler(FileSystem* fileSystem,
37 uint32 expectedReply)
38 : RequestHandler(),
39 fFileSystem(fileSystem),
40 fExpectReply(true),
41 fExpectedReply(expectedReply)
42 {
43 }
44
45 // destructor
~UserlandRequestHandler()46 UserlandRequestHandler::~UserlandRequestHandler()
47 {
48 }
49
50 // HandleRequest
51 status_t
HandleRequest(Request * request)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
_HandleRequest(MountVolumeRequest * request)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
_HandleRequest(UnmountVolumeRequest * request)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
_HandleRequest(SyncVolumeRequest * request)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
_HandleRequest(ReadFSInfoRequest * request)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
_HandleRequest(WriteFSInfoRequest * request)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
_HandleRequest(LookupRequest * request)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
_HandleRequest(GetVNodeNameRequest * request)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
_HandleRequest(ReadVNodeRequest * request)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
_HandleRequest(WriteVNodeRequest * request)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
_HandleRequest(FSRemoveVNodeRequest * request)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
_HandleRequest(DoIORequest * request)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
_HandleRequest(CancelIORequest * request)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
_HandleRequest(IterativeIOGetVecsRequest * request)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
_HandleRequest(IterativeIOFinishedRequest * request)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
_HandleRequest(IOCtlRequest * request)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
_HandleRequest(SetFlagsRequest * request)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
_HandleRequest(SelectRequest * request)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
_HandleRequest(DeselectRequest * request)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
_HandleRequest(FSyncRequest * request)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
_HandleRequest(ReadSymlinkRequest * request)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
_HandleRequest(CreateSymlinkRequest * request)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
_HandleRequest(LinkRequest * request)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
_HandleRequest(UnlinkRequest * request)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
_HandleRequest(RenameRequest * request)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
_HandleRequest(AccessRequest * request)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
_HandleRequest(ReadStatRequest * request)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
_HandleRequest(WriteStatRequest * request)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
_HandleRequest(CreateRequest * request)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
_HandleRequest(OpenRequest * request)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
_HandleRequest(CloseRequest * request)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
_HandleRequest(FreeCookieRequest * request)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
_HandleRequest(ReadRequest * request)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
_HandleRequest(WriteRequest * request)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
_HandleRequest(CreateDirRequest * request)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
_HandleRequest(RemoveDirRequest * request)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
_HandleRequest(OpenDirRequest * request)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
_HandleRequest(CloseDirRequest * request)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
_HandleRequest(FreeDirCookieRequest * request)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
_HandleRequest(ReadDirRequest * request)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
_HandleRequest(RewindDirRequest * request)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
_HandleRequest(OpenAttrDirRequest * request)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
_HandleRequest(CloseAttrDirRequest * request)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
_HandleRequest(FreeAttrDirCookieRequest * request)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
_HandleRequest(ReadAttrDirRequest * request)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
_HandleRequest(RewindAttrDirRequest * request)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
_HandleRequest(CreateAttrRequest * request)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
_HandleRequest(OpenAttrRequest * request)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
_HandleRequest(CloseAttrRequest * request)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
_HandleRequest(FreeAttrCookieRequest * request)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
_HandleRequest(ReadAttrRequest * request)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
_HandleRequest(WriteAttrRequest * request)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
_HandleRequest(ReadAttrStatRequest * request)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
_HandleRequest(WriteAttrStatRequest * request)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
_HandleRequest(RenameAttrRequest * request)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
_HandleRequest(RemoveAttrRequest * request)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
_HandleRequest(OpenIndexDirRequest * request)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
_HandleRequest(CloseIndexDirRequest * request)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
_HandleRequest(FreeIndexDirCookieRequest * request)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
_HandleRequest(ReadIndexDirRequest * request)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
_HandleRequest(RewindIndexDirRequest * request)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
_HandleRequest(CreateIndexRequest * request)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
_HandleRequest(RemoveIndexRequest * request)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
_HandleRequest(ReadIndexStatRequest * request)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
_HandleRequest(OpenQueryRequest * request)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
_HandleRequest(CloseQueryRequest * request)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
_HandleRequest(FreeQueryCookieRequest * request)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
_HandleRequest(ReadQueryRequest * request)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
_HandleRequest(RewindQueryRequest * request)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
_HandleRequest(NodeMonitoringEventRequest * request)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
_SendReply(RequestAllocator & allocator,bool expectsReceipt)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