fuse-backend-rs 0.9.3

A rust library for Fuse(filesystem in userspace) servers and virtio-fs devices
Documentation
diff --git a/src/transport/file_volatile_slice.rs b/src/transport/file_volatile_slice.rs
index c0ab4bd..e0386e6 100644
--- a/src/transport/file_volatile_slice.rs
+++ b/src/transport/file_volatile_slice.rs
@@ -4,9 +4,10 @@
 
 //! Helper structures to work around limitations of the `vm-memory` crate.
 //!
-//! The vm-memory v0.6.0 has added support of `Bitmap` to track dirty pages, which makes the rust
-//! compiler fail to compile our code. So introduce [FileVolatileSlice] to mask out the
-//! `BitmapSlice` generic type parameter.
+//! The vm-memory v0.6.0 introduced support of dirty page tracking by using `Bitmap`, which adds a
+//! generic type parameters to several APIs. That's a breaking change and  makes the rust compiler
+//! fail to compile our code. So introduce [FileVolatileSlice] to mask out the `BitmapSlice`
+//! generic type parameter.
 //!
 //! Dirty page tracking is handled at higher level in `IoBuffers`.
 
@@ -47,7 +48,12 @@ impl fmt::Display for Error {
 
 impl error::Error for Error {}
 
-/// An adapter structure to mask out the `vm_memory::BitmapSlice` generic parameter.
+/// An adapter structure to work around limitations of the `vm-memory` crate.
+///
+/// It solves the compilation failure by masking out the
+/// [`vm_memory::BitmapSlice`](https://docs.rs/vm-memory/latest/vm_memory/bitmap/trait.BitmapSlice.html)
+/// generic type parameter of
+/// [`vm_memory::VolatileSlice`](https://docs.rs/vm-memory/latest/vm_memory/volatile_memory/struct.VolatileSlice.html)
 #[derive(Clone, Copy, Debug)]
 pub struct FileVolatileSlice<'a> {
     addr: *mut u8,
@@ -55,14 +61,38 @@ pub struct FileVolatileSlice<'a> {
     phantom: PhantomData<&'a u8>,
 }
 
