devices/virtio/
descriptor_utils.rs

1// Copyright 2019 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::cmp;
6use std::io;
7use std::io::Write;
8use std::iter::FromIterator;
9use std::marker::PhantomData;
10use std::mem::size_of;
11use std::mem::MaybeUninit;
12use std::ptr::copy_nonoverlapping;
13use std::sync::Arc;
14
15use anyhow::Context;
16use base::FileReadWriteAtVolatile;
17use base::FileReadWriteVolatile;
18use base::VolatileSlice;
19use cros_async::IoOptions;
20use cros_async::MemRegion;
21use cros_async::MemRegionIter;
22use data_model::Le16;
23use data_model::Le32;
24use data_model::Le64;
25use disk::AsyncDisk;
26use smallvec::SmallVec;
27use vm_memory::GuestAddress;
28use vm_memory::GuestMemory;
29use zerocopy::FromBytes;
30use zerocopy::Immutable;
31use zerocopy::IntoBytes;
32use zerocopy::KnownLayout;
33
34use super::DescriptorChain;
35use crate::virtio::SplitDescriptorChain;
36
37struct DescriptorChainRegions {
38    regions: SmallVec<[MemRegion; 2]>,
39
40    // Index of the current region in `regions`.
41    current_region_index: usize,
42
43    // Number of bytes consumed in the current region.
44    current_region_offset: usize,
45
46    // Total bytes consumed in the entire descriptor chain.
47    bytes_consumed: usize,
48}
49
50impl DescriptorChainRegions {
51    fn new(regions: SmallVec<[MemRegion; 2]>) -> Self {
52        DescriptorChainRegions {
53            regions,
54            current_region_index: 0,
55            current_region_offset: 0,
56            bytes_consumed: 0,
57        }
58    }
59
60    fn available_bytes(&self) -> usize {
61        // This is guaranteed not to overflow because the total length of the chain is checked
62        // during all creations of `DescriptorChain` (see `DescriptorChain::new()`).
63        self.get_remaining_regions()
64            .fold(0usize, |count, region| count + region.len)
65    }
66
67    fn bytes_consumed(&self) -> usize {
68        self.bytes_consumed
69    }
70
71    /// Returns all the remaining buffers in the `DescriptorChain`. Calling this function does not
72    /// consume any bytes from the `DescriptorChain`. Instead callers should use the `consume`
73    /// method to advance the `DescriptorChain`. Multiple calls to `get` with no intervening calls
74    /// to `consume` will return the same data.
75    fn get_remaining_regions(&self) -> MemRegionIter {
76        MemRegionIter::new(&self.regions[self.current_region_index..])
77            .skip_bytes(self.current_region_offset)
78    }
79
80    /// Like `get_remaining_regions` but guarantees that the combined length of all the returned
81    /// iovecs is not greater than `count`. The combined length of the returned iovecs may be less
82    /// than `count` but will always be greater than 0 as long as there is still space left in the
83    /// `DescriptorChain`.
84    fn get_remaining_regions_with_count(&self, count: usize) -> MemRegionIter {
85        MemRegionIter::new(&self.regions[self.current_region_index..])
86            .skip_bytes(self.current_region_offset)
87            .take_bytes(count)
88    }
89
90    /// Returns all the remaining buffers in the `DescriptorChain` as `VolatileSlice`s of the given
91    /// `GuestMemory`. Calling this function does not consume any bytes from the `DescriptorChain`.
92    /// Instead callers should use the `consume` method to advance the `DescriptorChain`. Multiple
93    /// calls to `get` with no intervening calls to `consume` will return the same data.
94    fn get_remaining<'mem>(&self, mem: &'mem GuestMemory) -> SmallVec<[VolatileSlice<'mem>; 16]> {
95        self.get_remaining_regions()
96            .filter_map(|region| {
97                mem.get_slice_at_addr(GuestAddress(region.offset), region.len)
98                    .ok()
99            })
100            .collect()
101    }
102
103    /// Like 'get_remaining_regions_with_count' except convert the offsets to volatile slices in
104    /// the 'GuestMemory' given by 'mem'.
105    fn get_remaining_with_count<'mem>(
106        &self,
107        mem: &'mem GuestMemory,
108        count: usize,
109    ) -> SmallVec<[VolatileSlice<'mem>; 16]> {
110        self.get_remaining_regions_with_count(count)
111            .filter_map(|region| {
112                mem.get_slice_at_addr(GuestAddress(region.offset), region.len)
113                    .ok()
114            })
115            .collect()
116    }
117
118    /// Consumes `count` bytes from the `DescriptorChain`. If `count` is larger than
119    /// `self.available_bytes()` then all remaining bytes in the `DescriptorChain` will be consumed.
120    fn consume(&mut self, mut count: usize) {
121        while let Some(region) = self.regions.get(self.current_region_index) {
122            let region_remaining = region.len - self.current_region_offset;
123            if count < region_remaining {
124                // The remaining count to consume is less than the remaining un-consumed length of
125                // the current region. Adjust the region offset without advancing to the next region
126                // and stop.
127                self.current_region_offset += count;
128                self.bytes_consumed += count;
129                return;
130            }
131
132            // The current region has been exhausted. Advance to the next region.
133            self.current_region_index += 1;
134            self.current_region_offset = 0;
135
136            self.bytes_consumed += region_remaining;
137            count -= region_remaining;
138        }
139    }
140
141    fn split_at(&mut self, offset: usize) -> DescriptorChainRegions {
142        let mut other = DescriptorChainRegions {
143            regions: self.regions.clone(),
144            current_region_index: self.current_region_index,
145            current_region_offset: self.current_region_offset,
146            bytes_consumed: self.bytes_consumed,
147        };
148        other.consume(offset);
149        other.bytes_consumed = 0;
150
151        let mut rem = offset;
152        let mut end = self.current_region_index;
153        for region in &mut self.regions[self.current_region_index..] {
154            if rem <= region.len {
155                region.len = rem;
156                break;
157            }
158
159            end += 1;
160            rem -= region.len;
161        }
162
163        self.regions.truncate(end + 1);
164
165        other
166    }
167}
168
169/// Provides high-level interface over the sequence of memory regions
170/// defined by readable descriptors in the descriptor chain.
171///
172/// Note that virtio spec requires driver to place any device-writable
173/// descriptors after any device-readable descriptors (2.6.4.2 in Virtio Spec v1.1).
174/// Reader will skip iterating over descriptor chain when first writable
175/// descriptor is encountered.
176pub struct Reader {
177    mem: GuestMemory,
178    regions: DescriptorChainRegions,
179}
180
181/// An iterator over `FromBytes` objects on readable descriptors in the descriptor chain.
182pub struct ReaderIterator<'a, T: FromBytes> {
183    reader: &'a mut Reader,
184    phantom: PhantomData<T>,
185}
186
187impl<T: FromBytes> Iterator for ReaderIterator<'_, T> {
188    type Item = io::Result<T>;
189
190    fn next(&mut self) -> Option<io::Result<T>> {
191        if self.reader.available_bytes() == 0 {
192            None
193        } else {
194            Some(self.reader.read_obj())
195        }
196    }
197}
198
199impl Reader {
200    /// Construct a new Reader wrapper over `readable_regions`.
201    pub fn new_from_regions(
202        mem: &GuestMemory,
203        readable_regions: SmallVec<[MemRegion; 2]>,
204    ) -> Reader {
205        Reader {
206            mem: mem.clone(),
207            regions: DescriptorChainRegions::new(readable_regions),
208        }
209    }
210
211    /// Reads an object from the descriptor chain buffer without consuming it.
212    pub fn peek_obj<T: FromBytes>(&self) -> io::Result<T> {
213        let mut obj = MaybeUninit::uninit();
214
215        // SAFETY: We pass a valid pointer and size of `obj`.
216        let copied = unsafe {
217            copy_regions_to_mut_ptr(
218                &self.mem,
219                self.get_remaining_regions(),
220                obj.as_mut_ptr() as *mut u8,
221                size_of::<T>(),
222            )?
223        };
224        if copied != size_of::<T>() {
225            return Err(io::Error::from(io::ErrorKind::UnexpectedEof));
226        }
227
228        // SAFETY: `FromBytes` guarantees any set of initialized bytes is a valid value for `T`, and
229        // we initialized all bytes in `obj` in the copy above.
230        Ok(unsafe { obj.assume_init() })
231    }
232
233    /// Reads and consumes an object from the descriptor chain buffer.
234    pub fn read_obj<T: FromBytes>(&mut self) -> io::Result<T> {
235        let obj = self.peek_obj::<T>()?;
236        self.consume(size_of::<T>());
237        Ok(obj)
238    }
239
240    /// Reads objects by consuming all the remaining data in the descriptor chain buffer and returns
241    /// them as a collection. Returns an error if the size of the remaining data is indivisible by
242    /// the size of an object of type `T`.
243    pub fn collect<C: FromIterator<io::Result<T>>, T: FromBytes>(&mut self) -> C {
244        self.iter().collect()
245    }
246
247    /// Creates an iterator for sequentially reading `FromBytes` objects from the `Reader`.
248    /// Unlike `collect`, this doesn't consume all the remaining data in the `Reader` and
249    /// doesn't require the objects to be stored in a separate collection.
250    pub fn iter<T: FromBytes>(&mut self) -> ReaderIterator<T> {
251        ReaderIterator {
252            reader: self,
253            phantom: PhantomData,
254        }
255    }
256
257    /// Reads data into a volatile slice up to the minimum of the slice's length or the number of
258    /// bytes remaining. Returns the number of bytes read.
259    pub fn read_to_volatile_slice(&mut self, slice: VolatileSlice) -> usize {
260        let mut read = 0usize;
261        let mut dst = slice;
262        for src in self.get_remaining() {
263            src.copy_to_volatile_slice(dst);
264            let copied = std::cmp::min(src.size(), dst.size());
265            read += copied;
266            dst = match dst.offset(copied) {
267                Ok(v) => v,
268                Err(_) => break, // The slice is fully consumed
269            };
270        }
271        self.regions.consume(read);
272        read
273    }
274
275    /// Reads data from the descriptor chain buffer and passes the `VolatileSlice`s to the callback
276    /// `cb`.
277    pub fn read_to_cb<C: FnOnce(&[VolatileSlice]) -> usize>(
278        &mut self,
279        cb: C,
280        count: usize,
281    ) -> usize {
282        let iovs = self.regions.get_remaining_with_count(&self.mem, count);
283        let written = cb(&iovs[..]);
284        self.regions.consume(written);
285        written
286    }
287
288    /// Reads data from the descriptor chain buffer into a writable object.
289    /// Returns the number of bytes read from the descriptor chain buffer.
290    /// The number of bytes read can be less than `count` if there isn't
291    /// enough data in the descriptor chain buffer.
292    pub fn read_to<F: FileReadWriteVolatile>(
293        &mut self,
294        mut dst: F,
295        count: usize,
296    ) -> io::Result<usize> {
297        let iovs = self.regions.get_remaining_with_count(&self.mem, count);
298        let written = dst.write_vectored_volatile(&iovs[..])?;
299        self.regions.consume(written);
300        Ok(written)
301    }
302
303    /// Reads data from the descriptor chain buffer into a File at offset `off`.
304    /// Returns the number of bytes read from the descriptor chain buffer.
305    /// The number of bytes read can be less than `count` if there isn't
306    /// enough data in the descriptor chain buffer.
307    pub fn read_to_at<F: FileReadWriteAtVolatile>(
308        &mut self,
309        dst: &F,
310        count: usize,
311        off: u64,
312    ) -> io::Result<usize> {
313        let iovs = self.regions.get_remaining_with_count(&self.mem, count);
314        let written = dst.write_vectored_at_volatile(&iovs[..], off)?;
315        self.regions.consume(written);
316        Ok(written)
317    }
318
319    /// Reads data from the descriptor chain similar to 'read_to' except reading 'count' or
320    /// returning an error if 'count' bytes can't be read.
321    pub fn read_exact_to<F: FileReadWriteVolatile>(
322        &mut self,
323        mut dst: F,
324        mut count: usize,
325    ) -> io::Result<()> {
326        while count > 0 {
327            match self.read_to(&mut dst, count) {
328                Ok(0) => {
329                    return Err(io::Error::new(
330                        io::ErrorKind::UnexpectedEof,
331                        "failed to fill whole buffer",
332                    ))
333                }
334                Ok(n) => count -= n,
335                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
336                Err(e) => return Err(e),
337            }
338        }
339
340        Ok(())
341    }
342
343    /// Reads data from the descriptor chain similar to 'read_to_at' except reading 'count' or
344    /// returning an error if 'count' bytes can't be read.
345    pub fn read_exact_to_at<F: FileReadWriteAtVolatile>(
346        &mut self,
347        dst: &F,
348        mut count: usize,
349        mut off: u64,
350    ) -> io::Result<()> {
351        while count > 0 {
352            match self.read_to_at(dst, count, off) {
353                Ok(0) => {
354                    return Err(io::Error::new(
355                        io::ErrorKind::UnexpectedEof,
356                        "failed to fill whole buffer",
357                    ))
358                }
359                Ok(n) => {
360                    count -= n;
361                    off += n as u64;
362                }
363                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
364                Err(e) => return Err(e),
365            }
366        }
367
368        Ok(())
369    }
370
371    /// Reads data from the descriptor chain buffer into an `AsyncDisk` at offset `off`.
372    /// Returns the number of bytes read from the descriptor chain buffer.
373    /// The number of bytes read can be less than `count` if there isn't
374    /// enough data in the descriptor chain buffer.
375    pub async fn read_to_at_fut<F: AsyncDisk + ?Sized>(
376        &mut self,
377        dst: &F,
378        count: usize,
379        off: u64,
380        options: IoOptions,
381    ) -> disk::Result<usize> {
382        let written = dst
383            .write_from_mem(
384                off,
385                Arc::new(self.mem.clone()),
386                self.regions.get_remaining_regions_with_count(count),
387                options,
388            )
389            .await?;
390        self.regions.consume(written);
391        Ok(written)
392    }
393
394    /// Reads exactly `count` bytes from the chain to the disk asynchronously or returns an error if
395    /// not enough data can be read.
396    pub async fn read_exact_to_at_fut<F: AsyncDisk + ?Sized>(
397        &mut self,
398        dst: &F,
399        mut count: usize,
400        mut off: u64,
401        options: IoOptions,
402    ) -> disk::Result<()> {
403        while count > 0 {
404            let nread = self.read_to_at_fut(dst, count, off, options).await?;
405            if nread == 0 {
406                return Err(disk::Error::ReadingData(io::Error::new(
407                    io::ErrorKind::UnexpectedEof,
408                    "failed to write whole buffer",
409                )));
410            }
411            count -= nread;
412            off += nread as u64;
413        }
414
415        Ok(())
416    }
417
418    /// Returns number of bytes available for reading.  May return an error if the combined
419    /// lengths of all the buffers in the DescriptorChain would cause an integer overflow.
420    pub fn available_bytes(&self) -> usize {
421        self.regions.available_bytes()
422    }
423
424    /// Returns number of bytes already read from the descriptor chain buffer.
425    pub fn bytes_read(&self) -> usize {
426        self.regions.bytes_consumed()
427    }
428
429    pub fn get_remaining_regions(&self) -> MemRegionIter {
430        self.regions.get_remaining_regions()
431    }
432
433    /// Returns a `&[VolatileSlice]` that represents all the remaining data in this `Reader`.
434    /// Calling this method does not actually consume any data from the `Reader` and callers should
435    /// call `consume` to advance the `Reader`.
436    pub fn get_remaining(&self) -> SmallVec<[VolatileSlice; 16]> {
437        self.regions.get_remaining(&self.mem)
438    }
439
440    /// Consumes `amt` bytes from the underlying descriptor chain. If `amt` is larger than the
441    /// remaining data left in this `Reader`, then all remaining data will be consumed.
442    pub fn consume(&mut self, amt: usize) {
443        self.regions.consume(amt)
444    }
445
446    /// Splits this `Reader` into two at the given offset in the `DescriptorChain` buffer. After the
447    /// split, `self` will be able to read up to `offset` bytes while the returned `Reader` can read
448    /// up to `available_bytes() - offset` bytes. If `offset > self.available_bytes()`, then the
449    /// returned `Reader` will not be able to read any bytes.
450    pub fn split_at(&mut self, offset: usize) -> Reader {
451        Reader {
452            mem: self.mem.clone(),
453            regions: self.regions.split_at(offset),
454        }
455    }
456}
457
458/// Copy up to `size` bytes from `src` into `dst`.
459///
460/// Returns the total number of bytes copied.
461///
462/// # Safety
463///
464/// The caller must ensure that it is safe to write `size` bytes of data into `dst`.
465///
466/// After the function returns, it is only safe to assume that the number of bytes indicated by the
467/// return value (which may be less than the requested `size`) have been initialized. Bytes beyond
468/// that point are not initialized by this function.
469unsafe fn copy_regions_to_mut_ptr(
470    mem: &GuestMemory,
471    src: MemRegionIter,
472    dst: *mut u8,
473    size: usize,
474) -> io::Result<usize> {
475    let mut copied = 0;
476    for src_region in src {
477        if copied >= size {
478            break;
479        }
480
481        let remaining = size - copied;
482        let count = cmp::min(remaining, src_region.len);
483
484        let vslice = mem
485            .get_slice_at_addr(GuestAddress(src_region.offset), count)
486            .map_err(|_e| io::Error::from(io::ErrorKind::InvalidData))?;
487
488        // SAFETY: `get_slice_at_addr()` verified that the region points to valid memory, and
489        // the `count` calculation ensures we will write at most `size` bytes into `dst`.
490        unsafe {
491            copy_nonoverlapping(vslice.as_ptr(), dst.add(copied), count);
492        }
493
494        copied += count;
495    }
496
497    Ok(copied)
498}
499
500impl io::Read for Reader {
501    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
502        // SAFETY: We pass a valid pointer and size combination derived from `buf`.
503        let total = unsafe {
504            copy_regions_to_mut_ptr(
505                &self.mem,
506                self.regions.get_remaining_regions(),
507                buf.as_mut_ptr(),
508                buf.len(),
509            )?
510        };
511        self.regions.consume(total);
512        Ok(total)
513    }
514}
515
516#[cfg(any(target_os = "android", target_os = "linux"))]
517impl fuse::Reader for Reader {}
518
519#[cfg(any(target_os = "android", target_os = "linux"))]
520impl fuse::filesystem::ZeroCopyReader for Reader {
521    fn read_to(&mut self, f: &mut std::fs::File, count: usize, off: u64) -> io::Result<usize> {
522        self.read_to_at(f, count, off)
523    }
524}
525
526/// Provides high-level interface over the sequence of memory regions
527/// defined by writable descriptors in the descriptor chain.
528///
529/// Note that virtio spec requires driver to place any device-writable
530/// descriptors after any device-readable descriptors (2.6.4.2 in Virtio Spec v1.1).
531/// Writer will start iterating the descriptors from the first writable one and will
532/// assume that all following descriptors are writable.
533pub struct Writer {
534    mem: GuestMemory,
535    regions: DescriptorChainRegions,
536}
537
538impl Writer {
539    /// Construct a new Writer wrapper over `writable_regions`.
540    pub fn new_from_regions(
541        mem: &GuestMemory,
542        writable_regions: SmallVec<[MemRegion; 2]>,
543    ) -> Writer {
544        Writer {
545            mem: mem.clone(),
546            regions: DescriptorChainRegions::new(writable_regions),
547        }
548    }
549
550    /// Writes an object to the descriptor chain buffer.
551    pub fn write_obj<T: Immutable + IntoBytes>(&mut self, val: T) -> io::Result<()> {
552        self.write_all(val.as_bytes())
553    }
554
555    /// Writes all objects produced by `iter` into the descriptor chain buffer. Unlike `consume`,
556    /// this doesn't require the values to be stored in an intermediate collection first. It also
557    /// allows callers to choose which elements in a collection to write, for example by using the
558    /// `filter` or `take` methods of the `Iterator` trait.
559    pub fn write_iter<T: Immutable + IntoBytes, I: Iterator<Item = T>>(
560        &mut self,
561        mut iter: I,
562    ) -> io::Result<()> {
563        iter.try_for_each(|v| self.write_obj(v))
564    }
565
566    /// Writes a collection of objects into the descriptor chain buffer.
567    pub fn consume<T: Immutable + IntoBytes, C: IntoIterator<Item = T>>(
568        &mut self,
569        vals: C,
570    ) -> io::Result<()> {
571        self.write_iter(vals.into_iter())
572    }
573
574    /// Returns number of bytes available for writing.  May return an error if the combined
575    /// lengths of all the buffers in the DescriptorChain would cause an overflow.
576    pub fn available_bytes(&self) -> usize {
577        self.regions.available_bytes()
578    }
579
580    /// Reads data into a volatile slice up to the minimum of the slice's length or the number of
581    /// bytes remaining. Returns the number of bytes read.
582    pub fn write_from_volatile_slice(&mut self, slice: VolatileSlice) -> usize {
583        let mut written = 0usize;
584        let mut src = slice;
585        for dst in self.get_remaining() {
586            src.copy_to_volatile_slice(dst);
587            let copied = std::cmp::min(src.size(), dst.size());
588            written += copied;
589            src = match src.offset(copied) {
590                Ok(v) => v,
591                Err(_) => break, // The slice is fully consumed
592            };
593        }
594        self.regions.consume(written);
595        written
596    }
597
598    /// Writes data to the descriptor chain buffer from a readable object.
599    /// Returns the number of bytes written to the descriptor chain buffer.
600    /// The number of bytes written can be less than `count` if
601    /// there isn't enough data in the descriptor chain buffer.
602    pub fn write_from<F: FileReadWriteVolatile>(
603        &mut self,
604        mut src: F,
605        count: usize,
606    ) -> io::Result<usize> {
607        let iovs = self.regions.get_remaining_with_count(&self.mem, count);
608        let read = src.read_vectored_volatile(&iovs[..])?;
609        self.regions.consume(read);
610        Ok(read)
611    }
612
613    /// Writes data to the descriptor chain buffer from a File at offset `off`.
614    /// Returns the number of bytes written to the descriptor chain buffer.
615    /// The number of bytes written can be less than `count` if
616    /// there isn't enough data in the descriptor chain buffer.
617    pub fn write_from_at<F: FileReadWriteAtVolatile>(
618        &mut self,
619        src: &F,
620        count: usize,
621        off: u64,
622    ) -> io::Result<usize> {
623        let iovs = self.regions.get_remaining_with_count(&self.mem, count);
624        let read = src.read_vectored_at_volatile(&iovs[..], off)?;
625        self.regions.consume(read);
626        Ok(read)
627    }
628
629    pub fn write_all_from<F: FileReadWriteVolatile>(
630        &mut self,
631        mut src: F,
632        mut count: usize,
633    ) -> io::Result<()> {
634        while count > 0 {
635            match self.write_from(&mut src, count) {
636                Ok(0) => {
637                    return Err(io::Error::new(
638                        io::ErrorKind::WriteZero,
639                        "failed to write whole buffer",
640                    ))
641                }
642                Ok(n) => count -= n,
643                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
644                Err(e) => return Err(e),
645            }
646        }
647
648        Ok(())
649    }
650
651    pub fn write_all_from_at<F: FileReadWriteAtVolatile>(
652        &mut self,
653        src: &F,
654        mut count: usize,
655        mut off: u64,
656    ) -> io::Result<()> {
657        while count > 0 {
658            match self.write_from_at(src, count, off) {
659                Ok(0) => {
660                    return Err(io::Error::new(
661                        io::ErrorKind::WriteZero,
662                        "failed to write whole buffer",
663                    ))
664                }
665                Ok(n) => {
666                    count -= n;
667                    off += n as u64;
668                }
669                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
670                Err(e) => return Err(e),
671            }
672        }
673        Ok(())
674    }
675    /// Writes data to the descriptor chain buffer from an `AsyncDisk` at offset `off`.
676    /// Returns the number of bytes written to the descriptor chain buffer.
677    /// The number of bytes written can be less than `count` if
678    /// there isn't enough data in the descriptor chain buffer.
679    pub async fn write_from_at_fut<F: AsyncDisk + ?Sized>(
680        &mut self,
681        src: &F,
682        count: usize,
683        off: u64,
684        options: IoOptions,
685    ) -> disk::Result<usize> {
686        let read = src
687            .read_to_mem(
688                off,
689                Arc::new(self.mem.clone()),
690                self.regions.get_remaining_regions_with_count(count),
691                options,
692            )
693            .await?;
694        self.regions.consume(read);
695        Ok(read)
696    }
697
698    pub async fn write_all_from_at_fut<F: AsyncDisk + ?Sized>(
699        &mut self,
700        src: &F,
701        mut count: usize,
702        mut off: u64,
703        options: IoOptions,
704    ) -> disk::Result<()> {
705        while count > 0 {
706            let nwritten = self.write_from_at_fut(src, count, off, options).await?;
707            if nwritten == 0 {
708                return Err(disk::Error::WritingData(io::Error::new(
709                    io::ErrorKind::UnexpectedEof,
710                    "failed to write whole buffer",
711                )));
712            }
713            count -= nwritten;
714            off += nwritten as u64;
715        }
716        Ok(())
717    }
718
719    /// Returns number of bytes already written to the descriptor chain buffer.
720    pub fn bytes_written(&self) -> usize {
721        self.regions.bytes_consumed()
722    }
723
724    pub fn get_remaining_regions(&self) -> MemRegionIter {
725        self.regions.get_remaining_regions()
726    }
727
728    /// Returns a `&[VolatileSlice]` that represents all the remaining data in this `Writer`.
729    /// Calling this method does not actually advance the current position of the `Writer` in the
730    /// buffer and callers should call `consume_bytes` to advance the `Writer`. Not calling
731    /// `consume_bytes` with the amount of data copied into the returned `VolatileSlice`s will
732    /// result in that that data being overwritten the next time data is written into the `Writer`.
733    pub fn get_remaining(&self) -> SmallVec<[VolatileSlice; 16]> {
734        self.regions.get_remaining(&self.mem)
735    }
736
737    /// Consumes `amt` bytes from the underlying descriptor chain. If `amt` is larger than the
738    /// remaining data left in this `Reader`, then all remaining data will be consumed.
739    pub fn consume_bytes(&mut self, amt: usize) {
740        self.regions.consume(amt)
741    }
742
743    /// Splits this `Writer` into two at the given offset in the `DescriptorChain` buffer. After the
744    /// split, `self` will be able to write up to `offset` bytes while the returned `Writer` can
745    /// write up to `available_bytes() - offset` bytes. If `offset > self.available_bytes()`, then
746    /// the returned `Writer` will not be able to write any bytes.
747    pub fn split_at(&mut self, offset: usize) -> Writer {
748        Writer {
749            mem: self.mem.clone(),
750            regions: self.regions.split_at(offset),
751        }
752    }
753}
754
755impl io::Write for Writer {
756    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
757        let mut rem = buf;
758        let mut total = 0;
759        for b in self.regions.get_remaining(&self.mem) {
760            if rem.is_empty() {
761                break;
762            }
763
764            let count = cmp::min(rem.len(), b.size());
765            // SAFETY:
766            // Safe because we have already verified that `vs` points to valid memory.
767            unsafe {
768                copy_nonoverlapping(rem.as_ptr(), b.as_mut_ptr(), count);
769            }
770            rem = &rem[count..];
771            total += count;
772        }
773
774        self.regions.consume(total);
775        Ok(total)
776    }
777
778    fn flush(&mut self) -> io::Result<()> {
779        // Nothing to flush since the writes go straight into the buffer.
780        Ok(())
781    }
782}
783
784#[cfg(any(target_os = "android", target_os = "linux"))]
785impl fuse::Writer for Writer {
786    type ClosureWriter = Self;
787
788    fn write_at<F>(&mut self, offset: usize, f: F) -> io::Result<usize>
789    where
790        F: Fn(&mut Self) -> io::Result<usize>,
791    {
792        f(&mut self.split_at(offset))
793    }
794
795    fn has_sufficient_buffer(&self, size: u32) -> bool {
796        self.available_bytes() >= size as usize
797    }
798}
799
800#[cfg(any(target_os = "android", target_os = "linux"))]
801impl fuse::filesystem::ZeroCopyWriter for Writer {
802    fn write_from(&mut self, f: &mut std::fs::File, count: usize, off: u64) -> io::Result<usize> {
803        self.write_from_at(f, count, off)
804    }
805}
806
807const VIRTQ_DESC_F_NEXT: u16 = 0x1;
808const VIRTQ_DESC_F_WRITE: u16 = 0x2;
809
810#[derive(Copy, Clone, PartialEq, Eq)]
811pub enum DescriptorType {
812    Readable,
813    Writable,
814}
815
816#[derive(Copy, Clone, Debug, FromBytes, Immutable, IntoBytes, KnownLayout)]
817#[repr(C)]
818struct virtq_desc {
819    addr: Le64,
820    len: Le32,
821    flags: Le16,
822    next: Le16,
823}
824
825/// Test utility function to create a descriptor chain in guest memory.
826pub fn create_descriptor_chain(
827    memory: &GuestMemory,
828    descriptor_array_addr: GuestAddress,
829    mut buffers_start_addr: GuestAddress,
830    descriptors: Vec<(DescriptorType, u32)>,
831    spaces_between_regions: u32,
832) -> anyhow::Result<DescriptorChain> {
833    let descriptors_len = descriptors.len();
834    for (index, (type_, size)) in descriptors.into_iter().enumerate() {
835        let mut flags = 0;
836        if let DescriptorType::Writable = type_ {
837            flags |= VIRTQ_DESC_F_WRITE;
838        }
839        if index + 1 < descriptors_len {
840            flags |= VIRTQ_DESC_F_NEXT;
841        }
842
843        let index = index as u16;
844        let desc = virtq_desc {
845            addr: buffers_start_addr.offset().into(),
846            len: size.into(),
847            flags: flags.into(),
848            next: (index + 1).into(),
849        };
850
851        let offset = size + spaces_between_regions;
852        buffers_start_addr = buffers_start_addr
853            .checked_add(offset as u64)
854            .context("Invalid buffers_start_addr)")?;
855
856        let _ = memory.write_obj_at_addr(
857            desc,
858            descriptor_array_addr
859                .checked_add(index as u64 * std::mem::size_of::<virtq_desc>() as u64)
860                .context("Invalid descriptor_array_addr")?,
861        );
862    }
863
864    let chain = SplitDescriptorChain::new(memory, descriptor_array_addr, 0x100, 0);
865    DescriptorChain::new(chain, memory, 0)
866}
867
868#[cfg(test)]
869mod tests {
870    use std::fs::File;
871    use std::io::Read;
872
873    use cros_async::Executor;
874    use tempfile::tempfile;
875    use tempfile::NamedTempFile;
876
877    use super::*;
878
879    #[test]
880    fn reader_test_simple_chain() {
881        use DescriptorType::*;
882
883        let memory_start_addr = GuestAddress(0x0);
884        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
885
886        let mut chain = create_descriptor_chain(
887            &memory,
888            GuestAddress(0x0),
889            GuestAddress(0x100),
890            vec![
891                (Readable, 8),
892                (Readable, 16),
893                (Readable, 18),
894                (Readable, 64),
895            ],
896            0,
897        )
898        .expect("create_descriptor_chain failed");
899        let reader = &mut chain.reader;
900        assert_eq!(reader.available_bytes(), 106);
901        assert_eq!(reader.bytes_read(), 0);
902
903        let mut buffer = [0u8; 64];
904        reader
905            .read_exact(&mut buffer)
906            .expect("read_exact should not fail here");
907
908        assert_eq!(reader.available_bytes(), 42);
909        assert_eq!(reader.bytes_read(), 64);
910
911        match reader.read(&mut buffer) {
912            Err(_) => panic!("read should not fail here"),
913            Ok(length) => assert_eq!(length, 42),
914        }
915
916        assert_eq!(reader.available_bytes(), 0);
917        assert_eq!(reader.bytes_read(), 106);
918    }
919
920    #[test]
921    fn writer_test_simple_chain() {
922        use DescriptorType::*;
923
924        let memory_start_addr = GuestAddress(0x0);
925        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
926
927        let mut chain = create_descriptor_chain(
928            &memory,
929            GuestAddress(0x0),
930            GuestAddress(0x100),
931            vec![
932                (Writable, 8),
933                (Writable, 16),
934                (Writable, 18),
935                (Writable, 64),
936            ],
937            0,
938        )
939        .expect("create_descriptor_chain failed");
940        let writer = &mut chain.writer;
941        assert_eq!(writer.available_bytes(), 106);
942        assert_eq!(writer.bytes_written(), 0);
943
944        let buffer = [0; 64];
945        writer
946            .write_all(&buffer)
947            .expect("write_all should not fail here");
948
949        assert_eq!(writer.available_bytes(), 42);
950        assert_eq!(writer.bytes_written(), 64);
951
952        match writer.write(&buffer) {
953            Err(_) => panic!("write should not fail here"),
954            Ok(length) => assert_eq!(length, 42),
955        }
956
957        assert_eq!(writer.available_bytes(), 0);
958        assert_eq!(writer.bytes_written(), 106);
959    }
960
961    #[test]
962    fn reader_test_incompatible_chain() {
963        use DescriptorType::*;
964
965        let memory_start_addr = GuestAddress(0x0);
966        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
967
968        let mut chain = create_descriptor_chain(
969            &memory,
970            GuestAddress(0x0),
971            GuestAddress(0x100),
972            vec![(Writable, 8)],
973            0,
974        )
975        .expect("create_descriptor_chain failed");
976        let reader = &mut chain.reader;
977        assert_eq!(reader.available_bytes(), 0);
978        assert_eq!(reader.bytes_read(), 0);
979
980        assert!(reader.read_obj::<u8>().is_err());
981
982        assert_eq!(reader.available_bytes(), 0);
983        assert_eq!(reader.bytes_read(), 0);
984    }
985
986    #[test]
987    fn writer_test_incompatible_chain() {
988        use DescriptorType::*;
989
990        let memory_start_addr = GuestAddress(0x0);
991        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
992
993        let mut chain = create_descriptor_chain(
994            &memory,
995            GuestAddress(0x0),
996            GuestAddress(0x100),
997            vec![(Readable, 8)],
998            0,
999        )
1000        .expect("create_descriptor_chain failed");
1001        let writer = &mut chain.writer;
1002        assert_eq!(writer.available_bytes(), 0);
1003        assert_eq!(writer.bytes_written(), 0);
1004
1005        assert!(writer.write_obj(0u8).is_err());
1006
1007        assert_eq!(writer.available_bytes(), 0);
1008        assert_eq!(writer.bytes_written(), 0);
1009    }
1010
1011    #[test]
1012    fn reader_failing_io() {
1013        use DescriptorType::*;
1014
1015        let memory_start_addr = GuestAddress(0x0);
1016        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1017
1018        let mut chain = create_descriptor_chain(
1019            &memory,
1020            GuestAddress(0x0),
1021            GuestAddress(0x100),
1022            vec![(Readable, 256), (Readable, 256)],
1023            0,
1024        )
1025        .expect("create_descriptor_chain failed");
1026
1027        let reader = &mut chain.reader;
1028
1029        // Open a file in read-only mode so writes to it to trigger an I/O error.
1030        let device_file = if cfg!(windows) { "NUL" } else { "/dev/zero" };
1031        let mut ro_file = File::open(device_file).expect("failed to open device file");
1032
1033        reader
1034            .read_exact_to(&mut ro_file, 512)
1035            .expect_err("successfully read more bytes than SharedMemory size");
1036
1037        // The write above should have failed entirely, so we end up not writing any bytes at all.
1038        assert_eq!(reader.available_bytes(), 512);
1039        assert_eq!(reader.bytes_read(), 0);
1040    }
1041
1042    #[test]
1043    fn writer_failing_io() {
1044        use DescriptorType::*;
1045
1046        let memory_start_addr = GuestAddress(0x0);
1047        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1048
1049        let mut chain = create_descriptor_chain(
1050            &memory,
1051            GuestAddress(0x0),
1052            GuestAddress(0x100),
1053            vec![(Writable, 256), (Writable, 256)],
1054            0,
1055        )
1056        .expect("create_descriptor_chain failed");
1057
1058        let writer = &mut chain.writer;
1059
1060        let mut file = tempfile().unwrap();
1061
1062        file.set_len(384).unwrap();
1063
1064        writer
1065            .write_all_from(&mut file, 512)
1066            .expect_err("successfully wrote more bytes than in SharedMemory");
1067
1068        assert_eq!(writer.available_bytes(), 128);
1069        assert_eq!(writer.bytes_written(), 384);
1070    }
1071
1072    #[test]
1073    fn reader_writer_shared_chain() {
1074        use DescriptorType::*;
1075
1076        let memory_start_addr = GuestAddress(0x0);
1077        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1078
1079        let mut chain = create_descriptor_chain(
1080            &memory,
1081            GuestAddress(0x0),
1082            GuestAddress(0x100),
1083            vec![
1084                (Readable, 16),
1085                (Readable, 16),
1086                (Readable, 96),
1087                (Writable, 64),
1088                (Writable, 1),
1089                (Writable, 3),
1090            ],
1091            0,
1092        )
1093        .expect("create_descriptor_chain failed");
1094        let reader = &mut chain.reader;
1095        let writer = &mut chain.writer;
1096
1097        assert_eq!(reader.bytes_read(), 0);
1098        assert_eq!(writer.bytes_written(), 0);
1099
1100        let mut buffer = Vec::with_capacity(200);
1101
1102        assert_eq!(
1103            reader
1104                .read_to_end(&mut buffer)
1105                .expect("read should not fail here"),
1106            128
1107        );
1108
1109        // The writable descriptors are only 68 bytes long.
1110        writer
1111            .write_all(&buffer[..68])
1112            .expect("write should not fail here");
1113
1114        assert_eq!(reader.available_bytes(), 0);
1115        assert_eq!(reader.bytes_read(), 128);
1116        assert_eq!(writer.available_bytes(), 0);
1117        assert_eq!(writer.bytes_written(), 68);
1118    }
1119
1120    #[test]
1121    fn reader_writer_shattered_object() {
1122        use DescriptorType::*;
1123
1124        let memory_start_addr = GuestAddress(0x0);
1125        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1126
1127        let secret: Le32 = 0x12345678.into();
1128
1129        // Create a descriptor chain with memory regions that are properly separated.
1130        let mut chain_writer = create_descriptor_chain(
1131            &memory,
1132            GuestAddress(0x0),
1133            GuestAddress(0x100),
1134            vec![(Writable, 1), (Writable, 1), (Writable, 1), (Writable, 1)],
1135            123,
1136        )
1137        .expect("create_descriptor_chain failed");
1138        let writer = &mut chain_writer.writer;
1139        writer
1140            .write_obj(secret)
1141            .expect("write_obj should not fail here");
1142
1143        // Now create new descriptor chain pointing to the same memory and try to read it.
1144        let mut chain_reader = create_descriptor_chain(
1145            &memory,
1146            GuestAddress(0x0),
1147            GuestAddress(0x100),
1148            vec![(Readable, 1), (Readable, 1), (Readable, 1), (Readable, 1)],
1149            123,
1150        )
1151        .expect("create_descriptor_chain failed");
1152        let reader = &mut chain_reader.reader;
1153        match reader.read_obj::<Le32>() {
1154            Err(_) => panic!("read_obj should not fail here"),
1155            Ok(read_secret) => assert_eq!(read_secret, secret),
1156        }
1157    }
1158
1159    #[test]
1160    fn reader_unexpected_eof() {
1161        use DescriptorType::*;
1162
1163        let memory_start_addr = GuestAddress(0x0);
1164        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1165
1166        let mut chain = create_descriptor_chain(
1167            &memory,
1168            GuestAddress(0x0),
1169            GuestAddress(0x100),
1170            vec![(Readable, 256), (Readable, 256)],
1171            0,
1172        )
1173        .expect("create_descriptor_chain failed");
1174
1175        let reader = &mut chain.reader;
1176
1177        let mut buf = vec![0; 1024];
1178
1179        assert_eq!(
1180            reader
1181                .read_exact(&mut buf[..])
1182                .expect_err("read more bytes than available")
1183                .kind(),
1184            io::ErrorKind::UnexpectedEof
1185        );
1186    }
1187
1188    #[test]
1189    fn split_border() {
1190        use DescriptorType::*;
1191
1192        let memory_start_addr = GuestAddress(0x0);
1193        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1194
1195        let mut chain = create_descriptor_chain(
1196            &memory,
1197            GuestAddress(0x0),
1198            GuestAddress(0x100),
1199            vec![
1200                (Readable, 16),
1201                (Readable, 16),
1202                (Readable, 96),
1203                (Writable, 64),
1204                (Writable, 1),
1205                (Writable, 3),
1206            ],
1207            0,
1208        )
1209        .expect("create_descriptor_chain failed");
1210        let reader = &mut chain.reader;
1211
1212        let other = reader.split_at(32);
1213        assert_eq!(reader.available_bytes(), 32);
1214        assert_eq!(other.available_bytes(), 96);
1215    }
1216
1217    #[test]
1218    fn split_middle() {
1219        use DescriptorType::*;
1220
1221        let memory_start_addr = GuestAddress(0x0);
1222        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1223
1224        let mut chain = create_descriptor_chain(
1225            &memory,
1226            GuestAddress(0x0),
1227            GuestAddress(0x100),
1228            vec![
1229                (Readable, 16),
1230                (Readable, 16),
1231                (Readable, 96),
1232                (Writable, 64),
1233                (Writable, 1),
1234                (Writable, 3),
1235            ],
1236            0,
1237        )
1238        .expect("create_descriptor_chain failed");
1239        let reader = &mut chain.reader;
1240
1241        let other = reader.split_at(24);
1242        assert_eq!(reader.available_bytes(), 24);
1243        assert_eq!(other.available_bytes(), 104);
1244    }
1245
1246    #[test]
1247    fn split_end() {
1248        use DescriptorType::*;
1249
1250        let memory_start_addr = GuestAddress(0x0);
1251        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1252
1253        let mut chain = create_descriptor_chain(
1254            &memory,
1255            GuestAddress(0x0),
1256            GuestAddress(0x100),
1257            vec![
1258                (Readable, 16),
1259                (Readable, 16),
1260                (Readable, 96),
1261                (Writable, 64),
1262                (Writable, 1),
1263                (Writable, 3),
1264            ],
1265            0,
1266        )
1267        .expect("create_descriptor_chain failed");
1268        let reader = &mut chain.reader;
1269
1270        let other = reader.split_at(128);
1271        assert_eq!(reader.available_bytes(), 128);
1272        assert_eq!(other.available_bytes(), 0);
1273    }
1274
1275    #[test]
1276    fn split_beginning() {
1277        use DescriptorType::*;
1278
1279        let memory_start_addr = GuestAddress(0x0);
1280        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1281
1282        let mut chain = create_descriptor_chain(
1283            &memory,
1284            GuestAddress(0x0),
1285            GuestAddress(0x100),
1286            vec![
1287                (Readable, 16),
1288                (Readable, 16),
1289                (Readable, 96),
1290                (Writable, 64),
1291                (Writable, 1),
1292                (Writable, 3),
1293            ],
1294            0,
1295        )
1296        .expect("create_descriptor_chain failed");
1297        let reader = &mut chain.reader;
1298
1299        let other = reader.split_at(0);
1300        assert_eq!(reader.available_bytes(), 0);
1301        assert_eq!(other.available_bytes(), 128);
1302    }
1303
1304    #[test]
1305    fn split_outofbounds() {
1306        use DescriptorType::*;
1307
1308        let memory_start_addr = GuestAddress(0x0);
1309        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1310
1311        let mut chain = create_descriptor_chain(
1312            &memory,
1313            GuestAddress(0x0),
1314            GuestAddress(0x100),
1315            vec![
1316                (Readable, 16),
1317                (Readable, 16),
1318                (Readable, 96),
1319                (Writable, 64),
1320                (Writable, 1),
1321                (Writable, 3),
1322            ],
1323            0,
1324        )
1325        .expect("create_descriptor_chain failed");
1326        let reader = &mut chain.reader;
1327
1328        let other = reader.split_at(256);
1329        assert_eq!(
1330            other.available_bytes(),
1331            0,
1332            "Reader returned from out-of-bounds split still has available bytes"
1333        );
1334    }
1335
1336    #[test]
1337    fn read_full() {
1338        use DescriptorType::*;
1339
1340        let memory_start_addr = GuestAddress(0x0);
1341        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1342
1343        let mut chain = create_descriptor_chain(
1344            &memory,
1345            GuestAddress(0x0),
1346            GuestAddress(0x100),
1347            vec![(Readable, 16), (Readable, 16), (Readable, 16)],
1348            0,
1349        )
1350        .expect("create_descriptor_chain failed");
1351        let reader = &mut chain.reader;
1352
1353        let mut buf = [0u8; 64];
1354        assert_eq!(
1355            reader.read(&mut buf[..]).expect("failed to read to buffer"),
1356            48
1357        );
1358    }
1359
1360    #[test]
1361    fn write_full() {
1362        use DescriptorType::*;
1363
1364        let memory_start_addr = GuestAddress(0x0);
1365        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1366
1367        let mut chain = create_descriptor_chain(
1368            &memory,
1369            GuestAddress(0x0),
1370            GuestAddress(0x100),
1371            vec![(Writable, 16), (Writable, 16), (Writable, 16)],
1372            0,
1373        )
1374        .expect("create_descriptor_chain failed");
1375        let writer = &mut chain.writer;
1376
1377        let buf = [0xdeu8; 64];
1378        assert_eq!(
1379            writer.write(&buf[..]).expect("failed to write from buffer"),
1380            48
1381        );
1382    }
1383
1384    #[test]
1385    fn consume_collect() {
1386        use DescriptorType::*;
1387
1388        let memory_start_addr = GuestAddress(0x0);
1389        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1390        let vs: Vec<Le64> = vec![
1391            0x0101010101010101.into(),
1392            0x0202020202020202.into(),
1393            0x0303030303030303.into(),
1394        ];
1395
1396        let mut write_chain = create_descriptor_chain(
1397            &memory,
1398            GuestAddress(0x0),
1399            GuestAddress(0x100),
1400            vec![(Writable, 24)],
1401            0,
1402        )
1403        .expect("create_descriptor_chain failed");
1404        let writer = &mut write_chain.writer;
1405        writer
1406            .consume(vs.clone())
1407            .expect("failed to consume() a vector");
1408
1409        let mut read_chain = create_descriptor_chain(
1410            &memory,
1411            GuestAddress(0x0),
1412            GuestAddress(0x100),
1413            vec![(Readable, 24)],
1414            0,
1415        )
1416        .expect("create_descriptor_chain failed");
1417        let reader = &mut read_chain.reader;
1418        let vs_read = reader
1419            .collect::<io::Result<Vec<Le64>>, _>()
1420            .expect("failed to collect() values");
1421        assert_eq!(vs, vs_read);
1422    }
1423
1424    #[test]
1425    fn get_remaining_region_with_count() {
1426        use DescriptorType::*;
1427
1428        let memory_start_addr = GuestAddress(0x0);
1429        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1430
1431        let chain = create_descriptor_chain(
1432            &memory,
1433            GuestAddress(0x0),
1434            GuestAddress(0x100),
1435            vec![
1436                (Readable, 16),
1437                (Readable, 16),
1438                (Readable, 96),
1439                (Writable, 64),
1440                (Writable, 1),
1441                (Writable, 3),
1442            ],
1443            0,
1444        )
1445        .expect("create_descriptor_chain failed");
1446
1447        let Reader {
1448            mem: _,
1449            mut regions,
1450        } = chain.reader;
1451
1452        let drain = regions
1453            .get_remaining_regions_with_count(usize::MAX)
1454            .fold(0usize, |total, region| total + region.len);
1455        assert_eq!(drain, 128);
1456
1457        let exact = regions
1458            .get_remaining_regions_with_count(32)
1459            .fold(0usize, |total, region| total + region.len);
1460        assert!(exact > 0);
1461        assert!(exact <= 32);
1462
1463        let split = regions
1464            .get_remaining_regions_with_count(24)
1465            .fold(0usize, |total, region| total + region.len);
1466        assert!(split > 0);
1467        assert!(split <= 24);
1468
1469        regions.consume(64);
1470
1471        let first = regions
1472            .get_remaining_regions_with_count(8)
1473            .fold(0usize, |total, region| total + region.len);
1474        assert!(first > 0);
1475        assert!(first <= 8);
1476    }
1477
1478    #[test]
1479    fn get_remaining_with_count() {
1480        use DescriptorType::*;
1481
1482        let memory_start_addr = GuestAddress(0x0);
1483        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1484
1485        let chain = create_descriptor_chain(
1486            &memory,
1487            GuestAddress(0x0),
1488            GuestAddress(0x100),
1489            vec![
1490                (Readable, 16),
1491                (Readable, 16),
1492                (Readable, 96),
1493                (Writable, 64),
1494                (Writable, 1),
1495                (Writable, 3),
1496            ],
1497            0,
1498        )
1499        .expect("create_descriptor_chain failed");
1500        let Reader {
1501            mem: _,
1502            mut regions,
1503        } = chain.reader;
1504
1505        let drain = regions
1506            .get_remaining_with_count(&memory, usize::MAX)
1507            .iter()
1508            .fold(0usize, |total, iov| total + iov.size());
1509        assert_eq!(drain, 128);
1510
1511        let exact = regions
1512            .get_remaining_with_count(&memory, 32)
1513            .iter()
1514            .fold(0usize, |total, iov| total + iov.size());
1515        assert!(exact > 0);
1516        assert!(exact <= 32);
1517
1518        let split = regions
1519            .get_remaining_with_count(&memory, 24)
1520            .iter()
1521            .fold(0usize, |total, iov| total + iov.size());
1522        assert!(split > 0);
1523        assert!(split <= 24);
1524
1525        regions.consume(64);
1526
1527        let first = regions
1528            .get_remaining_with_count(&memory, 8)
1529            .iter()
1530            .fold(0usize, |total, iov| total + iov.size());
1531        assert!(first > 0);
1532        assert!(first <= 8);
1533    }
1534
1535    #[test]
1536    fn reader_peek_obj() {
1537        use DescriptorType::*;
1538
1539        let memory_start_addr = GuestAddress(0x0);
1540        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1541
1542        // Write test data to memory.
1543        memory
1544            .write_obj_at_addr(Le16::from(0xBEEF), GuestAddress(0x100))
1545            .unwrap();
1546        memory
1547            .write_obj_at_addr(Le16::from(0xDEAD), GuestAddress(0x200))
1548            .unwrap();
1549
1550        let mut chain_reader = create_descriptor_chain(
1551            &memory,
1552            GuestAddress(0x0),
1553            GuestAddress(0x100),
1554            vec![(Readable, 2), (Readable, 2)],
1555            0x100 - 2,
1556        )
1557        .expect("create_descriptor_chain failed");
1558        let reader = &mut chain_reader.reader;
1559
1560        // peek_obj() at the beginning of the chain should return the first object.
1561        let peek1 = reader.peek_obj::<Le16>().unwrap();
1562        assert_eq!(peek1, Le16::from(0xBEEF));
1563
1564        // peek_obj() again should return the same object, since it was not consumed.
1565        let peek2 = reader.peek_obj::<Le16>().unwrap();
1566        assert_eq!(peek2, Le16::from(0xBEEF));
1567
1568        // peek_obj() of an object spanning two descriptors should copy from both.
1569        let peek3 = reader.peek_obj::<Le32>().unwrap();
1570        assert_eq!(peek3, Le32::from(0xDEADBEEF));
1571
1572        // read_obj() should return the first object.
1573        let read1 = reader.read_obj::<Le16>().unwrap();
1574        assert_eq!(read1, Le16::from(0xBEEF));
1575
1576        // peek_obj() of a value that is larger than the rest of the chain should fail.
1577        reader
1578            .peek_obj::<Le32>()
1579            .expect_err("peek_obj past end of chain");
1580
1581        // read_obj() again should return the second object.
1582        let read2 = reader.read_obj::<Le16>().unwrap();
1583        assert_eq!(read2, Le16::from(0xDEAD));
1584
1585        // peek_obj() should fail at the end of the chain.
1586        reader
1587            .peek_obj::<Le16>()
1588            .expect_err("peek_obj past end of chain");
1589    }
1590
1591    #[test]
1592    fn region_reader_failing_io() {
1593        let ex = Executor::new().unwrap();
1594        ex.run_until(region_reader_failing_io_async(&ex)).unwrap();
1595    }
1596    async fn region_reader_failing_io_async(ex: &Executor) {
1597        use DescriptorType::*;
1598
1599        let memory_start_addr = GuestAddress(0x0);
1600        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1601
1602        let mut chain = create_descriptor_chain(
1603            &memory,
1604            GuestAddress(0x0),
1605            GuestAddress(0x100),
1606            vec![(Readable, 256), (Readable, 256)],
1607            0,
1608        )
1609        .expect("create_descriptor_chain failed");
1610
1611        let reader = &mut chain.reader;
1612
1613        // Open a file in read-only mode so writes to it to trigger an I/O error.
1614        let named_temp_file = NamedTempFile::new().expect("failed to create temp file");
1615        let ro_file =
1616            File::open(named_temp_file.path()).expect("failed to open temp file read only");
1617        let async_ro_file = disk::SingleFileDisk::new(ro_file, ex).expect("Failed to crate SFD");
1618
1619        reader
1620            .read_exact_to_at_fut(&async_ro_file, 512, 0, Default::default())
1621            .await
1622            .expect_err("successfully read more bytes than SingleFileDisk size");
1623
1624        // The write above should have failed entirely, so we end up not writing any bytes at all.
1625        assert_eq!(reader.available_bytes(), 512);
1626        assert_eq!(reader.bytes_read(), 0);
1627    }
1628
1629    #[test]
1630    fn region_writer_failing_io() {
1631        let ex = Executor::new().unwrap();
1632        ex.run_until(region_writer_failing_io_async(&ex)).unwrap()
1633    }
1634    async fn region_writer_failing_io_async(ex: &Executor) {
1635        use DescriptorType::*;
1636
1637        let memory_start_addr = GuestAddress(0x0);
1638        let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
1639
1640        let mut chain = create_descriptor_chain(
1641            &memory,
1642            GuestAddress(0x0),
1643            GuestAddress(0x100),
1644            vec![(Writable, 256), (Writable, 256)],
1645            0,
1646        )
1647        .expect("create_descriptor_chain failed");
1648
1649        let writer = &mut chain.writer;
1650
1651        let file = tempfile().expect("failed to create temp file");
1652
1653        file.set_len(384).unwrap();
1654        let async_file = disk::SingleFileDisk::new(file, ex).expect("Failed to crate SFD");
1655
1656        writer
1657            .write_all_from_at_fut(&async_file, 512, 0, Default::default())
1658            .await
1659            .expect_err("successfully wrote more bytes than in SingleFileDisk");
1660
1661        assert_eq!(writer.available_bytes(), 128);
1662        assert_eq!(writer.bytes_written(), 384);
1663    }
1664}