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
22status_t
23FSConnectRequest::GetAddressInfos(AddressInfo* infos, int32* count)
24{
25	ADD_NON_NULL_STRING(fsName);
26	return B_OK;
27}
28
29// FSConnectReply
30status_t
31FSConnectReply::GetAddressInfos(AddressInfo* infos, int32* count)
32{
33	ADD_NON_NULL_ADDRESS(portInfos);
34	return B_OK;
35}
36
37// MountVolumeRequest
38status_t
39MountVolumeRequest::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
57status_t
58GetVNodeNameReply::GetAddressInfos(AddressInfo* infos, int32* count)
59{
60	ADD_STRING(buffer);
61	return B_OK;
62}
63
64// CreateRequest
65status_t
66CreateRequest::GetAddressInfos(AddressInfo* infos, int32* count)
67{
68	ADD_NON_NULL_STRING(name);
69	return B_OK;
70}
71
72// ReadReply
73status_t
74ReadReply::GetAddressInfos(AddressInfo* infos, int32* count)
75{
76	ADD_ADDRESS(buffer);
77	return B_OK;
78}
79
80// WriteRequest
81status_t
82WriteRequest::GetAddressInfos(AddressInfo* infos, int32* count)
83{
84	ADD_ADDRESS(buffer);
85	return B_OK;
86}
87
88// IOCtlRequest
89status_t
90IOCtlRequest::GetAddressInfos(AddressInfo* infos, int32* count)
91{
92	ADD_ADDRESS(buffer);
93	return B_OK;
94}
95
96// IOCtlReply
97status_t
98IOCtlReply::GetAddressInfos(AddressInfo* infos, int32* count)
99{
100	ADD_ADDRESS(buffer);
101	return B_OK;
102}
103
104// LinkRequest
105status_t
106LinkRequest::GetAddressInfos(AddressInfo* infos, int32* count)
107{
108	ADD_NON_NULL_STRING(name);
109	return B_OK;
110}
111
112// UnlinkRequest
113status_t
114UnlinkRequest::GetAddressInfos(AddressInfo* infos, int32* count)
115{
116	ADD_NON_NULL_STRING(name);
117	return B_OK;
118}
119
120// CreateSymlinkRequest
121status_t
122CreateSymlinkRequest::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
130status_t
131ReadSymlinkReply::GetAddressInfos(AddressInfo* infos, int32* count)
132{
133	ADD_STRING(buffer);
134	return B_OK;
135}
136
137// RenameRequest
138status_t
139RenameRequest::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
147status_t
148CreateDirRequest::GetAddressInfos(AddressInfo* infos, int32* count)
149{
150	ADD_NON_NULL_STRING(name);
151	return B_OK;
152}
153
154// RemoveDirRequest
155status_t
156RemoveDirRequest::GetAddressInfos(AddressInfo* infos, int32* count)
157{
158	ADD_NON_NULL_STRING(name);
159	return B_OK;
160}
161
162// ReadDirReply
163status_t
164ReadDirReply::GetAddressInfos(AddressInfo* infos, int32* count)
165{
166	ADD_ADDRESS(buffer);
167	return B_OK;
168}
169
170// LookupRequest
171status_t
172LookupRequest::GetAddressInfos(AddressInfo* infos, int32* count)
173{
174	ADD_NON_NULL_STRING(entryName);
175	return B_OK;
176}
177
178// ReadAttrDirReply
179status_t
180ReadAttrDirReply::GetAddressInfos(AddressInfo* infos, int32* count)
181{
182	ADD_ADDRESS(buffer);
183	return B_OK;
184}
185
186// CreateAttrRequest
187status_t
188CreateAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
189{
190	ADD_NON_NULL_STRING(name);
191	return B_OK;
192}
193
194// OpenAttrRequest
195status_t
196OpenAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
197{
198	ADD_NON_NULL_STRING(name);
199	return B_OK;
200}
201
202// ReadAttrReply
203status_t
204ReadAttrReply::GetAddressInfos(AddressInfo* infos, int32* count)
205{
206	ADD_ADDRESS(buffer);
207	return B_OK;
208}
209
210// WriteAttrRequest
211status_t
212WriteAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
213{
214	ADD_ADDRESS(buffer);
215	return B_OK;
216}
217
218// RemoveAttrRequest
219status_t
220RemoveAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
221{
222	ADD_NON_NULL_STRING(name);
223	return B_OK;
224}
225
226// RenameAttrRequest
227status_t
228RenameAttrRequest::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
236status_t
237ReadIndexDirReply::GetAddressInfos(AddressInfo* infos, int32* count)
238{
239	ADD_ADDRESS(buffer);
240	return B_OK;
241}
242
243// CreateIndexRequest
244status_t
245CreateIndexRequest::GetAddressInfos(AddressInfo* infos, int32* count)
246{
247	ADD_NON_NULL_STRING(name);
248	return B_OK;
249}
250
251// RemoveIndexRequest
252status_t
253RemoveIndexRequest::GetAddressInfos(AddressInfo* infos, int32* count)
254{
255	ADD_NON_NULL_STRING(name);
256	return B_OK;
257}
258
259// ReadIndexStatRequest
260status_t
261ReadIndexStatRequest::GetAddressInfos(AddressInfo* infos, int32* count)
262{
263	ADD_NON_NULL_STRING(name);
264	return B_OK;
265}
266
267// OpenQueryRequest
268status_t
269OpenQueryRequest::GetAddressInfos(AddressInfo* infos, int32* count)
270{
271	ADD_NON_NULL_STRING(queryString);
272	return B_OK;
273}
274
275// ReadQueryReply
276status_t
277ReadQueryReply::GetAddressInfos(AddressInfo* infos, int32* count)
278{
279	ADD_ADDRESS(buffer);
280	return B_OK;
281}
282
283// NodeMonitoringEventRequest
284status_t
285NodeMonitoringEventRequest::GetAddressInfos(AddressInfo* infos, int32* count)
286{
287	ADD_ADDRESS(event);
288	return B_OK;
289}
290
291// NotifyListenerRequest
292status_t
293NotifyListenerRequest::GetAddressInfos(AddressInfo* infos, int32* count)
294{
295	ADD_STRING(oldName);
296	ADD_STRING(name);
297	return B_OK;
298}
299
300// NotifyQueryRequest
301status_t
302NotifyQueryRequest::GetAddressInfos(AddressInfo* infos, int32* count)
303{
304	ADD_STRING(name);
305	return B_OK;
306}
307
308// FileCacheReadReply
309status_t
310FileCacheReadReply::GetAddressInfos(AddressInfo* infos, int32* count)
311{
312	ADD_ADDRESS(buffer);
313	return B_OK;
314}
315
316// FileCacheWriteRequest
317status_t
318FileCacheWriteRequest::GetAddressInfos(AddressInfo* infos, int32* count)
319{
320	ADD_ADDRESS(buffer);
321	return B_OK;
322}
323
324// ReadFromIORequestReply
325status_t
326ReadFromIORequestReply::GetAddressInfos(AddressInfo* infos, int32* count)
327{
328	ADD_ADDRESS(buffer);
329	return B_OK;
330}
331
332// WriteToIORequestRequest
333status_t
334WriteToIORequestRequest::GetAddressInfos(AddressInfo* infos, int32* count)
335{
336	ADD_ADDRESS(buffer);
337	return B_OK;
338}
339
340
341// #pragma mark -
342
343// RequestAddressInfoGetter
344struct 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
356private:
357	AddressInfo*	fInfos;
358	int32*			fCount;
359};
360
361// get_request_address_infos
362status_t
363UserlandFSUtil::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
374struct RequestChecker {
375	template<typename R> status_t operator()(R* request)
376	{
377		return request->Check();
378	}
379};
380
381// check_request
382status_t
383UserlandFSUtil::check_request(Request* request)
384{
385	RequestChecker task;
386	return do_for_request(request, task);
387}
388
389
390// is_error_reply
391static inline
392bool
393is_error_reply(Request* request)
394{
395	return false;
396}
397
398// is_error_reply
399static inline
400bool
401is_error_reply(ReplyRequest* request)
402{
403	return (request->error != B_OK);
404}
405
406// RequestRelocator
407struct 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
500private:
501	int32		fRequestBufferSize;
502	area_id*	fAreas;
503	int32*		fAreaCount;
504	bool		fSuccess;
505};
506
507// relocate_request
508status_t
509UserlandFSUtil::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
519bool
520UserlandFSUtil::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
778bool
779UserlandFSUtil::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