-/// Safe because the field `FileVolatileSlice::addr` is used as data buffer.
+// Safe because the field `FileVolatileSlice::addr` is used as data buffer.
 unsafe impl<'a> Sync for FileVolatileSlice<'a> {}
 
 impl<'a> FileVolatileSlice<'a> {
     /// Create a new instance of [`FileVolatileSlice`] from a raw pointer.
     ///
     /// # Safety
-    /// This function is the same as `VolatileSlice::new()`.
+    /// To use this safely, the caller must guarantee that the memory at addr is size bytes long
+    /// and is available for the duration of the lifetime of the new [FileVolatileSlice].
+    /// The caller must also guarantee that all other users of the given chunk of memory are using
+    /// volatile accesses.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # use fuse_backend_rs::transport::FileVolatileSlice;
+    /// # use vm_memory::bytes::Bytes;
+    /// # use std::sync::atomic::Ordering;
+    /// let mut buffer = [0u8; 1024];
+    /// let s = unsafe { FileVolatileSlice::new(buffer.as_mut_ptr(), buffer.len()) };
+    ///
+    /// {
+    ///     let o: u32 = s.load(0x10, Ordering::Acquire).unwrap();
+    ///     assert_eq!(o, 0);
+    ///     s.store(1u8, 0x10, Ordering::Release).unwrap();
+    ///
+    ///     let s2 = s.as_volatile_slice();
+    ///     let s3 = FileVolatileSlice::new_from_volatile_slice(&s2);
+    ///     assert_eq!(s3.len(), 1024);
+    /// }
+    ///
+    /// assert_eq!(buffer[0x10], 1);
+    /// ```
     pub unsafe fn new(addr: *mut u8, size: usize) -> Self {
         Self {
             addr,
@@ -71,35 +101,36 @@ impl<'a> FileVolatileSlice<'a> {
         }
     }
 
-    /// Create a new [`FileVolatileSlice`] from [`VolatileSlice`] and strip off the [`BitmapSlice`]
-    /// generic type parameter.
+    /// Create a new [`FileVolatileSlice`] from [`VolatileSlice`](https://docs.rs/vm-memory/latest/vm_memory/volatile_memory/struct.VolatileSlice.html)
+    /// and strip off the [`BitmapSlice`](https://docs.rs/vm-memory/latest/vm_memory/bitmap/trait.BitmapSlice.html) generic type parameter.
     ///
-    /// The caller needs to dirty page tracking for the data buffer.
+    /// The caller needs to handle dirty page tracking for the data buffer.
     pub fn new_from_volatile_slice<S: BitmapSlice>(s: &VolatileSlice<'a, S>) -> Self {
         unsafe { Self::new(s.as_ptr(), s.len()) }
     }
 
-    /// Create a new instance of [`VolatileSlice`] without dirty page tracking.
+    /// Create a [`vm_memory::VolatileSlice`](https://docs.rs/vm-memory/latest/vm_memory/volatile_memory/struct.VolatileSlice.html)
+    /// from [FileVolatileSlice] without dirty page tracking.
     pub fn as_volatile_slice(&self) -> VolatileSlice<'_, ()> {
         unsafe { VolatileSlice::new(self.as_ptr(), self.len()) }
     }
 
-    /// Returns a pointer to the beginning of the slice.
+    /// Return a pointer to the start of the slice.
     pub fn as_ptr(&self) -> *mut u8 {
         self.addr
     }
 
-    /// Gets the size of this slice.
+    /// Get the size of the slice.
     pub fn len(&self) -> usize {
         self.size
     }
 
-    /// Checks if the slice is empty.
+    /// Check if the slice is empty.
     pub fn is_empty(&self) -> bool {
         self.size == 0
     }
 
-    /// Returns a subslice of this FileVolatileSlice starting at `offset`.
+    /// Return a subslice of this [FileVolatileSlice] starting at `offset`.
     pub fn offset(&self, count: usize) -> Result<Self, Error> {
         let new_addr = (self.addr as usize)
             .checked_add(count)
@@ -141,12 +172,7 @@ impl<'a> Bytes<usize> for FileVolatileSlice<'a> {
         VolatileSlice::read_from(&self.as_volatile_slice(), addr, src, count)
     }
 
-    fn read_exact_from<F>(
-        &self,
-        addr: usize,
-        src: &mut F,
-        count: usize,
-    ) -> Result<(), Self::E>
+    fn read_exact_from<F>(&self, addr: usize, src: &mut F, count: usize) -> Result<(), Self::E>
     where
         F: Read,
     {
@@ -167,12 +193,7 @@ impl<'a> Bytes<usize> for FileVolatileSlice<'a> {
         VolatileSlice::write_all_to(&self.as_volatile_slice(), addr, dst, count)
     }
 
-    fn store<T: AtomicAccess>(
-        &self,
-        val: T,
-        addr: usize,
-        order: Ordering,
-    ) -> Result<(), Self::E> {
+    fn store<T: AtomicAccess>(&self, val: T, addr: usize, order: Ordering) -> Result<(), Self::E> {
         VolatileSlice::store(&self.as_volatile_slice(), val, addr, order)
     }
 
@@ -193,10 +214,13 @@ mod tests {
         let o: u32 = s.load(0x10, Ordering::Acquire).unwrap();
         assert_eq!(o, 0);
         s.store(1u8, 0x10, Ordering::Release).unwrap();
-        assert_eq!(buffer[0x10], 1);
 
         let s2 = s.as_volatile_slice();
         let s3 = FileVolatileSlice::new_from_volatile_slice(&s2);
         assert_eq!(s3.len(), 1024);
+
+        assert!(s3.offset(2048).is_err());
+
+        assert_eq!(buffer[0x10], 1);
     }
-}
\ No newline at end of file
+}