1use 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
40pub const FUSE_KERN_BUF_PAGES: usize = 256;
43pub const FUSE_HEADER_SIZE: usize = 0x1000;
45
46#[derive(Debug)]
48pub struct FuseBuf<'a> {
49 mem: &'a mut [u8],
50}
51
52impl<'a> FuseBuf<'a> {
53 pub fn new(mem: &'a mut [u8]) -> FuseBuf<'a> {
55 FuseBuf { mem }
56 }
57}
58
59impl<'a, S: BitmapSlice + Default> Reader<'a, S> {
60 pub fn from_fuse_buffer(buf: FuseBuf<'a>) -> Result<Reader<'a, S>> {
64 let mut buffers: VecDeque<VolatileSlice<'a, S>> = VecDeque::new();
65 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#[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 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 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 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 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 pub fn bytes_written(&self) -> usize {
167 self.buf.len()
168 }
169
170 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 unsafe { self.buf.set_len(new_len) };
179 }
180
181 pub fn write_obj<T: ByteValued>(&mut self, val: T) -> io::Result<()> {
183 self.write_all(val.as_slice())
184 }
185
186 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 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 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 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 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 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 fn flush(&mut self) -> io::Result<()> {
334 Err(io::Error::other("Writer does not support flush buffer."))
335 }
336}
337
338pub trait FuseSessionExt {
340 fn file(&self) -> Option<&std::fs::File>;
342
343 fn bufsize(&self) -> usize;
345
346 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}