1use crate::mm::{
6 MappingAccess, MemoryAccessorExt, NumberOfElementsRead, TaskMemoryAccessor, read_to_array,
7 read_to_object_as_bytes, read_to_vec,
8};
9use crate::task::{CurrentTask, Task};
10use smallvec::{SmallVec, smallvec};
11use starnix_types::user_buffer::{UserBuffer, UserBuffers};
12use starnix_uapi::errors::{ENOTSUP, Errno};
13use starnix_uapi::user_address::UserAddress;
14use starnix_uapi::{errno, error};
15use std::mem::MaybeUninit;
16use std::ops::{Deref, DerefMut};
17use zerocopy::FromBytes;
18
19pub type OutputBufferCallback<'a> = dyn FnMut(&mut [MaybeUninit<u8>]) -> Result<usize, Errno> + 'a;
22
23fn slice_to_maybe_uninit(buffer: &[u8]) -> &[MaybeUninit<u8>] {
24 unsafe { std::slice::from_raw_parts(buffer.as_ptr() as *const MaybeUninit<u8>, buffer.len()) }
26}
27
28pub trait Iovec: Sized {
29 fn create(buffer: &UserBuffer) -> Self;
30}
31
32impl Iovec for syncio::zxio::iovec {
33 fn create(buffer: &UserBuffer) -> Self {
34 Self { iov_base: buffer.address.ptr() as *mut starnix_uapi::c_void, iov_len: buffer.length }
35 }
36}
37
38impl Iovec for syncio::zxio::zx_iovec {
39 fn create(buffer: &UserBuffer) -> Self {
40 Self { buffer: buffer.address.ptr() as *mut starnix_uapi::c_void, capacity: buffer.length }
41 }
42}
43
44impl Iovec for zx::sys::zx_iovec_t {
45 fn create(buffer: &UserBuffer) -> Self {
46 Self { buffer: buffer.address.ptr() as *const u8, capacity: buffer.length }
47 }
48}
49
50const IOVECS_IN_HEAP_THRESHOLD: usize = 5;
51
52pub struct IovecsRef<'a, I: Sized> {
54 iovecs: SmallVec<[I; IOVECS_IN_HEAP_THRESHOLD]>,
55 _marker: std::marker::PhantomData<&'a I>,
56}
57
58impl<'a, I: Iovec> IovecsRef<'a, I> {
59 fn new<B: Buffer + ?Sized>(buf: &'a mut B) -> Result<Self, Errno> {
65 let mut iovecs = SmallVec::with_capacity(buf.segments_count()?);
66 buf.peek_each_segment(&mut |buffer| iovecs.push(I::create(buffer)))?;
67 Ok(IovecsRef { iovecs, _marker: Default::default() })
68 }
69}
70
71impl<I> Deref for IovecsRef<'_, I> {
72 type Target = [I];
73 fn deref(&self) -> &Self::Target {
74 &self.iovecs
75 }
76}
77
78impl<I> DerefMut for IovecsRef<'_, I> {
79 fn deref_mut(&mut self) -> &mut Self::Target {
80 &mut self.iovecs
81 }
82}
83
84pub type PeekBufferSegmentsCallback<'a> = dyn FnMut(&UserBuffer) + 'a;
85
86pub trait Buffer: std::fmt::Debug {
90 fn segments_count(&self) -> Result<usize, Errno>;
93
94 fn peek_each_segment(
100 &mut self,
101 callback: &mut PeekBufferSegmentsCallback<'_>,
102 ) -> Result<(), Errno>;
103
104 fn peek_all_segments_as_iovecs(&mut self) -> Result<IovecsRef<'_, syncio::zxio::iovec>, Errno> {
114 IovecsRef::new(self)
115 }
116}
117
118pub fn with_iovec_segments<B: Buffer + ?Sized, I: Iovec, T>(
128 data: &mut B,
129 f: impl FnOnce(&mut [I]) -> Result<T, Errno>,
130) -> Option<Result<T, Errno>> {
131 match IovecsRef::new(data) {
132 Ok(mut o) => Some(f(&mut o)),
133 Err(e) => {
134 if e.code == ENOTSUP {
135 None
136 } else {
137 Some(Err(e))
138 }
139 }
140 }
141}
142
143pub trait OutputBuffer: Buffer {
147 fn write_each(&mut self, callback: &mut OutputBufferCallback<'_>) -> Result<usize, Errno>;
153
154 fn available(&self) -> usize;
156
157 fn bytes_written(&self) -> usize;
159
160 fn zero(&mut self) -> Result<usize, Errno>;
162
163 unsafe fn advance(&mut self, length: usize) -> Result<(), Errno>;
169
170 fn write(&mut self, buffer: &[u8]) -> Result<usize, Errno> {
175 let mut buffer = slice_to_maybe_uninit(buffer);
176
177 self.write_each(&mut move |data| {
178 let size = std::cmp::min(buffer.len(), data.len());
179 let (to_clone, remaining) = buffer.split_at(size);
180 data[0..size].clone_from_slice(to_clone);
181 buffer = remaining;
182 Ok(size)
183 })
184 }
185
186 fn write_all(&mut self, buffer: &[u8]) -> Result<usize, Errno> {
192 let size = self.write(buffer)?;
193 if size != buffer.len() { error!(EINVAL) } else { Ok(size) }
194 }
195
196 fn write_buffer(&mut self, input: &mut dyn InputBuffer) -> Result<usize, Errno> {
202 self.write_each(&mut move |data| {
203 let size = std::cmp::min(data.len(), input.available());
204 input.read_exact(&mut data[0..size])
205 })
206 }
207}
208
209pub type InputBufferCallback<'a> = dyn FnMut(&[u8]) -> Result<usize, Errno> + 'a;
213
214pub trait InputBuffer: Buffer {
218 fn peek_each(&mut self, callback: &mut InputBufferCallback<'_>) -> Result<usize, Errno>;
224
225 fn available(&self) -> usize;
227
228 fn bytes_read(&self) -> usize;
230
231 fn drain(&mut self) -> usize;
234
235 fn advance(&mut self, length: usize) -> Result<(), Errno>;
237
238 fn read_each(&mut self, callback: &mut InputBufferCallback<'_>) -> Result<usize, Errno> {
244 let length = self.peek_each(callback)?;
245 self.advance(length)?;
246 Ok(length)
247 }
248
249 fn read_all(&mut self) -> Result<Vec<u8>, Errno> {
251 let result = self.peek_all()?;
252 let drain_result = self.drain();
253 assert!(result.len() == drain_result);
254 Ok(result)
255 }
256
257 fn peek_all(&mut self) -> Result<Vec<u8>, Errno> {
259 unsafe {
261 read_to_vec::<u8, _>(self.available(), |buf| self.peek(buf).map(NumberOfElementsRead))
262 }
263 }
264
265 fn peek(&mut self, buffer: &mut [MaybeUninit<u8>]) -> Result<usize, Errno> {
271 let mut index = 0;
272 self.peek_each(&mut move |data| {
273 let data = slice_to_maybe_uninit(data);
274 let size = std::cmp::min(buffer.len() - index, data.len());
275 buffer[index..index + size].clone_from_slice(&data[..size]);
276 index += size;
277 Ok(size)
278 })
279 }
280
281 fn read(&mut self, buffer: &mut [MaybeUninit<u8>]) -> Result<usize, Errno> {
287 let length = self.peek(buffer)?;
288 self.advance(length)?;
289 Ok(length)
290 }
291
292 fn read_exact(&mut self, buffer: &mut [MaybeUninit<u8>]) -> Result<usize, Errno> {
298 let size = self.read(buffer)?;
299 if size != buffer.len() { error!(EINVAL) } else { Ok(size) }
300 }
301}
302
303pub trait InputBufferExt: InputBuffer {
304 fn read_to_vec_exact(&mut self, len: usize) -> Result<Vec<u8>, Errno> {
308 unsafe { read_to_vec::<u8, _>(len, |buf| self.read_exact(buf).map(NumberOfElementsRead)) }
310 }
311
312 fn read_to_vec_limited(&mut self, limit: usize) -> Result<Vec<u8>, Errno> {
314 unsafe { read_to_vec::<u8, _>(limit, |buf| self.read(buf).map(NumberOfElementsRead)) }
316 }
317
318 fn read_to_array<const N: usize>(&mut self) -> Result<[u8; N], Errno> {
322 unsafe {
324 read_to_array::<_, _, N>(|buf| {
325 self.read_exact(buf).map(|bytes_read| debug_assert_eq!(bytes_read, buf.len()))
326 })
327 }
328 }
329
330 fn read_to_object<T: FromBytes>(&mut self) -> Result<T, Errno> {
335 unsafe {
338 read_to_object_as_bytes(|buf| {
339 if self.read(buf)? != buf.len() { error!(EINVAL) } else { Ok(()) }
340 })
341 }
342 }
343}
344
345impl InputBufferExt for dyn InputBuffer + '_ {}
346impl<T: InputBuffer> InputBufferExt for T {}
347
348pub struct UserBuffersOutputBuffer<'a, M> {
350 mm: &'a M,
351 buffers: UserBuffers,
352 available: usize,
353 bytes_written: usize,
354}
355
356impl<'a, M> std::fmt::Debug for UserBuffersOutputBuffer<'a, M> {
357 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
358 f.debug_struct("UserBuffersOutputBuffer")
359 .field("buffers", &self.buffers)
360 .field("available", &self.available)
361 .field("bytes_written", &self.bytes_written)
362 .finish()
363 }
364}
365
366impl<'a, M: TaskMemoryAccessor> UserBuffersOutputBuffer<'a, M> {
367 fn new_inner(mm: &'a M, mut buffers: UserBuffers) -> Result<Self, Errno> {
368 let available = UserBuffer::cap_buffers_to_max_rw_count(
369 mm.maximum_valid_address().ok_or_else(|| errno!(EINVAL))?,
370 &mut buffers,
371 )?;
372 buffers.reverse();
374 Ok(Self { mm, buffers, available, bytes_written: 0 })
375 }
376
377 fn write_each_inner<B: AsRef<[u8]>, F: FnMut(usize) -> Result<B, Errno>>(
378 &mut self,
379 mut callback: F,
380 ) -> Result<usize, Errno> {
381 let mut bytes_written = 0;
382 while let Some(mut buffer) = self.buffers.pop() {
383 if buffer.is_null() {
384 continue;
385 }
386
387 let bytes = callback(buffer.length)?;
388 let bytes = bytes.as_ref();
389
390 bytes_written += self.mm.write_memory(buffer.address, bytes)?;
391 let bytes_len = bytes.len();
392 buffer.advance(bytes_len)?;
393 self.available -= bytes_len;
394 self.bytes_written += bytes_len;
395 if !buffer.is_empty() {
396 self.buffers.push(buffer);
397 break;
398 }
399 }
400 Ok(bytes_written)
401 }
402}
403
404impl<'a> UserBuffersOutputBuffer<'a, CurrentTask> {
405 pub fn unified_new(task: &'a CurrentTask, buffers: UserBuffers) -> Result<Self, Errno> {
406 Self::new_inner(task, buffers)
407 }
408
409 pub fn unified_new_at(
410 task: &'a CurrentTask,
411 address: UserAddress,
412 length: usize,
413 ) -> Result<Self, Errno> {
414 Self::unified_new(task, smallvec![UserBuffer { address, length }])
415 }
416}
417
418impl<'a> UserBuffersOutputBuffer<'a, Task> {
419 pub fn syscall_new(task: &'a Task, buffers: UserBuffers) -> Result<Self, Errno> {
420 Self::new_inner(task, buffers)
421 }
422}
423
424impl<'a, M: TaskMemoryAccessor> Buffer for UserBuffersOutputBuffer<'a, M> {
425 fn segments_count(&self) -> Result<usize, Errno> {
426 Ok(self.buffers.len())
427 }
428
429 fn peek_each_segment(
430 &mut self,
431 callback: &mut PeekBufferSegmentsCallback<'_>,
432 ) -> Result<(), Errno> {
433 self.mm.ensure_buffers_mapped_in_user_vmar(&self.buffers, MappingAccess::ForWriting)?;
445 for buffer in self.buffers.iter().rev() {
446 if buffer.is_null() {
447 continue;
448 }
449 callback(buffer)
450 }
451
452 Ok(())
453 }
454}
455
456impl<'a, M: TaskMemoryAccessor> OutputBuffer for UserBuffersOutputBuffer<'a, M> {
457 fn write(&mut self, mut bytes: &[u8]) -> Result<usize, Errno> {
458 let mut bytes_written = 0;
459 for buffer in self.buffers.iter().rev() {
460 if buffer.is_empty() {
461 continue;
462 }
463 if bytes.is_empty() {
464 break;
465 }
466 let len = std::cmp::min(buffer.length, bytes.len());
467 let (to_write, remaining) = bytes.split_at(len);
468 bytes_written += self.mm.write_memory(buffer.address, to_write)?;
469 bytes = remaining;
470 if len != buffer.length {
471 break;
472 }
473 }
474 unsafe {
476 self.advance(bytes_written)?;
477 }
478 Ok(bytes_written)
479 }
480
481 fn write_each(&mut self, callback: &mut OutputBufferCallback<'_>) -> Result<usize, Errno> {
482 self.write_each_inner(|buflen| {
483 unsafe {
485 read_to_vec::<u8, _>(buflen, |buf| {
486 let result = callback(buf)?;
487 if result > buflen {
488 return error!(EINVAL);
489 }
490 Ok(NumberOfElementsRead(result))
491 })
492 }
493 })
494 }
495
496 fn available(&self) -> usize {
497 self.available
498 }
499
500 fn bytes_written(&self) -> usize {
501 self.bytes_written
502 }
503
504 fn zero(&mut self) -> Result<usize, Errno> {
505 let mut bytes_written = 0;
506 while let Some(mut buffer) = self.buffers.pop() {
507 if buffer.is_null() {
508 continue;
509 }
510
511 let count = self.mm.zero(buffer.address, buffer.length)?;
512 buffer.advance(count)?;
513 bytes_written += count;
514
515 self.available -= count;
516 self.bytes_written += count;
517
518 if !buffer.is_empty() {
519 self.buffers.push(buffer);
520 break;
521 }
522 }
523
524 Ok(bytes_written)
525 }
526
527 unsafe fn advance(&mut self, mut length: usize) -> Result<(), Errno> {
528 if length > self.available() {
529 return error!(EINVAL);
530 }
531
532 while let Some(mut buffer) = self.buffers.pop() {
533 if buffer.is_null() {
534 continue;
535 }
536
537 let advance_by = std::cmp::min(length, buffer.length);
538 buffer.advance(advance_by)?;
539 self.available -= advance_by;
540 self.bytes_written += advance_by;
541 if !buffer.is_empty() {
542 self.buffers.push(buffer);
543 break;
544 }
545 length -= advance_by;
546 }
547
548 Ok(())
549 }
550}
551
552pub struct UserBuffersInputBuffer<'a, M> {
554 mm: &'a M,
555 buffers: UserBuffers,
556 available: usize,
557 bytes_read: usize,
558}
559
560impl<'a, M> std::fmt::Debug for UserBuffersInputBuffer<'a, M> {
561 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
562 f.debug_struct("UserBuffersInputBuffer")
563 .field("buffers", &self.buffers)
564 .field("available", &self.available)
565 .field("bytes_read", &self.bytes_read)
566 .finish()
567 }
568}
569
570impl<'a, M: TaskMemoryAccessor> UserBuffersInputBuffer<'a, M> {
571 fn new_inner(mm: &'a M, mut buffers: UserBuffers) -> Result<Self, Errno> {
572 let available = UserBuffer::cap_buffers_to_max_rw_count(
573 mm.maximum_valid_address().ok_or_else(|| errno!(EINVAL))?,
574 &mut buffers,
575 )?;
576 buffers.reverse();
578 Ok(Self { mm, buffers, available, bytes_read: 0 })
579 }
580
581 fn peek_each_inner<F: FnMut(&UserBuffer, usize) -> Result<usize, Errno>>(
582 &mut self,
583 mut callback: F,
584 ) -> Result<usize, Errno> {
585 let mut read = 0;
586 for buffer in self.buffers.iter().rev() {
587 if buffer.is_null() {
588 continue;
589 }
590
591 let result = callback(buffer, read)?;
592 if result > buffer.length {
593 return error!(EINVAL);
594 }
595 read += result;
596 if result != buffer.length {
597 break;
598 }
599 }
600 Ok(read)
601 }
602}
603
604impl<'a> UserBuffersInputBuffer<'a, CurrentTask> {
605 pub fn unified_new(task: &'a CurrentTask, buffers: UserBuffers) -> Result<Self, Errno> {
606 Self::new_inner(task, buffers)
607 }
608
609 pub fn unified_new_at(
610 task: &'a CurrentTask,
611 address: UserAddress,
612 length: usize,
613 ) -> Result<Self, Errno> {
614 Self::unified_new(task, smallvec![UserBuffer { address, length }])
615 }
616}
617
618impl<'a> UserBuffersInputBuffer<'a, Task> {
619 pub fn syscall_new(task: &'a Task, buffers: UserBuffers) -> Result<Self, Errno> {
620 Self::new_inner(task, buffers)
621 }
622}
623
624impl<'a, M: TaskMemoryAccessor> Buffer for UserBuffersInputBuffer<'a, M> {
625 fn segments_count(&self) -> Result<usize, Errno> {
626 Ok(self.buffers.iter().filter(|b| b.is_null()).count())
627 }
628
629 fn peek_each_segment(
630 &mut self,
631 callback: &mut PeekBufferSegmentsCallback<'_>,
632 ) -> Result<(), Errno> {
633 self.mm.ensure_buffers_mapped_in_user_vmar(&self.buffers, MappingAccess::ForReading)?;
640 for buffer in self.buffers.iter().rev() {
641 if buffer.is_null() {
642 continue;
643 }
644 callback(buffer)
645 }
646
647 Ok(())
648 }
649}
650
651impl<'a, M: TaskMemoryAccessor> InputBuffer for UserBuffersInputBuffer<'a, M> {
652 fn peek(&mut self, uninit_bytes: &mut [MaybeUninit<u8>]) -> Result<usize, Errno> {
653 self.peek_each_inner(|buffer, read_so_far| {
654 let read_to = &mut uninit_bytes[read_so_far..];
655 let read_count = std::cmp::min(buffer.length, read_to.len());
656 let read_to = &mut read_to[..read_count];
657 let read_bytes = self.mm.read_memory(buffer.address, read_to)?;
658 debug_assert_eq!(read_bytes.len(), read_count);
659 Ok(read_count)
660 })
661 }
662
663 fn peek_each(&mut self, callback: &mut InputBufferCallback<'_>) -> Result<usize, Errno> {
664 const STACK_BUF_LEN: usize = 512;
669 #[repr(C, align(8))]
670 struct AlignedBuf([MaybeUninit<u8>; STACK_BUF_LEN]);
671 let mut stack_buf = AlignedBuf([MaybeUninit::uninit(); STACK_BUF_LEN]);
672 self.peek_each_inner(|buffer, _read_so_far| {
673 if buffer.length <= STACK_BUF_LEN {
674 let bytes =
675 self.mm.read_memory(buffer.address, &mut stack_buf.0[..buffer.length])?;
676 callback(bytes)
677 } else {
678 let bytes = self.mm.read_memory_to_vec(buffer.address, buffer.length)?;
679 callback(&bytes)
680 }
681 })
682 }
683
684 fn drain(&mut self) -> usize {
685 let result = self.available;
686 self.bytes_read += self.available;
687 self.available = 0;
688 self.buffers.clear();
689 result
690 }
691
692 fn advance(&mut self, mut length: usize) -> Result<(), Errno> {
693 if length > self.available {
694 return error!(EINVAL);
695 }
696 self.available -= length;
697 self.bytes_read += length;
698 while let Some(mut buffer) = self.buffers.pop() {
699 if length < buffer.length {
700 buffer.advance(length)?;
701 self.buffers.push(buffer);
702 return Ok(());
703 }
704 length -= buffer.length;
705 if length == 0 {
706 return Ok(());
707 }
708 }
709 if length != 0 { error!(EINVAL) } else { Ok(()) }
710 }
711
712 fn available(&self) -> usize {
713 self.available
714 }
715 fn bytes_read(&self) -> usize {
716 self.bytes_read
717 }
718}
719
720#[derive(Debug)]
722pub struct VecOutputBuffer {
723 buffer: Vec<u8>,
724 capacity: usize,
728}
729
730impl VecOutputBuffer {
731 pub fn new(capacity: usize) -> Self {
732 Self { buffer: Vec::with_capacity(capacity), capacity }
733 }
734
735 pub fn data(&self) -> &[u8] {
736 &self.buffer
737 }
738
739 pub fn reset(&mut self) {
740 self.buffer.clear()
741 }
742}
743
744impl From<VecOutputBuffer> for Vec<u8> {
745 fn from(data: VecOutputBuffer) -> Self {
746 data.buffer
747 }
748}
749
750impl Buffer for VecOutputBuffer {
751 fn segments_count(&self) -> Result<usize, Errno> {
752 Ok(1)
753 }
754
755 fn peek_each_segment(
756 &mut self,
757 callback: &mut PeekBufferSegmentsCallback<'_>,
758 ) -> Result<(), Errno> {
759 let current_len = self.buffer.len();
760 let buffer = &mut self.buffer.spare_capacity_mut()[..self.capacity - current_len];
761 callback(&UserBuffer {
762 address: UserAddress::from(buffer.as_mut_ptr() as u64),
763 length: buffer.len(),
764 });
765
766 Ok(())
767 }
768}
769
770impl OutputBuffer for VecOutputBuffer {
771 fn write_each(&mut self, callback: &mut OutputBufferCallback<'_>) -> Result<usize, Errno> {
772 let current_len = self.buffer.len();
773 let written =
774 callback(&mut self.buffer.spare_capacity_mut()[..self.capacity - current_len])?;
775 if current_len + written > self.capacity {
776 return error!(EINVAL);
777 }
778 unsafe { self.buffer.set_len(current_len + written) }
780 Ok(written)
781 }
782
783 fn available(&self) -> usize {
784 self.capacity - self.buffer.len()
785 }
786
787 fn bytes_written(&self) -> usize {
788 self.buffer.len()
789 }
790
791 fn zero(&mut self) -> Result<usize, Errno> {
792 let zeroed = self.capacity - self.buffer.len();
793 self.buffer.resize(self.capacity, 0);
794 Ok(zeroed)
795 }
796
797 unsafe fn advance(&mut self, length: usize) -> Result<(), Errno> {
798 if length > self.available() {
799 return error!(EINVAL);
800 }
801
802 let current_len = self.buffer.len();
803 unsafe { self.buffer.set_len(current_len + length) };
807 Ok(())
808 }
809}
810
811#[derive(Debug)]
813pub struct VecInputBuffer {
814 buffer: Vec<u8>,
815
816 bytes_read: usize,
818}
819
820impl VecInputBuffer {
821 pub fn new(buffer: &[u8]) -> Self {
822 Self { buffer: buffer.to_vec(), bytes_read: 0 }
823 }
824}
825
826impl From<Vec<u8>> for VecInputBuffer {
827 fn from(buffer: Vec<u8>) -> Self {
828 Self { buffer, bytes_read: 0 }
829 }
830}
831
832impl Buffer for VecInputBuffer {
833 fn segments_count(&self) -> Result<usize, Errno> {
834 Ok(1)
835 }
836
837 fn peek_each_segment(
838 &mut self,
839 callback: &mut PeekBufferSegmentsCallback<'_>,
840 ) -> Result<(), Errno> {
841 let buffer = &self.buffer[self.bytes_read..];
842 callback(&UserBuffer {
843 address: UserAddress::from(buffer.as_ptr() as u64),
844 length: buffer.len(),
845 });
846
847 Ok(())
848 }
849}
850
851impl InputBuffer for VecInputBuffer {
852 fn peek_each(&mut self, callback: &mut InputBufferCallback<'_>) -> Result<usize, Errno> {
853 let read = callback(&self.buffer[self.bytes_read..])?;
854 if self.bytes_read + read > self.buffer.len() {
855 return error!(EINVAL);
856 }
857 debug_assert!(self.bytes_read <= self.buffer.len());
858 Ok(read)
859 }
860 fn advance(&mut self, length: usize) -> Result<(), Errno> {
861 if length > self.buffer.len() {
862 return error!(EINVAL);
863 }
864 self.bytes_read += length;
865 debug_assert!(self.bytes_read <= self.buffer.len());
866 Ok(())
867 }
868 fn available(&self) -> usize {
869 self.buffer.len() - self.bytes_read
870 }
871 fn bytes_read(&self) -> usize {
872 self.bytes_read
873 }
874 fn drain(&mut self) -> usize {
875 let result = self.available();
876 self.bytes_read += result;
877 result
878 }
879}
880
881impl VecInputBuffer {
882 pub fn read_object<T: FromBytes>(&mut self) -> Result<T, Errno> {
886 let size = std::mem::size_of::<T>();
887 let end = self.bytes_read + size;
888 if end > self.buffer.len() {
889 return error!(EINVAL);
890 }
891 let obj =
892 T::read_from_bytes(&self.buffer[self.bytes_read..end]).map_err(|_| errno!(EINVAL))?;
893 self.bytes_read = end;
894 debug_assert!(self.bytes_read <= self.buffer.len());
895 Ok(obj)
896 }
897}
898
899#[cfg(test)]
900mod tests {
901 use super::*;
902 use crate::mm::{MemoryAccessor as _, PAGE_SIZE};
903 use crate::testing::*;
904 use usercopy::slice_to_maybe_uninit_mut;
905
906 #[test]
907 fn test_data_input_buffer() {
908 let mut executor = fuchsia_async::TestExecutor::new();
909 executor.run_singlethreaded(async {
910 spawn_kernel_and_run(async |current_task| {
911 let page_size = *PAGE_SIZE;
912 let addr = map_memory(¤t_task, UserAddress::default(), 64 * page_size);
913
914 let data: Vec<u8> = (0..1024).map(|i| (i % 256) as u8).collect();
915 let mm = current_task.deref();
916 mm.write_memory(addr, &data).expect("failed to write test data");
917
918 let input_iovec = smallvec![
919 UserBuffer { address: addr, length: 25 },
920 UserBuffer {
921 address: (addr + 64usize).expect("Memory mapped OOB!"),
922 length: 12
923 },
924 ];
925
926 {
928 let mut input_buffer =
929 UserBuffersInputBuffer::unified_new(¤t_task, input_iovec.clone())
930 .expect("UserBuffersInputBuffer");
931 assert!(input_buffer.peek_each(&mut |data| Ok(data.len() + 1)).is_err());
932 }
933
934 {
936 let mut input_buffer =
937 UserBuffersInputBuffer::unified_new(¤t_task, input_iovec.clone())
938 .expect("UserBuffersInputBuffer");
939 assert_eq!(input_buffer.available(), 37);
940 assert_eq!(input_buffer.bytes_read(), 0);
941 assert_eq!(input_buffer.drain(), 37);
942 assert_eq!(input_buffer.available(), 0);
943 assert_eq!(input_buffer.bytes_read(), 37);
944 }
945
946 {
948 let mut input_buffer =
949 UserBuffersInputBuffer::unified_new(¤t_task, input_iovec.clone())
950 .expect("UserBuffersInputBuffer");
951 assert_eq!(input_buffer.available(), 37);
952 assert_eq!(input_buffer.bytes_read(), 0);
953 let buffer = input_buffer.read_all().expect("read_all");
954 assert_eq!(input_buffer.available(), 0);
955 assert_eq!(input_buffer.bytes_read(), 37);
956 assert_eq!(buffer.len(), 37);
957 assert_eq!(&data[..25], &buffer[..25]);
958 assert_eq!(&data[64..76], &buffer[25..37]);
959 }
960
961 {
963 let mut input_buffer =
964 UserBuffersInputBuffer::unified_new(¤t_task, input_iovec)
965 .expect("UserBuffersInputBuffer");
966 let mut buffer = [0; 50];
967 assert_eq!(input_buffer.available(), 37);
968 assert_eq!(input_buffer.bytes_read(), 0);
969 assert_eq!(
970 input_buffer
971 .read_exact(slice_to_maybe_uninit_mut(&mut buffer[0..20]))
972 .expect("read"),
973 20
974 );
975 assert_eq!(input_buffer.available(), 17);
976 assert_eq!(input_buffer.bytes_read(), 20);
977 assert_eq!(
978 input_buffer
979 .read_exact(slice_to_maybe_uninit_mut(&mut buffer[20..37]))
980 .expect("read"),
981 17
982 );
983 assert!(
984 input_buffer
985 .read_exact(slice_to_maybe_uninit_mut(&mut buffer[37..]))
986 .is_err()
987 );
988 assert_eq!(input_buffer.available(), 0);
989 assert_eq!(input_buffer.bytes_read(), 37);
990 assert_eq!(&data[..25], &buffer[..25]);
991 assert_eq!(&data[64..76], &buffer[25..37]);
992 }
993 })
994 .await;
995 });
996 }
997
998 #[test]
999 fn test_data_output_buffer() {
1000 let mut executor = fuchsia_async::TestExecutor::new();
1001 executor.run_singlethreaded(async {
1002 spawn_kernel_and_run(async |current_task| {
1003 let page_size = *PAGE_SIZE;
1004 let addr = map_memory(¤t_task, UserAddress::default(), 64 * page_size);
1005
1006 let output_iovec = smallvec![
1007 UserBuffer { address: addr, length: 25 },
1008 UserBuffer {
1009 address: (addr + 64usize).expect("Memory was mapped OOB!"),
1010 length: 12
1011 },
1012 ];
1013
1014 let _mm = current_task.deref();
1015 let data: Vec<u8> = (0..1024).map(|i| (i % 256) as u8).collect();
1016
1017 {
1019 let mut output_buffer =
1020 UserBuffersOutputBuffer::unified_new(¤t_task, output_iovec.clone())
1021 .expect("UserBuffersOutputBuffer");
1022 assert!(output_buffer.write_each(&mut |data| Ok(data.len() + 1)).is_err());
1023 }
1024
1025 {
1027 let mut output_buffer =
1028 UserBuffersOutputBuffer::unified_new(¤t_task, output_iovec)
1029 .expect("UserBuffersOutputBuffer");
1030 assert_eq!(output_buffer.available(), 37);
1031 assert_eq!(output_buffer.bytes_written(), 0);
1032 assert_eq!(output_buffer.write_all(&data[0..20]).expect("write"), 20);
1033 assert_eq!(output_buffer.available(), 17);
1034 assert_eq!(output_buffer.bytes_written(), 20);
1035 assert_eq!(output_buffer.write_all(&data[20..37]).expect("write"), 17);
1036 assert_eq!(output_buffer.available(), 0);
1037 assert_eq!(output_buffer.bytes_written(), 37);
1038 assert!(output_buffer.write_all(&data[37..50]).is_err());
1039
1040 let buffer = current_task
1041 .read_memory_to_array::<128>(addr)
1042 .expect("failed to write test data");
1043 assert_eq!(&data[0..25], &buffer[0..25]);
1044 assert_eq!(&data[25..37], &buffer[64..76]);
1045 }
1046 })
1047 .await;
1048 });
1049 }
1050
1051 #[::fuchsia::test]
1052 fn test_vec_input_buffer() {
1053 let mut input_buffer = VecInputBuffer::new(b"helloworld");
1054 assert!(input_buffer.peek_each(&mut |data| Ok(data.len() + 1)).is_err());
1055
1056 let mut input_buffer = VecInputBuffer::new(b"helloworld");
1057 assert_eq!(input_buffer.bytes_read(), 0);
1058 assert_eq!(input_buffer.available(), 10);
1059 assert_eq!(input_buffer.drain(), 10);
1060 assert_eq!(input_buffer.bytes_read(), 10);
1061 assert_eq!(input_buffer.available(), 0);
1062
1063 let mut input_buffer = VecInputBuffer::new(b"helloworld");
1064 assert_eq!(input_buffer.bytes_read(), 0);
1065 assert_eq!(input_buffer.available(), 10);
1066 assert_eq!(&input_buffer.read_all().expect("read_all"), b"helloworld");
1067 assert_eq!(input_buffer.bytes_read(), 10);
1068 assert_eq!(input_buffer.available(), 0);
1069
1070 let mut input_buffer = VecInputBuffer::new(b"helloworld");
1071 let mut buffer = [0; 5];
1072 assert_eq!(
1073 input_buffer.read_exact(slice_to_maybe_uninit_mut(&mut buffer)).expect("read"),
1074 5
1075 );
1076 assert_eq!(input_buffer.bytes_read(), 5);
1077 assert_eq!(input_buffer.available(), 5);
1078 assert_eq!(&buffer, b"hello");
1079 assert_eq!(
1080 input_buffer.read_exact(slice_to_maybe_uninit_mut(&mut buffer)).expect("read"),
1081 5
1082 );
1083 assert_eq!(input_buffer.bytes_read(), 10);
1084 assert_eq!(input_buffer.available(), 0);
1085 assert_eq!(&buffer, b"world");
1086 assert!(input_buffer.read_exact(slice_to_maybe_uninit_mut(&mut buffer)).is_err());
1087
1088 let mut input_buffer = VecInputBuffer::new(b"hello");
1090 assert_eq!(input_buffer.bytes_read(), 0);
1091 let buffer: [u8; 3] = input_buffer.read_object().expect("read_object");
1092 assert_eq!(&buffer, b"hel");
1093 assert_eq!(input_buffer.bytes_read(), 3);
1094 let buffer: [u8; 2] = input_buffer.read_object().expect("read_object");
1095 assert_eq!(&buffer, b"lo");
1096 assert_eq!(input_buffer.bytes_read(), 5);
1097 assert!(input_buffer.read_object::<[u8; 1]>().is_err());
1098 assert_eq!(input_buffer.bytes_read(), 5);
1099
1100 let mut input_buffer = VecInputBuffer::new(b"hello");
1101 assert_eq!(input_buffer.bytes_read(), 0);
1102 assert!(input_buffer.read_object::<[u8; 100]>().is_err());
1103 assert_eq!(input_buffer.bytes_read(), 0);
1104 }
1105
1106 #[::fuchsia::test]
1107 fn test_vec_output_buffer() {
1108 let mut output_buffer = VecOutputBuffer::new(10);
1109 assert!(output_buffer.write_each(&mut |data| Ok(data.len() + 1)).is_err());
1110 assert_eq!(output_buffer.bytes_written(), 0);
1111 assert_eq!(output_buffer.available(), 10);
1112 assert_eq!(output_buffer.write_all(b"hello").expect("write"), 5);
1113 assert_eq!(output_buffer.bytes_written(), 5);
1114 assert_eq!(output_buffer.available(), 5);
1115 assert_eq!(output_buffer.data(), b"hello");
1116 assert_eq!(output_buffer.write_all(b"world").expect("write"), 5);
1117 assert_eq!(output_buffer.bytes_written(), 10);
1118 assert_eq!(output_buffer.available(), 0);
1119 assert_eq!(output_buffer.data(), b"helloworld");
1120 assert!(output_buffer.write_all(b"foo").is_err());
1121 let data: Vec<u8> = output_buffer.into();
1122 assert_eq!(data, b"helloworld".to_vec());
1123 }
1124
1125 #[::fuchsia::test]
1126 fn test_vec_output_buffer_advance_preserves_capacity() {
1127 let mut output_buffer = VecOutputBuffer::new(10);
1128 output_buffer.buffer.spare_capacity_mut()[0].write(b'a');
1129 unsafe { output_buffer.advance(1).expect("advance") };
1131 assert_eq!(output_buffer.bytes_written(), 1);
1132 assert_eq!(output_buffer.available(), 9);
1133 assert_eq!(output_buffer.write_all(b"bcdefghij").expect("write"), 9);
1134 assert_eq!(output_buffer.data(), b"abcdefghij");
1135 }
1136
1137 #[::fuchsia::test]
1138 fn test_vec_write_buffer() {
1139 let mut input_buffer = VecInputBuffer::new(b"helloworld");
1140 let mut output_buffer = VecOutputBuffer::new(20);
1141 assert_eq!(output_buffer.write_buffer(&mut input_buffer).expect("write_buffer"), 10);
1142 assert_eq!(output_buffer.data(), b"helloworld");
1143 }
1144
1145 #[::fuchsia::test]
1146 async fn test_peek_each_segment_maps_lazy_mapping() {
1147 spawn_kernel_and_run(async |current_task| {
1148 let page_size = *PAGE_SIZE;
1149 let length = (2 * page_size) as usize;
1150 let addr = map_memory(¤t_task, UserAddress::default(), 2 * page_size);
1151 let iovecs = smallvec![
1152 UserBuffer { address: addr, length: 25 },
1153 UserBuffer { address: (addr + 64usize).expect("in bounds"), length: 12 },
1154 ];
1155
1156 {
1158 let child_task = current_task.clone_task_for_test(0, None);
1159 let mut input_buffer =
1160 UserBuffersInputBuffer::unified_new(&child_task, iovecs.clone())
1161 .expect("UserBuffersInputBuffer");
1162 let segments = input_buffer
1163 .peek_all_segments_as_iovecs()
1164 .expect("peek_all_segments_as_iovecs");
1165 assert_eq!(segments.len(), 2);
1166 assert!(
1167 !child_task
1168 .mm()
1169 .unwrap()
1170 .ensure_range_mapped_in_user_vmar(addr, Some(length))
1171 .expect("ensure_range_mapped_in_user_vmar")
1172 );
1173 }
1174
1175 {
1176 let child_task = current_task.clone_task_for_test(0, None);
1177 let mut output_buffer = UserBuffersOutputBuffer::unified_new(&child_task, iovecs)
1178 .expect("UserBuffersOutputBuffer");
1179 let segments = output_buffer
1180 .peek_all_segments_as_iovecs()
1181 .expect("peek_all_segments_as_iovecs");
1182 assert_eq!(segments.len(), 2);
1183 assert!(
1184 !child_task
1185 .mm()
1186 .unwrap()
1187 .ensure_range_mapped_in_user_vmar(addr, Some(length))
1188 .expect("ensure_range_mapped_in_user_vmar")
1189 );
1190 }
1191 })
1192 .await;
1193 }
1194}