xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/server/UserlandRequestHandler.cpp (revision 422eeed69970bd2002f8663dce331521b5e117de)
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