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