xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp (revision c237c4ce593ee823d9867fd997e51e4c447f5623)
1 // Requests.cpp
2 
3 #include <limits.h>
4 
5 #include "Debug.h"
6 #include "Requests.h"
7 
8 #define _ADD_ADDRESS(_address, _flags)				\
9 	if (*count >= MAX_REQUEST_ADDRESS_COUNT)		\
10 		return B_BAD_VALUE;							\
11 	infos[*count].address = &_address;				\
12 	infos[*count].flags = _flags;					\
13 	infos[(*count)++].max_size = INT32_MAX;	// TODO:...
14 
15 #define ADD_ADDRESS(address)	_ADD_ADDRESS(address, 0)
16 #define ADD_STRING(address)		_ADD_ADDRESS(address, ADDRESS_IS_STRING)
17 #define ADD_NON_NULL_ADDRESS(address)	_ADD_ADDRESS(address, ADDRESS_NOT_NULL)
18 #define ADD_NON_NULL_STRING(address)	\
19 	_ADD_ADDRESS(address, (ADDRESS_IS_STRING | ADDRESS_NOT_NULL))
20 
21 // FSConnectRequest
22 status_t
23 FSConnectRequest::GetAddressInfos(AddressInfo* infos, int32* count)
24 {
25 	ADD_NON_NULL_STRING(fsName);
26 	return B_OK;
27 }
28 
29 // FSConnectReply
30 status_t
31 FSConnectReply::GetAddressInfos(AddressInfo* infos, int32* count)
32 {
33 	ADD_NON_NULL_ADDRESS(portInfos);
34 	return B_OK;
35 }
36 
37 // MountVolumeRequest
38 status_t
39 MountVolumeRequest::GetAddressInfos(AddressInfo* infos, int32* count)
40 {
41 	ADD_NON_NULL_STRING(cwd);
42 	ADD_STRING(device);
43 	ADD_STRING(parameters);
44 	return B_OK;
45 }
46 
47 //// InitializeVolumeRequest
48 //status_t
49 //InitializeVolumeRequest::GetAddressInfos(AddressInfo* infos, int32* count)
50 //{
51 //	ADD_STRING(device);
52 //	ADD_STRING(parameters);
53 //	return B_OK;
54 //}
55 
56 // GetVNodeNameReply
57 status_t
58 GetVNodeNameReply::GetAddressInfos(AddressInfo* infos, int32* count)
59 {
60 	ADD_STRING(buffer);
61 	return B_OK;
62 }
63 
64 // CreateRequest
65 status_t
66 CreateRequest::GetAddressInfos(AddressInfo* infos, int32* count)
67 {
68 	ADD_NON_NULL_STRING(name);
69 	return B_OK;
70 }
71 
72 // ReadReply
73 status_t
74 ReadReply::GetAddressInfos(AddressInfo* infos, int32* count)
75 {
76 	ADD_ADDRESS(buffer);
77 	return B_OK;
78 }
79 
80 // WriteRequest
81 status_t
82 WriteRequest::GetAddressInfos(AddressInfo* infos, int32* count)
83 {
84 	ADD_ADDRESS(buffer);
85 	return B_OK;
86 }
87 
88 // IOCtlRequest
89 status_t
90 IOCtlRequest::GetAddressInfos(AddressInfo* infos, int32* count)
91 {
92 	ADD_ADDRESS(buffer);
93 	return B_OK;
94 }
95 
96 // IOCtlReply
97 status_t
98 IOCtlReply::GetAddressInfos(AddressInfo* infos, int32* count)
99 {
100 	ADD_ADDRESS(buffer);
101 	return B_OK;
102 }
103 
104 // LinkRequest
105 status_t
106 LinkRequest::GetAddressInfos(AddressInfo* infos, int32* count)
107 {
108 	ADD_NON_NULL_STRING(name);
109 	return B_OK;
110 }
111 
112 // UnlinkRequest
113 status_t
114 UnlinkRequest::GetAddressInfos(AddressInfo* infos, int32* count)
115 {
116 	ADD_NON_NULL_STRING(name);
117 	return B_OK;
118 }
119 
120 // CreateSymlinkRequest
121 status_t
122 CreateSymlinkRequest::GetAddressInfos(AddressInfo* infos, int32* count)
123 {
124 	ADD_NON_NULL_STRING(name);
125 	ADD_NON_NULL_STRING(target);
126 	return B_OK;
127 }
128 
129 // ReadSymlinkReply
130 status_t
131 ReadSymlinkReply::GetAddressInfos(AddressInfo* infos, int32* count)
132 {
133 	ADD_STRING(buffer);
134 	return B_OK;
135 }
136 
137 // RenameRequest
138 status_t
139 RenameRequest::GetAddressInfos(AddressInfo* infos, int32* count)
140 {
141 	ADD_NON_NULL_STRING(oldName);
142 	ADD_NON_NULL_STRING(newName);
143 	return B_OK;
144 }
145 
146 // CreateDirRequest
147 status_t
148 CreateDirRequest::GetAddressInfos(AddressInfo* infos, int32* count)
149 {
150 	ADD_NON_NULL_STRING(name);
151 	return B_OK;
152 }
153 
154 // RemoveDirRequest
155 status_t
156 RemoveDirRequest::GetAddressInfos(AddressInfo* infos, int32* count)
157 {
158 	ADD_NON_NULL_STRING(name);
159 	return B_OK;
160 }
161 
162 // ReadDirReply
163 status_t
164 ReadDirReply::GetAddressInfos(AddressInfo* infos, int32* count)
165 {
166 	ADD_ADDRESS(buffer);
167 	return B_OK;
168 }
169 
170 // LookupRequest
171 status_t
172 LookupRequest::GetAddressInfos(AddressInfo* infos, int32* count)
173 {
174 	ADD_NON_NULL_STRING(entryName);
175 	return B_OK;
176 }
177 
178 // ReadAttrDirReply
179 status_t
180 ReadAttrDirReply::GetAddressInfos(AddressInfo* infos, int32* count)
181 {
182 	ADD_ADDRESS(buffer);
183 	return B_OK;
184 }
185 
186 // CreateAttrRequest
187 status_t
188 CreateAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
189 {
190 	ADD_NON_NULL_STRING(name);
191 	return B_OK;
192 }
193 
194 // OpenAttrRequest
195 status_t
196 OpenAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
197 {
198 	ADD_NON_NULL_STRING(name);
199 	return B_OK;
200 }
201 
202 // ReadAttrReply
203 status_t
204 ReadAttrReply::GetAddressInfos(AddressInfo* infos, int32* count)
205 {
206 	ADD_ADDRESS(buffer);
207 	return B_OK;
208 }
209 
210 // WriteAttrRequest
211 status_t
212 WriteAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
213 {
214 	ADD_ADDRESS(buffer);
215 	return B_OK;
216 }
217 
218 // RemoveAttrRequest
219 status_t
220 RemoveAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
221 {
222 	ADD_NON_NULL_STRING(name);
223 	return B_OK;
224 }
225 
226 // RenameAttrRequest
227 status_t
228 RenameAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
229 {
230 	ADD_NON_NULL_STRING(oldName);
231 	ADD_NON_NULL_STRING(newName);
232 	return B_OK;
233 }
234 
235 // ReadIndexDirReply
236 status_t
237 ReadIndexDirReply::GetAddressInfos(AddressInfo* infos, int32* count)
238 {
239 	ADD_ADDRESS(buffer);
240 	return B_OK;
241 }
242 
243 // CreateIndexRequest
244 status_t
245 CreateIndexRequest::GetAddressInfos(AddressInfo* infos, int32* count)
246 {
247 	ADD_NON_NULL_STRING(name);
248 	return B_OK;
249 }
250 
251 // RemoveIndexRequest
252 status_t
253 RemoveIndexRequest::GetAddressInfos(AddressInfo* infos, int32* count)
254 {
255 	ADD_NON_NULL_STRING(name);
256 	return B_OK;
257 }
258 
259 // ReadIndexStatRequest
260 status_t
261 ReadIndexStatRequest::GetAddressInfos(AddressInfo* infos, int32* count)
262 {
263 	ADD_NON_NULL_STRING(name);
264 	return B_OK;
265 }
266 
267 // OpenQueryRequest
268 status_t
269 OpenQueryRequest::GetAddressInfos(AddressInfo* infos, int32* count)
270 {
271 	ADD_NON_NULL_STRING(queryString);
272 	return B_OK;
273 }
274 
275 // ReadQueryReply
276 status_t
277 ReadQueryReply::GetAddressInfos(AddressInfo* infos, int32* count)
278 {
279 	ADD_ADDRESS(buffer);
280 	return B_OK;
281 }
282 
283 // NodeMonitoringEventRequest
284 status_t
285 NodeMonitoringEventRequest::GetAddressInfos(AddressInfo* infos, int32* count)
286 {
287 	ADD_ADDRESS(event);
288 	return B_OK;
289 }
290 
291 // NotifyListenerRequest
292 status_t
293 NotifyListenerRequest::GetAddressInfos(AddressInfo* infos, int32* count)
294 {
295 	ADD_STRING(oldName);
296 	ADD_STRING(name);
297 	return B_OK;
298 }
299 
300 // NotifyQueryRequest
301 status_t
302 NotifyQueryRequest::GetAddressInfos(AddressInfo* infos, int32* count)
303 {
304 	ADD_STRING(name);
305 	return B_OK;
306 }
307 
308 // FileCacheReadReply
309 status_t
310 FileCacheReadReply::GetAddressInfos(AddressInfo* infos, int32* count)
311 {
312 	ADD_ADDRESS(buffer);
313 	return B_OK;
314 }
315 
316 // FileCacheWriteRequest
317 status_t
318 FileCacheWriteRequest::GetAddressInfos(AddressInfo* infos, int32* count)
319 {
320 	ADD_ADDRESS(buffer);
321 	return B_OK;
322 }
323 
324 // ReadFromIORequestReply
325 status_t
326 ReadFromIORequestReply::GetAddressInfos(AddressInfo* infos, int32* count)
327 {
328 	ADD_ADDRESS(buffer);
329 	return B_OK;
330 }
331 
332 // WriteToIORequestRequest
333 status_t
334 WriteToIORequestRequest::GetAddressInfos(AddressInfo* infos, int32* count)
335 {
336 	ADD_ADDRESS(buffer);
337 	return B_OK;
338 }
339 
340 
341 // #pragma mark -
342 
343 // RequestAddressInfoGetter
344 struct RequestAddressInfoGetter {
345 	RequestAddressInfoGetter(AddressInfo* infos, int32* count)
346 		: fInfos(infos),
347 		  fCount(count)
348 	{
349 	}
350 
351 	template<typename R> status_t operator()(R* request)
352 	{
353 		return request->GetAddressInfos(fInfos, fCount);
354 	}
355 
356 private:
357 	AddressInfo*	fInfos;
358 	int32*			fCount;
359 };
360 
361 // get_request_address_infos
362 status_t
363 UserlandFSUtil::get_request_address_infos(Request* request, AddressInfo* infos,
364 	int32* count)
365 {
366 	if (!infos || !count)
367 		return B_BAD_VALUE;
368 	*count = 0;
369 	RequestAddressInfoGetter task(infos, count);
370 	return do_for_request(request, task);
371 }
372 
373 // RequestChecker
374 struct RequestChecker {
375 	template<typename R> status_t operator()(R* request)
376 	{
377 		return request->Check();
378 	}
379 };
380 
381 // check_request
382 status_t
383 UserlandFSUtil::check_request(Request* request)
384 {
385 	RequestChecker task;
386 	return do_for_request(request, task);
387 }
388 
389 
390 // is_error_reply
391 static inline
392 bool
393 is_error_reply(Request* request)
394 {
395 	return false;
396 }
397 
398 // is_error_reply
399 static inline
400 bool
401 is_error_reply(ReplyRequest* request)
402 {
403 	return (request->error != B_OK);
404 }
405 
406 // RequestRelocator
407 struct RequestRelocator {
408 	RequestRelocator(int32 requestBufferSize, area_id* areas, int32* count)
409 		: fRequestBufferSize(requestBufferSize),
410 		  fAreas(areas),
411 		  fAreaCount(count)
412 	{
413 		*fAreaCount = 0;
414 	}
415 
416 	~RequestRelocator()
417 	{
418 		if (!fSuccess) {
419 			for (int32 i = 0; i < *fAreaCount; i++)
420 				delete_area(fAreas[i]);
421 		}
422 	}
423 
424 	template<typename R> status_t operator()(R* request)
425 	{
426 		// check the request buffer size
427 		if (fRequestBufferSize < (int32)sizeof(R))
428 			RETURN_ERROR(B_BAD_DATA);
429 		// no need to relocate the addresses of a reply that indicates an error
430 		if (is_error_reply(request)) {
431 			fSuccess = true;
432 			return B_OK;
433 		}
434 		// get the address infos
435 		AddressInfo infos[MAX_REQUEST_ADDRESS_COUNT];
436 		int32 count = 0;
437 		status_t error = request->GetAddressInfos(infos, &count);
438 		if (error != B_OK)
439 			RETURN_ERROR(error);
440 		// check and relocate the addresses
441 		for (int32 i = 0; i < count; i++) {
442 			// check
443 			Address* address = infos[i].address;
444 			int32 size = address->GetSize();
445 			int32 offset = address->GetOffset();
446 //PRINT(("  relocating address: area: %ld, offset: %ld, size: %ld...\n",
447 //address->GetArea(), offset, size));
448 			if (offset < 0 || size < 0 || size > infos[i].max_size)
449 				RETURN_ERROR(B_BAD_DATA);
450 			if ((infos[i].flags & ADDRESS_NOT_NULL) && size == 0)
451 				RETURN_ERROR(B_BAD_DATA);
452 			// relocate
453 			area_id area = address->GetArea();
454 			if (area < 0) {
455 				// data in the buffer itself
456 				if (offset == 0 && size == 0) {
457 //PRINT(("    -> relocated address: NULL\n"));
458 					address->SetRelocatedAddress(NULL);
459 				} else {
460 					if (offset < (int32)sizeof(R)
461 						|| offset + size > fRequestBufferSize) {
462 						RETURN_ERROR(B_BAD_DATA);
463 					}
464 //PRINT(("    -> relocated address: %p\n", (uint8*)request + offset));
465 					address->SetRelocatedAddress((uint8*)request + offset);
466 				}
467 			} else {
468 				// clone the area
469 				void* data;
470 				area = clone_area("cloned request data", &data,
471 #ifdef _KERNEL_MODE
472 					B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA,
473 #else
474 					B_ANY_ADDRESS, B_READ_AREA,
475 #endif
476 					area);
477 				if (area < 0)
478 					RETURN_ERROR(area);
479 				fAreas[(*fAreaCount)++] = area;
480 				// check offset and size
481 				area_info areaInfo;
482 				error = get_area_info(area, &areaInfo);
483 				if (error != B_OK)
484 					RETURN_ERROR(error);
485 				if (offset + size > (int32)areaInfo.size)
486 					RETURN_ERROR(B_BAD_DATA);
487 //PRINT(("    -> relocated address: %p\n", (uint8*)data + offset));
488 				address->SetRelocatedAddress((uint8*)data + offset);
489 			}
490 		}
491 		// finally let the request check its integrity
492 		error = request->Check();
493 		if (error != B_OK)
494 			RETURN_ERROR(error);
495 		fSuccess = true;
496 //PRINT(("RequestRelocator done: success\n"));
497 		return B_OK;
498 	}
499 
500 private:
501 	int32		fRequestBufferSize;
502 	area_id*	fAreas;
503 	int32*		fAreaCount;
504 	bool		fSuccess;
505 };
506 
507 // relocate_request
508 status_t
509 UserlandFSUtil::relocate_request(Request* request, int32 requestBufferSize,
510 	area_id* areas, int32* count)
511 {
512 	if (!request || !areas || !count)
513 		return B_BAD_VALUE;
514 	RequestRelocator task(requestBufferSize, areas, count);
515 	return do_for_request(request, task);
516 }
517 
518 // is_kernel_request
519 bool
520 UserlandFSUtil::is_kernel_request(uint32 type)
521 {
522 	switch (type) {
523 		// kernel -> userland requests
524 		// administrative
525 		case UFS_DISCONNECT_REQUEST:
526 		case FS_CONNECT_REQUEST:
527 			return true;
528 		case FS_CONNECT_REPLY:
529 			return false;
530 		// FS
531 		case MOUNT_VOLUME_REQUEST:
532 		case UNMOUNT_VOLUME_REQUEST:
533 //		case INITIALIZE_VOLUME_REQUEST:
534 		case SYNC_VOLUME_REQUEST:
535 		case READ_FS_INFO_REQUEST:
536 		case WRITE_FS_INFO_REQUEST:
537 			return true;
538 		case MOUNT_VOLUME_REPLY:
539 		case UNMOUNT_VOLUME_REPLY:
540 //		case INITIALIZE_VOLUME_REPLY:
541 		case SYNC_VOLUME_REPLY:
542 		case READ_FS_INFO_REPLY:
543 		case WRITE_FS_INFO_REPLY:
544 			return false;
545 		// vnodes
546 		case LOOKUP_REQUEST:
547 		case GET_VNODE_NAME_REQUEST:
548 		case READ_VNODE_REQUEST:
549 		case WRITE_VNODE_REQUEST:
550 		case FS_REMOVE_VNODE_REQUEST:
551 			return true;
552 		case LOOKUP_REPLY:
553 		case GET_VNODE_NAME_REPLY:
554 		case READ_VNODE_REPLY:
555 		case WRITE_VNODE_REPLY:
556 		case FS_REMOVE_VNODE_REPLY:
557 			return false;
558 		// asynchronous I/O
559 		case DO_IO_REQUEST:
560 		case CANCEL_IO_REQUEST:
561 		case ITERATIVE_IO_GET_VECS_REQUEST:
562 		case ITERATIVE_IO_FINISHED_REQUEST:
563 			return true;
564 		case DO_IO_REPLY:
565 		case CANCEL_IO_REPLY:
566 		case ITERATIVE_IO_GET_VECS_REPLY:
567 		case ITERATIVE_IO_FINISHED_REPLY:
568 			return false;
569 		// nodes
570 		case IOCTL_REQUEST:
571 		case SET_FLAGS_REQUEST:
572 		case SELECT_REQUEST:
573 		case DESELECT_REQUEST:
574 		case FSYNC_REQUEST:
575 		case READ_SYMLINK_REQUEST:
576 		case CREATE_SYMLINK_REQUEST:
577 		case LINK_REQUEST:
578 		case UNLINK_REQUEST:
579 		case RENAME_REQUEST:
580 		case ACCESS_REQUEST:
581 		case READ_STAT_REQUEST:
582 		case WRITE_STAT_REQUEST:
583 			return true;
584 		case IOCTL_REPLY:
585 		case SET_FLAGS_REPLY:
586 		case SELECT_REPLY:
587 		case DESELECT_REPLY:
588 		case FSYNC_REPLY:
589 		case READ_SYMLINK_REPLY:
590 		case CREATE_SYMLINK_REPLY:
591 		case LINK_REPLY:
592 		case UNLINK_REPLY:
593 		case RENAME_REPLY:
594 		case ACCESS_REPLY:
595 		case READ_STAT_REPLY:
596 		case WRITE_STAT_REPLY:
597 			return false;
598 		// files
599 		case CREATE_REQUEST:
600 		case OPEN_REQUEST:
601 		case CLOSE_REQUEST:
602 		case FREE_COOKIE_REQUEST:
603 		case READ_REQUEST:
604 		case WRITE_REQUEST:
605 			return true;
606 		case CREATE_REPLY:
607 		case OPEN_REPLY:
608 		case CLOSE_REPLY:
609 		case FREE_COOKIE_REPLY:
610 		case READ_REPLY:
611 		case WRITE_REPLY:
612 			return false;
613 		// directories
614 		case CREATE_DIR_REQUEST:
615 		case REMOVE_DIR_REQUEST:
616 		case OPEN_DIR_REQUEST:
617 		case CLOSE_DIR_REQUEST:
618 		case FREE_DIR_COOKIE_REQUEST:
619 		case READ_DIR_REQUEST:
620 		case REWIND_DIR_REQUEST:
621 			return true;
622 		case CREATE_DIR_REPLY:
623 		case REMOVE_DIR_REPLY:
624 		case OPEN_DIR_REPLY:
625 		case CLOSE_DIR_REPLY:
626 		case FREE_DIR_COOKIE_REPLY:
627 		case READ_DIR_REPLY:
628 		case REWIND_DIR_REPLY:
629 			return false;
630 		// attribute directories
631 		case OPEN_ATTR_DIR_REQUEST:
632 		case CLOSE_ATTR_DIR_REQUEST:
633 		case FREE_ATTR_DIR_COOKIE_REQUEST:
634 		case READ_ATTR_DIR_REQUEST:
635 		case REWIND_ATTR_DIR_REQUEST:
636 			return true;
637 		case OPEN_ATTR_DIR_REPLY:
638 		case CLOSE_ATTR_DIR_REPLY:
639 		case FREE_ATTR_DIR_COOKIE_REPLY:
640 		case READ_ATTR_DIR_REPLY:
641 		case REWIND_ATTR_DIR_REPLY:
642 			return false;
643 		// attributes
644 		case CREATE_ATTR_REQUEST:
645 		case OPEN_ATTR_REQUEST:
646 		case CLOSE_ATTR_REQUEST:
647 		case FREE_ATTR_COOKIE_REQUEST:
648 		case READ_ATTR_REQUEST:
649 		case WRITE_ATTR_REQUEST:
650 		case READ_ATTR_STAT_REQUEST:
651 		case WRITE_ATTR_STAT_REQUEST:
652 		case RENAME_ATTR_REQUEST:
653 		case REMOVE_ATTR_REQUEST:
654 			return true;
655 		case CREATE_ATTR_REPLY:
656 		case OPEN_ATTR_REPLY:
657 		case CLOSE_ATTR_REPLY:
658 		case FREE_ATTR_COOKIE_REPLY:
659 		case READ_ATTR_REPLY:
660 		case WRITE_ATTR_REPLY:
661 		case READ_ATTR_STAT_REPLY:
662 		case WRITE_ATTR_STAT_REPLY:
663 		case RENAME_ATTR_REPLY:
664 		case REMOVE_ATTR_REPLY:
665 			return false;
666 		// indices
667 		case OPEN_INDEX_DIR_REQUEST:
668 		case CLOSE_INDEX_DIR_REQUEST:
669 		case FREE_INDEX_DIR_COOKIE_REQUEST:
670 		case READ_INDEX_DIR_REQUEST:
671 		case REWIND_INDEX_DIR_REQUEST:
672 		case CREATE_INDEX_REQUEST:
673 		case REMOVE_INDEX_REQUEST:
674 		case READ_INDEX_STAT_REQUEST:
675 			return true;
676 		case OPEN_INDEX_DIR_REPLY:
677 		case CLOSE_INDEX_DIR_REPLY:
678 		case FREE_INDEX_DIR_COOKIE_REPLY:
679 		case READ_INDEX_DIR_REPLY:
680 		case REWIND_INDEX_DIR_REPLY:
681 		case CREATE_INDEX_REPLY:
682 		case REMOVE_INDEX_REPLY:
683 		case READ_INDEX_STAT_REPLY:
684 			return false;
685 		// queries
686 		case OPEN_QUERY_REQUEST:
687 		case CLOSE_QUERY_REQUEST:
688 		case FREE_QUERY_COOKIE_REQUEST:
689 		case READ_QUERY_REQUEST:
690 		case REWIND_QUERY_REQUEST:
691 			return true;
692 		case OPEN_QUERY_REPLY:
693 		case CLOSE_QUERY_REPLY:
694 		case FREE_QUERY_COOKIE_REPLY:
695 		case READ_QUERY_REPLY:
696 		case REWIND_QUERY_REPLY:
697 			return false;
698 		// node monitoring
699 		case NODE_MONITORING_EVENT_REQUEST:
700 			return true;
701 		case NODE_MONITORING_EVENT_REPLY:
702 			return false;
703 
704 		// userland -> kernel requests
705 		// notifications
706 		case NOTIFY_LISTENER_REQUEST:
707 		case NOTIFY_SELECT_EVENT_REQUEST:
708 		case NOTIFY_QUERY_REQUEST:
709 			return false;
710 		case NOTIFY_LISTENER_REPLY:
711 		case NOTIFY_SELECT_EVENT_REPLY:
712 		case NOTIFY_QUERY_REPLY:
713 			return true;
714 		// vnodes
715 		case GET_VNODE_REQUEST:
716 		case PUT_VNODE_REQUEST:
717 		case ACQUIRE_VNODE_REQUEST:
718 		case NEW_VNODE_REQUEST:
719 		case PUBLISH_VNODE_REQUEST:
720 		case REMOVE_VNODE_REQUEST:
721 		case UNREMOVE_VNODE_REQUEST:
722 		case GET_VNODE_REMOVED_REQUEST:
723 			return false;
724 		case GET_VNODE_REPLY:
725 		case PUT_VNODE_REPLY:
726 		case ACQUIRE_VNODE_REPLY:
727 		case NEW_VNODE_REPLY:
728 		case PUBLISH_VNODE_REPLY:
729 		case REMOVE_VNODE_REPLY:
730 		case UNREMOVE_VNODE_REPLY:
731 		case GET_VNODE_REMOVED_REPLY:
732 			return true;
733 		// file cache
734 		case FILE_CACHE_CREATE_REQUEST:
735 		case FILE_CACHE_DELETE_REQUEST:
736 		case FILE_CACHE_SET_ENABLED_REQUEST:
737 		case FILE_CACHE_SET_SIZE_REQUEST:
738 		case FILE_CACHE_SYNC_REQUEST:
739 		case FILE_CACHE_READ_REQUEST:
740 		case FILE_CACHE_WRITE_REQUEST:
741 			return false;
742 		case FILE_CACHE_CREATE_REPLY:
743 		case FILE_CACHE_DELETE_REPLY:
744 		case FILE_CACHE_SET_ENABLED_REPLY:
745 		case FILE_CACHE_SET_SIZE_REPLY:
746 		case FILE_CACHE_SYNC_REPLY:
747 		case FILE_CACHE_READ_REPLY:
748 		case FILE_CACHE_WRITE_REPLY:
749 			return true;
750 		// I/O
751 		case DO_ITERATIVE_FD_IO_REQUEST:
752 		case READ_FROM_IO_REQUEST_REQUEST:
753 		case WRITE_TO_IO_REQUEST_REQUEST:
754 		case NOTIFY_IO_REQUEST_REQUEST:
755 			return false;
756 		case DO_ITERATIVE_FD_IO_REPLY:
757 		case NOTIFY_IO_REQUEST_REPLY:
758 		case READ_FROM_IO_REQUEST_REPLY:
759 		case WRITE_TO_IO_REQUEST_REPLY:
760 			return true;
761 		// node monitoring
762 		case ADD_NODE_LISTENER_REQUEST:
763 		case REMOVE_NODE_LISTENER_REQUEST:
764 			return false;
765 		case ADD_NODE_LISTENER_REPLY:
766 		case REMOVE_NODE_LISTENER_REPLY:
767 			return true;
768 
769 		// general reply
770 		case RECEIPT_ACK_REPLY:
771 			return true;
772 		default:
773 			return false;
774 	}
775 }
776 
777 // is_userland_request
778 bool
779 UserlandFSUtil::is_userland_request(uint32 type)
780 {
781 	switch (type) {
782 		// kernel -> userland requests
783 		// administrative
784 		case UFS_DISCONNECT_REQUEST:
785 		case FS_CONNECT_REQUEST:
786 			return false;
787 		case FS_CONNECT_REPLY:
788 			return true;
789 		// FS
790 		case MOUNT_VOLUME_REQUEST:
791 		case UNMOUNT_VOLUME_REQUEST:
792 //		case INITIALIZE_VOLUME_REQUEST:
793 		case SYNC_VOLUME_REQUEST:
794 		case READ_FS_INFO_REQUEST:
795 		case WRITE_FS_INFO_REQUEST:
796 			return false;
797 		case MOUNT_VOLUME_REPLY:
798 		case UNMOUNT_VOLUME_REPLY:
799 //		case INITIALIZE_VOLUME_REPLY:
800 		case SYNC_VOLUME_REPLY:
801 		case READ_FS_INFO_REPLY:
802 		case WRITE_FS_INFO_REPLY:
803 			return true;
804 		// vnodes
805 		case LOOKUP_REQUEST:
806 		case GET_VNODE_NAME_REQUEST:
807 		case READ_VNODE_REQUEST:
808 		case WRITE_VNODE_REQUEST:
809 		case FS_REMOVE_VNODE_REQUEST:
810 			return false;
811 		case LOOKUP_REPLY:
812 		case GET_VNODE_NAME_REPLY:
813 		case READ_VNODE_REPLY:
814 		case WRITE_VNODE_REPLY:
815 		case FS_REMOVE_VNODE_REPLY:
816 			return true;
817 		// asynchronous I/O
818 		case DO_IO_REQUEST:
819 		case CANCEL_IO_REQUEST:
820 		case ITERATIVE_IO_GET_VECS_REQUEST:
821 		case ITERATIVE_IO_FINISHED_REQUEST:
822 			return false;
823 		case DO_IO_REPLY:
824 		case CANCEL_IO_REPLY:
825 		case ITERATIVE_IO_GET_VECS_REPLY:
826 		case ITERATIVE_IO_FINISHED_REPLY:
827 			return true;
828 		// nodes
829 		case IOCTL_REQUEST:
830 		case SET_FLAGS_REQUEST:
831 		case SELECT_REQUEST:
832 		case DESELECT_REQUEST:
833 		case FSYNC_REQUEST:
834 		case READ_SYMLINK_REQUEST:
835 		case CREATE_SYMLINK_REQUEST:
836 		case LINK_REQUEST:
837 		case UNLINK_REQUEST:
838 		case RENAME_REQUEST:
839 		case ACCESS_REQUEST:
840 		case READ_STAT_REQUEST:
841 		case WRITE_STAT_REQUEST:
842 			return false;
843 		case IOCTL_REPLY:
844 		case SET_FLAGS_REPLY:
845 		case SELECT_REPLY:
846 		case DESELECT_REPLY:
847 		case FSYNC_REPLY:
848 		case READ_SYMLINK_REPLY:
849 		case CREATE_SYMLINK_REPLY:
850 		case LINK_REPLY:
851 		case UNLINK_REPLY:
852 		case RENAME_REPLY:
853 		case ACCESS_REPLY:
854 		case READ_STAT_REPLY:
855 		case WRITE_STAT_REPLY:
856 			return true;
857 		// files
858 		case CREATE_REQUEST:
859 		case OPEN_REQUEST:
860 		case CLOSE_REQUEST:
861 		case FREE_COOKIE_REQUEST:
862 		case READ_REQUEST:
863 		case WRITE_REQUEST:
864 			return false;
865 		case CREATE_REPLY:
866 		case OPEN_REPLY:
867 		case CLOSE_REPLY:
868 		case FREE_COOKIE_REPLY:
869 		case READ_REPLY:
870 		case WRITE_REPLY:
871 			return true;
872 		// directories
873 		case CREATE_DIR_REQUEST:
874 		case REMOVE_DIR_REQUEST:
875 		case OPEN_DIR_REQUEST:
876 		case CLOSE_DIR_REQUEST:
877 		case FREE_DIR_COOKIE_REQUEST:
878 		case READ_DIR_REQUEST:
879 		case REWIND_DIR_REQUEST:
880 			return false;
881 		case CREATE_DIR_REPLY:
882 		case REMOVE_DIR_REPLY:
883 		case OPEN_DIR_REPLY:
884 		case CLOSE_DIR_REPLY:
885 		case FREE_DIR_COOKIE_REPLY:
886 		case READ_DIR_REPLY:
887 		case REWIND_DIR_REPLY:
888 			return true;
889 		// attribute directories
890 		case OPEN_ATTR_DIR_REQUEST:
891 		case CLOSE_ATTR_DIR_REQUEST:
892 		case FREE_ATTR_DIR_COOKIE_REQUEST:
893 		case READ_ATTR_DIR_REQUEST:
894 		case REWIND_ATTR_DIR_REQUEST:
895 			return false;
896 		case OPEN_ATTR_DIR_REPLY:
897 		case CLOSE_ATTR_DIR_REPLY:
898 		case FREE_ATTR_DIR_COOKIE_REPLY:
899 		case READ_ATTR_DIR_REPLY:
900 		case REWIND_ATTR_DIR_REPLY:
901 			return true;
902 		// attributes
903 		case CREATE_ATTR_REQUEST:
904 		case OPEN_ATTR_REQUEST:
905 		case CLOSE_ATTR_REQUEST:
906 		case FREE_ATTR_COOKIE_REQUEST:
907 		case READ_ATTR_REQUEST:
908 		case WRITE_ATTR_REQUEST:
909 		case RENAME_ATTR_REQUEST:
910 		case READ_ATTR_STAT_REQUEST:
911 		case WRITE_ATTR_STAT_REQUEST:
912 		case REMOVE_ATTR_REQUEST:
913 			return false;
914 		case CREATE_ATTR_REPLY:
915 		case OPEN_ATTR_REPLY:
916 		case CLOSE_ATTR_REPLY:
917 		case FREE_ATTR_COOKIE_REPLY:
918 		case READ_ATTR_REPLY:
919 		case WRITE_ATTR_REPLY:
920 		case READ_ATTR_STAT_REPLY:
921 		case WRITE_ATTR_STAT_REPLY:
922 		case RENAME_ATTR_REPLY:
923 		case REMOVE_ATTR_REPLY:
924 			return true;
925 		// indices
926 		case OPEN_INDEX_DIR_REQUEST:
927 		case CLOSE_INDEX_DIR_REQUEST:
928 		case FREE_INDEX_DIR_COOKIE_REQUEST:
929 		case READ_INDEX_DIR_REQUEST:
930 		case REWIND_INDEX_DIR_REQUEST:
931 		case CREATE_INDEX_REQUEST:
932 		case REMOVE_INDEX_REQUEST:
933 		case READ_INDEX_STAT_REQUEST:
934 			return false;
935 		case OPEN_INDEX_DIR_REPLY:
936 		case CLOSE_INDEX_DIR_REPLY:
937 		case FREE_INDEX_DIR_COOKIE_REPLY:
938 		case READ_INDEX_DIR_REPLY:
939 		case REWIND_INDEX_DIR_REPLY:
940 		case CREATE_INDEX_REPLY:
941 		case REMOVE_INDEX_REPLY:
942 		case READ_INDEX_STAT_REPLY:
943 			return true;
944 		// queries
945 		case OPEN_QUERY_REQUEST:
946 		case CLOSE_QUERY_REQUEST:
947 		case FREE_QUERY_COOKIE_REQUEST:
948 		case READ_QUERY_REQUEST:
949 		case REWIND_QUERY_REQUEST:
950 			return false;
951 		case OPEN_QUERY_REPLY:
952 		case CLOSE_QUERY_REPLY:
953 		case FREE_QUERY_COOKIE_REPLY:
954 		case READ_QUERY_REPLY:
955 		case REWIND_QUERY_REPLY:
956 			return true;
957 		// node monitoring
958 		case NODE_MONITORING_EVENT_REQUEST:
959 			return false;
960 		case NODE_MONITORING_EVENT_REPLY:
961 			return true;
962 
963 		// userland -> kernel requests
964 		// notifications
965 		case NOTIFY_LISTENER_REQUEST:
966 		case NOTIFY_SELECT_EVENT_REQUEST:
967 		case NOTIFY_QUERY_REQUEST:
968 			return true;
969 		case NOTIFY_LISTENER_REPLY:
970 		case NOTIFY_SELECT_EVENT_REPLY:
971 		case NOTIFY_QUERY_REPLY:
972 			return false;
973 		// vnodes
974 		case GET_VNODE_REQUEST:
975 		case PUT_VNODE_REQUEST:
976 		case ACQUIRE_VNODE_REQUEST:
977 		case NEW_VNODE_REQUEST:
978 		case PUBLISH_VNODE_REQUEST:
979 		case REMOVE_VNODE_REQUEST:
980 		case UNREMOVE_VNODE_REQUEST:
981 		case GET_VNODE_REMOVED_REQUEST:
982 			return true;
983 		case GET_VNODE_REPLY:
984 		case PUT_VNODE_REPLY:
985 		case ACQUIRE_VNODE_REPLY:
986 		case NEW_VNODE_REPLY:
987 		case PUBLISH_VNODE_REPLY:
988 		case REMOVE_VNODE_REPLY:
989 		case UNREMOVE_VNODE_REPLY:
990 		case GET_VNODE_REMOVED_REPLY:
991 			return false;
992 		// file cache
993 		case FILE_CACHE_CREATE_REQUEST:
994 		case FILE_CACHE_DELETE_REQUEST:
995 		case FILE_CACHE_SET_ENABLED_REQUEST:
996 		case FILE_CACHE_SET_SIZE_REQUEST:
997 		case FILE_CACHE_SYNC_REQUEST:
998 		case FILE_CACHE_READ_REQUEST:
999 		case FILE_CACHE_WRITE_REQUEST:
1000 			return true;
1001 		case FILE_CACHE_CREATE_REPLY:
1002 		case FILE_CACHE_DELETE_REPLY:
1003 		case FILE_CACHE_SET_ENABLED_REPLY:
1004 		case FILE_CACHE_SET_SIZE_REPLY:
1005 		case FILE_CACHE_SYNC_REPLY:
1006 		case FILE_CACHE_READ_REPLY:
1007 		case FILE_CACHE_WRITE_REPLY:
1008 			return false;
1009 		// I/O
1010 		case DO_ITERATIVE_FD_IO_REQUEST:
1011 		case NOTIFY_IO_REQUEST_REQUEST:
1012 		case READ_FROM_IO_REQUEST_REQUEST:
1013 		case WRITE_TO_IO_REQUEST_REQUEST:
1014 			return true;
1015 		case DO_ITERATIVE_FD_IO_REPLY:
1016 		case NOTIFY_IO_REQUEST_REPLY:
1017 		case READ_FROM_IO_REQUEST_REPLY:
1018 		case WRITE_TO_IO_REQUEST_REPLY:
1019 			return false;
1020 		// node monitoring
1021 		case ADD_NODE_LISTENER_REQUEST:
1022 		case REMOVE_NODE_LISTENER_REQUEST:
1023 			return true;
1024 		case ADD_NODE_LISTENER_REPLY:
1025 		case REMOVE_NODE_LISTENER_REPLY:
1026 			return false;
1027 
1028 		// general reply
1029 		case RECEIPT_ACK_REPLY:
1030 			return true;
1031 		default:
1032 			return false;
1033 	}
1034 }
1035