virtiofs_opendal/
buffer.rs1use std::cell::RefCell;
19use std::cmp::min;
20use std::ptr;
21
22use vm_memory::bitmap::BitmapSlice;
23use vm_memory::VolatileSlice;
24
25use crate::error::*;
26
27pub trait ReadWriteAtVolatile<B: BitmapSlice> {
29 fn read_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> Result<usize>;
30 fn write_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> Result<usize>;
31}
32
33impl<B: BitmapSlice, T: ReadWriteAtVolatile<B> + ?Sized> ReadWriteAtVolatile<B> for &T {
34 fn read_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> Result<usize> {
35 (**self).read_vectored_at_volatile(bufs)
36 }
37
38 fn write_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> Result<usize> {
39 (**self).write_vectored_at_volatile(bufs)
40 }
41}
42
43pub struct BufferWrapper {
45 buffer: RefCell<opendal::Buffer>,
46}
47
48impl BufferWrapper {
49 pub fn new(buffer: opendal::Buffer) -> BufferWrapper {
50 BufferWrapper {
51 buffer: RefCell::new(buffer),
52 }
53 }
54
55 pub fn get_buffer(&self) -> opendal::Buffer {
56 return self.buffer.borrow().clone();
57 }
58}
59
60impl<B: BitmapSlice> ReadWriteAtVolatile<B> for BufferWrapper {
61 fn read_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> Result<usize> {
62 let slice_guards: Vec<_> = bufs.iter().map(|s| s.ptr_guard_mut()).collect();
63 let iovecs: Vec<_> = slice_guards
64 .iter()
65 .map(|s| libc::iovec {
66 iov_base: s.as_ptr() as *mut libc::c_void,
67 iov_len: s.len() as libc::size_t,
68 })
69 .collect();
70 if iovecs.is_empty() {
71 return Ok(0);
72 }
73 let data = self.buffer.borrow().to_vec();
74 let mut result = 0;
75 for (index, iovec) in iovecs.iter().enumerate() {
76 let num = min(data.len() - result, iovec.iov_len);
77 if num == 0 {
78 break;
79 }
80 unsafe {
81 ptr::copy_nonoverlapping(data[result..].as_ptr(), iovec.iov_base as *mut u8, num)
82 }
83 bufs[index].bitmap().mark_dirty(0, num);
84 result += num;
85 }
86 Ok(result)
87 }
88
89 fn write_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> Result<usize> {
90 let slice_guards: Vec<_> = bufs.iter().map(|s| s.ptr_guard()).collect();
91 let iovecs: Vec<_> = slice_guards
92 .iter()
93 .map(|s| libc::iovec {
94 iov_base: s.as_ptr() as *mut libc::c_void,
95 iov_len: s.len() as libc::size_t,
96 })
97 .collect();
98 if iovecs.is_empty() {
99 return Ok(0);
100 }
101 let len = iovecs.iter().map(|iov| iov.iov_len).sum();
102 let mut data = vec![0; len];
103 let mut offset = 0;
104 for iov in iovecs.iter() {
105 unsafe {
106 ptr::copy_nonoverlapping(
107 iov.iov_base as *const u8,
108 data.as_mut_ptr().add(offset),
109 iov.iov_len,
110 );
111 }
112 offset += iov.iov_len;
113 }
114 *self.buffer.borrow_mut() = opendal::Buffer::from(data);
115 Ok(len)
116 }
117}