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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)58 GetVNodeNameReply::GetAddressInfos(AddressInfo* infos, int32* count)
59 {
60 ADD_STRING(buffer);
61 return B_OK;
62 }
63
64 // CreateRequest
65 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)74 ReadReply::GetAddressInfos(AddressInfo* infos, int32* count)
75 {
76 ADD_ADDRESS(buffer);
77 return B_OK;
78 }
79
80 // WriteRequest
81 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)82 WriteRequest::GetAddressInfos(AddressInfo* infos, int32* count)
83 {
84 ADD_ADDRESS(buffer);
85 return B_OK;
86 }
87
88 // IOCtlRequest
89 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)90 IOCtlRequest::GetAddressInfos(AddressInfo* infos, int32* count)
91 {
92 ADD_ADDRESS(buffer);
93 return B_OK;
94 }
95
96 // IOCtlReply
97 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)98 IOCtlReply::GetAddressInfos(AddressInfo* infos, int32* count)
99 {
100 ADD_ADDRESS(buffer);
101 return B_OK;
102 }
103
104 // LinkRequest
105 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)131 ReadSymlinkReply::GetAddressInfos(AddressInfo* infos, int32* count)
132 {
133 ADD_STRING(buffer);
134 return B_OK;
135 }
136
137 // RenameRequest
138 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)164 ReadDirReply::GetAddressInfos(AddressInfo* infos, int32* count)
165 {
166 ADD_ADDRESS(buffer);
167 return B_OK;
168 }
169
170 // LookupRequest
171 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)180 ReadAttrDirReply::GetAddressInfos(AddressInfo* infos, int32* count)
181 {
182 ADD_ADDRESS(buffer);
183 return B_OK;
184 }
185
186 // CreateAttrRequest
187 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)204 ReadAttrReply::GetAddressInfos(AddressInfo* infos, int32* count)
205 {
206 ADD_ADDRESS(buffer);
207 return B_OK;
208 }
209
210 // WriteAttrRequest
211 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)212 WriteAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count)
213 {
214 ADD_ADDRESS(buffer);
215 return B_OK;
216 }
217
218 // RemoveAttrRequest
219 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)237 ReadIndexDirReply::GetAddressInfos(AddressInfo* infos, int32* count)
238 {
239 ADD_ADDRESS(buffer);
240 return B_OK;
241 }
242
243 // CreateIndexRequest
244 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)277 ReadQueryReply::GetAddressInfos(AddressInfo* infos, int32* count)
278 {
279 ADD_ADDRESS(buffer);
280 return B_OK;
281 }
282
283 // NodeMonitoringEventRequest
284 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)285 NodeMonitoringEventRequest::GetAddressInfos(AddressInfo* infos, int32* count)
286 {
287 ADD_ADDRESS(event);
288 return B_OK;
289 }
290
291 // NotifyListenerRequest
292 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)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
GetAddressInfos(AddressInfo * infos,int32 * count)302 NotifyQueryRequest::GetAddressInfos(AddressInfo* infos, int32* count)
303 {
304 ADD_STRING(name);
305 return B_OK;
306 }
307
308 // FileCacheReadReply
309 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)310 FileCacheReadReply::GetAddressInfos(AddressInfo* infos, int32* count)
311 {
312 ADD_ADDRESS(buffer);
313 return B_OK;
314 }
315
316 // FileCacheWriteRequest
317 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)318 FileCacheWriteRequest::GetAddressInfos(AddressInfo* infos, int32* count)
319 {
320 ADD_ADDRESS(buffer);
321 return B_OK;
322 }
323
324 // ReadFromIORequestReply
325 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)326 ReadFromIORequestReply::GetAddressInfos(AddressInfo* infos, int32* count)
327 {
328 ADD_ADDRESS(buffer);
329 return B_OK;
330 }
331
332 // WriteToIORequestRequest
333 status_t
GetAddressInfos(AddressInfo * infos,int32 * count)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 {
RequestAddressInfoGetterRequestAddressInfoGetter345 RequestAddressInfoGetter(AddressInfo* infos, int32* count)
346 : fInfos(infos),
347 fCount(count)
348 {
349 }
350
operator ()RequestAddressInfoGetter351 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
get_request_address_infos(Request * request,AddressInfo * infos,int32 * count)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 {
operator ()RequestChecker375 template<typename R> status_t operator()(R* request)
376 {
377 return request->Check();
378 }
379 };
380
381 // check_request
382 status_t
check_request(Request * request)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
is_error_reply(Request * request)393 is_error_reply(Request* request)
394 {
395 return false;
396 }
397
398 // is_error_reply
399 static inline
400 bool
is_error_reply(ReplyRequest * request)401 is_error_reply(ReplyRequest* request)
402 {
403 return (request->error != B_OK);
404 }
405
406 // RequestRelocator
407 struct RequestRelocator {
RequestRelocatorRequestRelocator408 RequestRelocator(int32 requestBufferSize, area_id* areas, int32* count)
409 : fRequestBufferSize(requestBufferSize),
410 fAreas(areas),
411 fAreaCount(count)
412 {
413 *fAreaCount = 0;
414 }
415
~RequestRelocatorRequestRelocator416 ~RequestRelocator()
417 {
418 if (!fSuccess) {
419 for (int32 i = 0; i < *fAreaCount; i++)
420 delete_area(fAreas[i]);
421 }
422 }
423
operator ()RequestRelocator424 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
relocate_request(Request * request,int32 requestBufferSize,area_id * areas,int32 * count)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
is_kernel_request(uint32 type)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
is_userland_request(uint32 type)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