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