1use 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
39pub const FUSE_KERN_BUF_PAGES: usize = 256;
42pub const FUSE_HEADER_SIZE: usize = 0x1000;
44
45#[derive(Debug)]
47pub struct FuseBuf<'a> {
48 mem: &'a mut [u8],
49}
50
51impl<'a> FuseBuf<'a> {
52 pub fn new(mem: &'a mut [u8]) -> FuseBuf<'a> {
54 FuseBuf { mem }
55 }
56}
57
58impl<'a, S: BitmapSlice + Default> Reader<'a, S> {
59 pub fn from_fuse_buffer(buf: FuseBuf<'a>) -> Result<Reader<'a, S>> {
63 let mut buffers: VecDeque<VolatileSlice<'a, S>> = VecDeque::new();
64 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#[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 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 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 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 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 pub fn bytes_written(&self) -> usize {
166 self.buf.len()
167 }
168
169 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 unsafe { self.buf.set_len(new_len) };
178 }
179
180 pub fn write_obj<T: ByteValued>(&mut self, val: T) -> io::Result<()> {
182 self.write_all(val.as_slice())
183 }
184
185 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}