fuse_backend_rs/transport/fusedev/
mod.rs

1// Copyright (C) 2020 Alibaba Cloud. All rights reserved.
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! Traits and Structs to implement the fusedev transport driver.
6//!
7//! With fusedev transport driver, requests received from `/dev/fuse` will be stored in an internal
8//! buffer and the whole reply message must be written all at once.
9
10use std::collections::VecDeque;
11use std::io::{self, IoSlice, Write};
12use std::marker::PhantomData;
13use std::mem::ManuallyDrop;
14use std::os::fd::AsRawFd;
15use std::os::unix::io::RawFd;
16
17use nix::sys::uio::writev;
18use nix::unistd::write;
19use vm_memory::{ByteValued, VolatileSlice};
20
21use super::{Error, FileReadWriteVolatile, IoBuffers, Reader, Result, Writer};
22use crate::file_buf::FileVolatileSlice;
23use crate::BitmapSlice;
24
25#[cfg(target_os = "linux")]
26mod linux_session;
27#[cfg(target_os = "linux")]
28pub use linux_session::*;
29
30#[cfg(all(target_os = "macos", not(feature = "fuse-t")))]
31mod macos_session;
32#[cfg(all(target_os = "macos", not(feature = "fuse-t")))]
33pub use macos_session::*;
34
35#[cfg(all(target_os = "macos", feature = "fuse-t"))]
36mod fuse_t_session;
37#[cfg(all(target_os = "macos", feature = "fuse-t"))]
38pub use fuse_t_session::*;
39
40// These follow the definition from libfuse.
41/// Maximum size of FUSE message data, 1M with 4K page.
42pub const FUSE_KERN_BUF_PAGES: usize = 256;
43/// Maximum size of FUSE message header, 4K.
44pub const FUSE_HEADER_SIZE: usize = 0x1000;
45
46/// A buffer reference wrapper for fuse requests.
47#[derive(Debug)]
48pub struct FuseBuf<'a> {
49    mem: &'a mut [u8],
50}
51
52impl<'a> FuseBuf<'a> {
53    /// Construct a new fuse request buffer wrapper.
54    pub fn new(mem: &'a mut [u8]) -> FuseBuf<'a> {
55        FuseBuf { mem }
56    }
57}
58
59impl<'a, S: BitmapSlice + Default> Reader<'a, S> {
60    /// Construct a new Reader wrapper over `desc_chain`.
61    ///
62    /// 'request`: Fuse request from clients read from /dev/fuse
63    pub fn from_fuse_buffer(buf: FuseBuf<'a>) -> Result<Reader<'a, S>> {
64        let mut buffers: VecDeque<VolatileSlice<'a, S>> = VecDeque::new();
65        // Safe because Reader has the same lifetime with buf.
66        buffers.push_back(unsafe {
67            VolatileSlice::with_bitmap(buf.mem.as_mut_ptr(), buf.mem.len(), S::default(), None)
68        });
69
70        Ok(Reader {
71            buffers: IoBuffers {
72                buffers,
73                bytes_consumed: 0,
74            },
75        })
76    }
77}
78
79/// Writer to send FUSE reply to the FUSE driver.
80///
81/// There are a few special properties to follow:
82/// 1. A fuse device request MUST be written to the fuse device in one shot.
83/// 2. If the writer is split, a final commit() MUST be called to issue the
84///    device write operation.
85/// 3. Concurrency, caller should not write to the writer concurrently.
86#[derive(Debug, PartialEq, Eq)]
87pub struct FuseDevWriter<'a, S: BitmapSlice = ()> {
88    fd: RawFd,
89    buffered: bool,
90    buf: ManuallyDrop<Vec<u8>>,
91    bitmapslice: S,
92    phantom: PhantomData<&'a mut [S]>,
93}
94
95impl<'a, S: BitmapSlice + Default> FuseDevWriter<'a, S> {
96    /// Construct a new [Writer].
97    pub fn new(fd: RawFd, data_buf: &'a mut [u8]) -> Result<FuseDevWriter<'a, S>> {
98        let buf = unsafe { Vec::from_raw_parts(data_buf.as_mut_ptr(), 0, data_buf.len()) };
99        Ok(FuseDevWriter {
100            fd,
101            buffered: false,
102            buf: ManuallyDrop::new(buf),
103            bitmapslice: S::default(),
104            phantom: PhantomData,
105        })
106    }
107}
108
109impl<'a, S: BitmapSlice> FuseDevWriter<'a, S> {
110    /// Split the [Writer] at the given offset.
111    ///
112    /// After the split, `self` will be able to write up to `offset` bytes while the returned
113    /// `Writer` can write up to `available_bytes() - offset` bytes.  Returns an error if
114    /// `offset > self.available_bytes()`.
115    pub fn split_at(&mut self, offset: usize) -> Result<FuseDevWriter<'a, S>> {
116        if self.buf.capacity() < offset {
117            return Err(Error::SplitOutOfBounds(offset));
118        }
119
120        let (len1, len2) = if self.buf.len() > offset {
121            (offset, self.buf.len() - offset)
122        } else {
123            (self.buf.len(), 0)
124        };
125        let cap2 = self.buf.capacity() - offset;
126        let ptr = self.buf.as_mut_ptr();
127
128        // Safe because both buffers refer to different parts of the same underlying `data_buf`.
129        self.buf = unsafe { ManuallyDrop::new(Vec::from_raw_parts(ptr, len1, offset)) };
130        self.buffered = true;
131        let buf = unsafe { ManuallyDrop::new(Vec::from_raw_parts(ptr.add(offset), len2, cap2)) };
132
133        Ok(FuseDevWriter {
134            fd: self.fd,
135            buffered: true,
136            buf,
137            bitmapslice: self.bitmapslice.clone(),
138            phantom: PhantomData,
139        })
140    }
141
142    /// Compose the FUSE reply message and send the message to `/dev/fuse`.
143    pub fn commit(&mut self, other: Option<&Writer<'a, S>>) -> io::Result<usize> {
144        if !self.buffered {
145            return Ok(0);
146        }
147
148        let o = match other {
149            Some(Writer::FuseDev(w)) => w.buf.as_slice(),
150            _ => &[],
151        };
152        let res = match (self.buf.len(), o.len()) {
153            (0, 0) => Ok(0),
154            (0, _) => write(self.fd, o),
155            (_, 0) => write(self.fd, self.buf.as_slice()),
156            (_, _) => {
157                let bufs = [IoSlice::new(self.buf.as_slice()), IoSlice::new(o)];
158                writev(self.fd, &bufs)
159            }
160        };
161
162        res.map_err(|e| io::Error::from_raw_os_error(e as i32))
163    }
164
165    /// Return number of bytes already written to the internal buffer.
166    pub fn bytes_written(&self) -> usize {
167        self.buf.len()
168    }
169
170    /// Return number of bytes available for writing.
171    pub fn available_bytes(&self) -> usize {
172        self.buf.capacity() - self.buf.len()
173    }
174
175    fn account_written(&mut self, count: usize) {
176        let new_len = self.buf.len() + count;
177        // Safe because check_avail_space() ensures that `count` is valid.
178        unsafe { self.buf.set_len(new_len) };
179    }
180
181    /// Write an object to the writer.
182    pub fn write_obj<T: ByteValued>(&mut self, val: T) -> io::Result<()> {
183        self.write_all(val.as_slice())
184    }
185
186    /// Write data to the writer from a file descriptor.
187    ///
188    /// Return the number of bytes written to the writer.
189    pub fn write_from<F: FileReadWriteVolatile>(
190        &mut self,
191        mut src: F,
192        count: usize,
193    ) -> io::Result<usize> {
194        self.check_available_space(count)?;
195
196        let cnt = src.read_vectored_volatile(
197            // Safe because we have made sure buf has at least count capacity above
198            unsafe {
199                &[FileVolatileSlice::from_raw_ptr(
200                    self.buf.as_mut_ptr().add(self.buf.len()),
201                    count,
202                )]
203            },
204        )?;
205        self.account_written(cnt);
206
207        if self.buffered {
208            Ok(cnt)
209        } else {
210            Self::do_write(self.fd, &self.buf[..cnt])
211        }
212    }
213
214    /// Write data to the writer from a File at offset `off`.
215    /// Return the number of bytes written to the writer.
216    pub fn write_from_at<F: FileReadWriteVolatile>(
217        &mut self,
218        mut src: F,
219        count: usize,
220        off: u64,
221    ) -> io::Result<usize> {
222        self.check_available_space(count)?;
223
224        let cnt = src.read_vectored_at_volatile(
225            // Safe because we have made sure buf has at least count capacity above
226            unsafe {
227                &[FileVolatileSlice::from_raw_ptr(
228                    self.buf.as_mut_ptr().add(self.buf.len()),
229                    count,
230                )]
231            },
232            off,
233        )?;
234        self.account_written(cnt);
235
236        if self.buffered {
237            Ok(cnt)
238        } else {
239            Self::do_write(self.fd, &self.buf[..cnt])
240        }
241    }
242
243    /// Write all data to the writer from a file descriptor.
244    pub fn write_all_from<F: FileReadWriteVolatile>(
245        &mut self,
246        mut src: F,
247        mut count: usize,
248    ) -> io::Result<()> {
249        self.check_available_space(count)?;
250
251        while count > 0 {
252            match self.write_from(&mut src, count) {
253                Ok(0) => {
254                    return Err(io::Error::new(
255                        io::ErrorKind::WriteZero,
256                        "failed to write whole buffer",
257                    ))
258                }
259                Ok(n) => count -= n,
260                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
261                Err(e) => return Err(e),
262            }
263        }
264
265        Ok(())
266    }
267
268    fn check_available_space(&self, sz: usize) -> io::Result<()> {
269        assert!(self.buffered || self.buf.is_empty());
270        if sz > self.available_bytes() {
271            Err(io::Error::new(
272                io::ErrorKind::InvalidData,
273                format!(
274                    "data out of range, available {} requested {}",
275                    self.available_bytes(),
276                    sz
277                ),
278            ))
279        } else {
280            Ok(())
281        }
282    }
283
284    fn do_write(fd: RawFd, data: &[u8]) -> io::Result<usize> {
285        write(fd, data).map_err(|e| {
286            error! {"fail to write to fuse device fd {}: {}, {:?}", fd, e, data};
287            io::Error::other(format!("{e}"))
288        })
289    }
290}
291
292impl<S: BitmapSlice> Write for FuseDevWriter<'_, S> {
293    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
294        self.check_available_space(data.len())?;
295
296        if self.buffered {
297            self.buf.extend_from_slice(data);
298            Ok(data.len())
299        } else {
300            Self::do_write(self.fd, data).inspect(|&x| {
301                self.account_written(x);
302            })
303        }
304    }
305
306    // default write_vectored only writes the first non-empty IoSlice. Override it.
307    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
308        self.check_available_space(bufs.iter().fold(0, |acc, x| acc + x.len()))?;
309
310        if self.buffered {
311            let count = bufs.iter().filter(|b| !b.is_empty()).fold(0, |acc, b| {
312                self.buf.extend_from_slice(b);
313                acc + b.len()
314            });
315            Ok(count)
316        } else {
317            if bufs.is_empty() {
318                return Ok(0);
319            }
320            writev(self.fd, bufs)
321                .inspect(|&x| {
322                    self.account_written(x);
323                })
324                .map_err(|e| {
325                    error! {"fail to write to fuse device on commit: {}", e};
326                    io::Error::other(format!("{e}"))
327                })
328        }
329    }
330
331    /// As this writer can associate multiple writers by splitting, `flush()` can't
332    /// flush them all. Disable it!
333    fn flush(&mut self) -> io::Result<()> {
334        Err(io::Error::other("Writer does not support flush buffer."))
335    }
336}
337
338/// Extension trait for FuseSession to provide helper methods.
339pub trait FuseSessionExt {
340    /// Get the underlying file of the fuse session.
341    fn file(&self) -> Option<&std::fs::File>;
342
343    /// Get the buffer size of the fuse session.
344    fn bufsize(&self) -> usize;
345
346    /// Create a new fuse message writer and pass it to the given closure.
347    fn with_writer<F>(&mut self, f: F)
348    where
349        F: FnOnce(FuseDevWriter),
350    {
351        if let Some(file) = self.file() {
352            let fd = file.as_raw_fd();
353            let mut buf = vec![0x0u8; self.bufsize()];
354            let writer = FuseDevWriter::new(fd, &mut buf).unwrap();
355            f(writer);
356        }
357    }
358
359    /// Create a new fuse message writer and pass it to the given closure. and return the result from the closure.
360    fn try_with_writer<F, R, E>(&mut self, f: F) -> std::result::Result<R, E>
361    where
362        F: FnOnce(FuseDevWriter) -> std::result::Result<R, E>,
363        E: From<Error>,
364    {
365        if let Some(file) = self.file() {
366            let fd = file.as_raw_fd();
367            let mut buf = vec![0x0u8; self.bufsize()];
368            let writer = FuseDevWriter::new(fd, &mut buf)?;
369            f(writer)
370        } else {
371            Err(Error::SessionFailure("invalid fuse session".into()).into())
372        }
373    }
374}
375
376#[cfg(feature = "async-io")]
377mod async_io {
378    use super::*;
379    use crate::file_buf::FileVolatileBuf;
380    use crate::file_traits::AsyncFileReadWriteVolatile;
381
382    impl<'a, S: BitmapSlice> FuseDevWriter<'a, S> {
383        /// Write data from a buffer into this writer in asynchronous mode.
384        ///
385        /// Return the number of bytes written to the writer.
386        pub async fn async_write(&mut self, data: &[u8]) -> io::Result<usize> {
387            self.check_available_space(data.len())?;
388
389            if self.buffered {
390                // write to internal buf
391                self.buf.extend_from_slice(data);
392                Ok(data.len())
393            } else {
394                nix::sys::uio::pwrite(self.fd, data, 0)
395                    .map(|x| {
396                        self.account_written(x);
397                        x
398                    })
399                    .map_err(|e| {
400                        error! {"fail to write to fuse device fd {}: {}", self.fd, e};
401                        io::Error::other(format!("{}", e))
402                    })
403            }
404        }
405
406        /// Write data from two buffers into this writer in asynchronous mode.
407        ///
408        /// Return the number of bytes written to the writer.
409        pub async fn async_write2(&mut self, data: &[u8], data2: &[u8]) -> io::Result<usize> {
410            let len = data.len() + data2.len();
411            self.check_available_space(len)?;
412
413            if self.buffered {
414                // write to internal buf
415                self.buf.extend_from_slice(data);
416                self.buf.extend_from_slice(data2);
417                Ok(len)
418            } else {
419                let bufs = [IoSlice::new(data), IoSlice::new(data2)];
420                writev(self.fd, &bufs)
421                    .map(|x| {
422                        self.account_written(x);
423                        x
424                    })
425                    .map_err(|e| {
426                        error! {"fail to write to fuse device fd {}: {}", self.fd, e};
427                        io::Error::other(format!("{}", e))
428                    })
429            }
430        }
431
432        /// Write data from two buffers into this writer in asynchronous mode.
433        ///
434        /// Return the number of bytes written to the writer.
435        pub async fn async_write3(
436            &mut self,
437            data: &[u8],
438            data2: &[u8],
439            data3: &[u8],
440        ) -> io::Result<usize> {
441            let len = data.len() + data2.len() + data3.len();
442            self.check_available_space(len)?;
443
444            if self.buffered {
445                // write to internal buf
446                self.buf.extend_from_slice(data);
447                self.buf.extend_from_slice(data2);
448                self.buf.extend_from_slice(data3);
449                Ok(len)
450            } else {
451                let bufs = [IoSlice::new(data), IoSlice::new(data2), IoSlice::new(data3)];
452                writev(self.fd, &bufs)
453                    .map(|x| {
454                        self.account_written(x);
455                        x
456                    })
457                    .map_err(|e| {
458                        error! {"fail to write to fuse device fd {}: {}", self.fd, e};
459                        io::Error::other(format!("{}", e))
460                    })
461            }
462        }
463
464        /// Attempts to write an entire buffer into this writer in asynchronous mode.
465        pub async fn async_write_all(&mut self, mut buf: &[u8]) -> io::Result<()> {
466            while !buf.is_empty() {
467                match self.async_write(buf).await {
468                    Ok(0) => {
469                        return Err(io::Error::new(
470                            io::ErrorKind::WriteZero,
471                            "failed to write whole buffer",
472                        ));
473                    }
474                    Ok(n) => buf = &buf[n..],
475                    Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
476                    Err(e) => return Err(e),
477                }
478            }
479
480            Ok(())
481        }
482
483        /// Write data from a File at offset `off` to the writer in asynchronous mode.
484        ///
485        /// Return the number of bytes written to the writer.
486        pub async fn async_write_from_at<F: AsyncFileReadWriteVolatile>(
487            &mut self,
488            src: &F,
489            count: usize,
490            off: u64,
491        ) -> io::Result<usize> {
492            self.check_available_space(count)?;
493
494            let buf = unsafe { FileVolatileBuf::from_raw_ptr(self.buf.as_mut_ptr(), 0, count) };
495            let (res, _) = src.async_read_at_volatile(buf, off).await;
496            match res {
497                Ok(cnt) => {
498                    self.account_written(cnt);
499                    if self.buffered {
500                        Ok(cnt)
501                    } else {
502                        // write to fd, can only happen once per instance
503                        nix::sys::uio::pwrite(self.fd, &self.buf[..cnt], 0).map_err(|e| {
504                            error! {"fail to write to fuse device fd {}: {}", self.fd, e};
505                            io::Error::other(format!("{}", e))
506                        })
507                    }
508                }
509                Err(e) => Err(e),
510            }
511        }
512
513        /// Commit all internal buffers of the writer and others.
514        ///
515        /// We need this because the lifetime of others is usually shorter than self.
516        pub async fn async_commit(&mut self, other: Option<&Writer<'a, S>>) -> io::Result<usize> {
517            let o = match other {
518                Some(Writer::FuseDev(w)) => w.buf.as_slice(),
519                _ => &[],
520            };
521
522            let res = match (self.buf.len(), o.len()) {
523                (0, 0) => Ok(0),
524                (0, _) => nix::sys::uio::pwrite(self.fd, o, 0).map_err(|e| {
525                    error! {"fail to write to fuse device fd {}: {}", self.fd, e};
526                    io::Error::other(format!("{}", e))
527                }),
528                (_, 0) => nix::sys::uio::pwrite(self.fd, self.buf.as_slice(), 0).map_err(|e| {
529                    error! {"fail to write to fuse device fd {}: {}", self.fd, e};
530                    io::Error::other(format!("{}", e))
531                }),
532                (_, _) => {
533                    let bufs = [IoSlice::new(self.buf.as_slice()), IoSlice::new(o)];
534                    writev(self.fd, &bufs).map_err(|e| {
535                        error! {"fail to write to fuse device fd {}: {}", self.fd, e};
536                        io::Error::other(format!("{}", e))
537                    })
538                }
539            };
540
541            res.map_err(|e| {
542                error! {"fail to write to fuse device on commit: {}", e};
543                e
544            })
545        }
546    }
547}
548
549#[cfg(test)]
550mod tests {
551    use super::*;
552    use std::io::{Read, Seek, SeekFrom, Write};
553    use std::os::unix::io::AsRawFd;
554    use vmm_sys_util::tempfile::TempFile;
555
556    #[test]
557    fn reader_test_simple_chain() {
558        let mut buf = [0u8; 106];
559        let mut reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut buf)).unwrap();
560
561        assert_eq!(reader.available_bytes(), 106);
562        assert_eq!(reader.bytes_read(), 0);
563
564        let mut buffer = [0 as u8; 64];
565        if let Err(_) = reader.read_exact(&mut buffer) {
566            panic!("read_exact should not fail here");
567        }
568
569        assert_eq!(reader.available_bytes(), 42);
570        assert_eq!(reader.bytes_read(), 64);
571
572        match reader.read(&mut buffer) {
573            Err(_) => panic!("read should not fail here"),
574            Ok(length) => assert_eq!(length, 42),
575        }
576
577        assert_eq!(reader.available_bytes(), 0);
578        assert_eq!(reader.bytes_read(), 106);
579    }
580
581    #[test]
582    fn writer_test_simple_chain() {
583        let file = TempFile::new().unwrap().into_file();
584        let mut buf = vec![0x0u8; 106];
585        let mut writer = FuseDevWriter::<()>::new(file.as_raw_fd(), &mut buf).unwrap();
586
587        writer.buffered = true;
588        assert_eq!(writer.available_bytes(), 106);
589        assert_eq!(writer.bytes_written(), 0);
590
591        let mut buffer = [0 as u8; 64];
592        if let Err(_) = writer.write_all(&mut buffer) {
593            panic!("write_all should not fail here");
594        }
595
596        assert_eq!(writer.available_bytes(), 42);
597        assert_eq!(writer.bytes_written(), 64);
598
599        let mut buffer = [0 as u8; 42];
600        match writer.write(&mut buffer) {
601            Err(_) => panic!("write should not fail here"),
602            Ok(length) => assert_eq!(length, 42),
603        }
604
605        assert_eq!(writer.available_bytes(), 0);
606        assert_eq!(writer.bytes_written(), 106);
607    }
608
609    #[test]
610    fn writer_test_split_chain() {
611        let file = TempFile::new().unwrap().into_file();
612        let mut buf = vec![0x0u8; 108];
613        let mut writer = FuseDevWriter::<()>::new(file.as_raw_fd(), &mut buf).unwrap();
614        let writer2 = writer.split_at(106).unwrap();
615
616        assert_eq!(writer.available_bytes(), 106);
617        assert_eq!(writer.bytes_written(), 0);
618        assert_eq!(writer2.available_bytes(), 2);
619        assert_eq!(writer2.bytes_written(), 0);
620
621        let mut buffer = [0 as u8; 64];
622        if let Err(_) = writer.write_all(&mut buffer) {
623            panic!("write_all should not fail here");
624        }
625
626        assert_eq!(writer.available_bytes(), 42);
627        assert_eq!(writer.bytes_written(), 64);
628
629        let mut buffer = [0 as u8; 42];
630        match writer.write(&mut buffer) {
631            Err(_) => panic!("write should not fail here"),
632            Ok(length) => assert_eq!(length, 42),
633        }
634
635        assert_eq!(writer.available_bytes(), 0);
636        assert_eq!(writer.bytes_written(), 106);
637    }
638
639    #[test]
640    fn reader_unexpected_eof() {
641        let mut buf = [0u8; 106];
642        let mut reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut buf)).unwrap();
643
644        let mut buf2 = Vec::with_capacity(1024);
645        buf2.resize(1024, 0);
646
647        assert_eq!(
648            reader
649                .read_exact(&mut buf2[..])
650                .expect_err("read more bytes than available")
651                .kind(),
652            io::ErrorKind::UnexpectedEof
653        );
654    }
655
656    #[test]
657    fn reader_split_border() {
658        let mut buf = [0u8; 128];
659        let mut reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut buf)).unwrap();
660        let other = reader.split_at(32).expect("failed to split Reader");
661
662        assert_eq!(reader.available_bytes(), 32);
663        assert_eq!(other.available_bytes(), 96);
664    }
665
666    #[test]
667    fn reader_split_outofbounds() {
668        let mut buf = [0u8; 128];
669        let mut reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut buf)).unwrap();
670
671        if let Ok(_) = reader.split_at(256) {
672            panic!("successfully split Reader with out of bounds offset");
673        }
674    }
675
676    #[test]
677    fn writer_simple_commit_header() {
678        let file = TempFile::new().unwrap().into_file();
679        let mut buf = vec![0x0u8; 106];
680        let mut writer = FuseDevWriter::<()>::new(file.as_raw_fd(), &mut buf).unwrap();
681
682        writer.buffered = true;
683        assert_eq!(writer.available_bytes(), 106);
684
685        writer.write(&[0x1u8; 4]).unwrap();
686        assert_eq!(writer.available_bytes(), 102);
687        assert_eq!(writer.bytes_written(), 4);
688
689        let buf = vec![0xdeu8; 64];
690        let slices = [
691            IoSlice::new(&buf[..32]),
692            IoSlice::new(&buf[32..48]),
693            IoSlice::new(&buf[48..]),
694        ];
695        assert_eq!(
696            writer
697                .write_vectored(&slices)
698                .expect("failed to write from buffer"),
699            64
700        );
701        assert!(writer.flush().is_err());
702
703        writer.commit(None).unwrap();
704    }
705
706    #[test]
707    fn writer_split_commit_header() {
708        let file = TempFile::new().unwrap().into_file();
709        let mut buf = vec![0x0u8; 106];
710        let mut writer = FuseDevWriter::<()>::new(file.as_raw_fd(), &mut buf).unwrap();
711        let mut other = writer.split_at(4).expect("failed to split Writer");
712
713        assert_eq!(writer.available_bytes(), 4);
714        assert_eq!(other.available_bytes(), 102);
715
716        writer.write(&[0x1u8; 4]).unwrap();
717        assert_eq!(writer.available_bytes(), 0);
718        assert_eq!(writer.bytes_written(), 4);
719
720        let buf = vec![0xdeu8; 64];
721        let slices = [
722            IoSlice::new(&buf[..32]),
723            IoSlice::new(&buf[32..48]),
724            IoSlice::new(&buf[48..]),
725        ];
726        assert_eq!(
727            other
728                .write_vectored(&slices)
729                .expect("failed to write from buffer"),
730            64
731        );
732        assert!(writer.flush().is_err());
733
734        writer.commit(None).unwrap();
735    }
736
737    #[test]
738    fn writer_split_commit_all() {
739        let file = TempFile::new().unwrap().into_file();
740        let mut buf = vec![0x0u8; 106];
741        let mut writer = FuseDevWriter::<()>::new(file.as_raw_fd(), &mut buf).unwrap();
742        let mut other = writer.split_at(4).expect("failed to split Writer");
743
744        assert_eq!(writer.available_bytes(), 4);
745        assert_eq!(other.available_bytes(), 102);
746
747        writer.write(&[0x1u8; 4]).unwrap();
748        assert_eq!(writer.available_bytes(), 0);
749        assert_eq!(writer.bytes_written(), 4);
750
751        let buf = vec![0xdeu8; 64];
752        let slices = [
753            IoSlice::new(&buf[..32]),
754            IoSlice::new(&buf[32..48]),
755            IoSlice::new(&buf[48..]),
756        ];
757        assert_eq!(
758            other
759                .write_vectored(&slices)
760                .expect("failed to write from buffer"),
761            64
762        );
763
764        writer.commit(Some(&other.into())).unwrap();
765    }
766
767    #[test]
768    fn read_full() {
769        let mut buf2 = [0u8; 48];
770        let mut reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut buf2)).unwrap();
771        let mut buf = vec![0u8; 64];
772
773        assert_eq!(
774            reader.read(&mut buf[..]).expect("failed to read to buffer"),
775            48
776        );
777    }
778
779    #[test]
780    fn write_full() {
781        let file = TempFile::new().unwrap().into_file();
782        let mut buf = vec![0x0u8; 48];
783        let mut writer = FuseDevWriter::<()>::new(file.as_raw_fd(), &mut buf).unwrap();
784
785        let buf = vec![0xdeu8; 64];
786        writer.write(&buf[..]).unwrap_err();
787
788        let buf = vec![0xdeu8; 48];
789        assert_eq!(
790            writer.write(&buf[..]).expect("failed to write from buffer"),
791            48
792        );
793    }
794
795    #[test]
796    fn write_vectored() {
797        let file = TempFile::new().unwrap().into_file();
798        let mut buf = vec![0x0u8; 48];
799        let mut writer = FuseDevWriter::<()>::new(file.as_raw_fd(), &mut buf).unwrap();
800
801        let buf = vec![0xdeu8; 48];
802        let slices = [
803            IoSlice::new(&buf[..32]),
804            IoSlice::new(&buf[32..40]),
805            IoSlice::new(&buf[40..]),
806        ];
807        assert_eq!(
808            writer
809                .write_vectored(&slices)
810                .expect("failed to write from buffer"),
811            48
812        );
813    }
814
815    #[test]
816    fn read_obj() {
817        let mut buf2 = [0u8; 9];
818        let mut reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut buf2)).unwrap();
819
820        let _val: u64 = reader.read_obj().expect("failed to read to file");
821
822        assert_eq!(reader.available_bytes(), 1);
823        assert_eq!(reader.bytes_read(), 8);
824        assert!(reader.read_obj::<u64>().is_err());
825    }
826
827    #[test]
828    fn read_exact_to() {
829        let mut buf2 = [0u8; 48];
830        let mut reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut buf2)).unwrap();
831        let mut file = TempFile::new().unwrap().into_file();
832
833        reader
834            .read_exact_to(&mut file, 47)
835            .expect("failed to read to file");
836
837        assert_eq!(reader.available_bytes(), 1);
838        assert_eq!(reader.bytes_read(), 47);
839    }
840
841    #[test]
842    fn read_to_at() {
843        let mut buf2 = [0u8; 48];
844        let mut reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut buf2)).unwrap();
845        let mut file = TempFile::new().unwrap().into_file();
846
847        assert_eq!(
848            reader
849                .read_to_at(&mut file, 48, 16)
850                .expect("failed to read to file"),
851            48
852        );
853        assert_eq!(reader.available_bytes(), 0);
854        assert_eq!(reader.bytes_read(), 48);
855    }
856
857    #[test]
858    fn write_obj() {
859        let file1 = TempFile::new().unwrap().into_file();
860        let mut buf = vec![0x0u8; 48];
861        let mut writer = FuseDevWriter::<()>::new(file1.as_raw_fd(), &mut buf).unwrap();
862        let _writer2 = writer.split_at(40).unwrap();
863        let val = 0x1u64;
864
865        writer.write_obj(val).expect("failed to write from buffer");
866        assert_eq!(writer.available_bytes(), 32);
867    }
868
869    #[test]
870    fn write_all_from() {
871        let file1 = TempFile::new().unwrap().into_file();
872        let mut buf = vec![0x0u8; 48];
873        let mut writer = FuseDevWriter::<()>::new(file1.as_raw_fd(), &mut buf).unwrap();
874        let mut file = TempFile::new().unwrap().into_file();
875        let buf = vec![0xdeu8; 64];
876
877        writer.buffered = true;
878
879        file.write_all(&buf).unwrap();
880        file.seek(SeekFrom::Start(0)).unwrap();
881        writer
882            .write_all_from(&mut file, 47)
883            .expect("failed to write from buffer");
884        assert_eq!(writer.available_bytes(), 1);
885        assert_eq!(writer.bytes_written(), 47);
886
887        // Write more data than capacity
888        writer.write_all_from(&mut file, 2).unwrap_err();
889        assert_eq!(writer.available_bytes(), 1);
890        assert_eq!(writer.bytes_written(), 47);
891    }
892
893    #[test]
894    fn write_all_from_split() {
895        let file1 = TempFile::new().unwrap().into_file();
896        let mut buf = vec![0x0u8; 58];
897        let mut writer = FuseDevWriter::<()>::new(file1.as_raw_fd(), &mut buf).unwrap();
898        let _other = writer.split_at(48).unwrap();
899        let mut file = TempFile::new().unwrap().into_file();
900        let buf = vec![0xdeu8; 64];
901
902        file.write_all(&buf).unwrap();
903        file.seek(SeekFrom::Start(0)).unwrap();
904        writer
905            .write_all_from(&mut file, 47)
906            .expect("failed to write from buffer");
907        assert_eq!(writer.available_bytes(), 1);
908        assert_eq!(writer.bytes_written(), 47);
909
910        // Write more data than capacity
911        writer.write_all_from(&mut file, 2).unwrap_err();
912        assert_eq!(writer.available_bytes(), 1);
913        assert_eq!(writer.bytes_written(), 47);
914    }
915
916    #[test]
917    fn write_from_at() {
918        let file1 = TempFile::new().unwrap().into_file();
919        let mut buf = vec![0x0u8; 48];
920        let mut writer = FuseDevWriter::<()>::new(file1.as_raw_fd(), &mut buf).unwrap();
921        let mut file = TempFile::new().unwrap().into_file();
922        let buf = vec![0xdeu8; 64];
923
924        writer.buffered = true;
925
926        file.write_all(&buf).unwrap();
927        file.seek(SeekFrom::Start(0)).unwrap();
928        assert_eq!(
929            writer
930                .write_from_at(&mut file, 40, 16)
931                .expect("failed to write from buffer"),
932            40
933        );
934        assert_eq!(writer.available_bytes(), 8);
935        assert_eq!(writer.bytes_written(), 40);
936
937        // Write more data than capacity
938        writer.write_from_at(&mut file, 40, 16).unwrap_err();
939        assert_eq!(writer.available_bytes(), 8);
940        assert_eq!(writer.bytes_written(), 40);
941    }
942
943    #[test]
944    fn write_from_at_split() {
945        let file1 = TempFile::new().unwrap().into_file();
946        let mut buf = vec![0x0u8; 58];
947        let mut writer = FuseDevWriter::<()>::new(file1.as_raw_fd(), &mut buf).unwrap();
948        let _other = writer.split_at(48).unwrap();
949        let mut file = TempFile::new().unwrap().into_file();
950        let buf = vec![0xdeu8; 64];
951
952        file.write_all(&buf).unwrap();
953        file.seek(SeekFrom::Start(0)).unwrap();
954        assert_eq!(
955            writer
956                .write_from_at(&mut file, 40, 16)
957                .expect("failed to write from buffer"),
958            40
959        );
960        assert_eq!(writer.available_bytes(), 8);
961        assert_eq!(writer.bytes_written(), 40);
962
963        // Write more data than capacity
964        writer.write_from_at(&mut file, 40, 16).unwrap_err();
965        assert_eq!(writer.available_bytes(), 8);
966        assert_eq!(writer.bytes_written(), 40);
967    }
968
969    #[cfg(feature = "async-io")]
970    mod async_io {
971        use vmm_sys_util::tempdir::TempDir;
972
973        use crate::async_file::File;
974        use crate::async_runtime;
975
976        use super::*;
977
978        #[test]
979        fn async_read_to_at() {
980            let dir = TempDir::new().unwrap();
981            let path = dir.as_path().to_path_buf().join("test.txt");
982            std::fs::write(&path, b"this is a test").unwrap();
983
984            let mut buf2 = [0u8; 48];
985            let mut reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut buf2)).unwrap();
986
987            async_runtime::block_on(async {
988                let file = File::async_open(&path, true, false).await.unwrap();
989                let res = reader.async_read_to_at(&file, 48, 0).await.unwrap();
990                assert_eq!(res, 48);
991            })
992        }
993
994        #[test]
995        fn async_write() {
996            let dir = TempDir::new().unwrap();
997            let path = dir.as_path().to_path_buf().join("test.txt");
998            std::fs::write(&path, b"this is a test").unwrap();
999
1000            let file = TempFile::new().unwrap().into_file();
1001            let fd = file.as_raw_fd();
1002            let mut buf = vec![0x0u8; 48];
1003            let mut writer = FuseDevWriter::<()>::new(fd, &mut buf).unwrap();
1004            let buf = vec![0xdeu8; 64];
1005            let res = async_runtime::block_on(async { writer.async_write(&buf[..]).await });
1006            assert!(res.is_err());
1007
1008            let fd = file.as_raw_fd();
1009            let mut buf = vec![0x0u8; 48];
1010            let mut writer2 = FuseDevWriter::<()>::new(fd, &mut buf).unwrap();
1011            let buf = vec![0xdeu8; 48];
1012            let res = async_runtime::block_on(async { writer2.async_write(&buf[..]).await });
1013            assert_eq!(res.unwrap(), 48);
1014        }
1015
1016        #[test]
1017        fn async_write2() {
1018            let file = TempFile::new().unwrap().into_file();
1019            let fd = file.as_raw_fd();
1020            let mut buf = vec![0x0u8; 48];
1021            let mut writer = FuseDevWriter::<()>::new(fd, &mut buf).unwrap();
1022            let buf = vec![0xdeu8; 48];
1023            let res = async_runtime::block_on(async {
1024                writer.async_write2(&buf[..32], &buf[32..]).await
1025            });
1026            assert_eq!(res.unwrap(), 48);
1027        }
1028
1029        #[test]
1030        fn async_write3() {
1031            let file = TempFile::new().unwrap().into_file();
1032            let fd = file.as_raw_fd();
1033            let mut buf = vec![0x0u8; 48];
1034            let mut writer = FuseDevWriter::<()>::new(fd, &mut buf).unwrap();
1035            let buf = vec![0xdeu8; 48];
1036            let res = async_runtime::block_on(async {
1037                writer
1038                    .async_write3(&buf[..32], &buf[32..40], &buf[40..])
1039                    .await
1040            });
1041            assert_eq!(res.unwrap(), 48);
1042        }
1043
1044        #[test]
1045        fn async_write_from_at() {
1046            let file1 = TempFile::new().unwrap().into_file();
1047            let fd1 = file1.as_raw_fd();
1048
1049            let buf = vec![0xdeu8; 64];
1050            let dir = TempDir::new().unwrap();
1051            let path = dir.as_path().to_path_buf().join("test.txt");
1052            std::fs::write(&path, &buf).unwrap();
1053
1054            let mut buf = vec![0x0u8; 48];
1055            let mut writer = FuseDevWriter::<()>::new(fd1, &mut buf).unwrap();
1056            let res = async_runtime::block_on(async {
1057                let file = File::async_open(&path, true, false).await.unwrap();
1058                writer.async_write_from_at(&file, 40, 16).await
1059            });
1060
1061            assert_eq!(res.unwrap(), 40);
1062        }
1063
1064        #[test]
1065        fn async_writer_split_commit_all() {
1066            let file = TempFile::new().unwrap().into_file();
1067            let fd = file.as_raw_fd();
1068            let mut buf = vec![0x0u8; 106];
1069            let buf = unsafe { std::mem::transmute::<&mut [u8], &'static mut [u8]>(&mut buf) };
1070            let mut writer = FuseDevWriter::<()>::new(fd, buf).unwrap();
1071            let mut other = writer.split_at(4).expect("failed to split Writer");
1072
1073            assert_eq!(writer.available_bytes(), 4);
1074            assert_eq!(other.available_bytes(), 102);
1075
1076            writer.write(&[0x1u8; 4]).unwrap();
1077            assert_eq!(writer.available_bytes(), 0);
1078            assert_eq!(writer.bytes_written(), 4);
1079
1080            let buf = vec![0xdeu8; 64];
1081            let slices = [
1082                IoSlice::new(&buf[..32]),
1083                IoSlice::new(&buf[32..48]),
1084                IoSlice::new(&buf[48..]),
1085            ];
1086            assert_eq!(
1087                other
1088                    .write_vectored(&slices)
1089                    .expect("failed to write from buffer"),
1090                64
1091            );
1092
1093            let res =
1094                async_runtime::block_on(async { writer.async_commit(Some(&other.into())).await });
1095            let _ = res.unwrap();
1096        }
1097    }
1098}