diff --git a/simulator/runner/memory/file.rs b/simulator/runner/memory/file.rs index ffa0b8fd6..a5b956cc4 100644 --- a/simulator/runner/memory/file.rs +++ b/simulator/runner/memory/file.rs @@ -94,6 +94,31 @@ impl MemorySimFile { sum.into() }) } + + fn insert_op(&self, op: OperationType) { + self.callbacks.lock().push(Operation { + time: self.generate_latency(), + op, + }); + } + + pub fn write_buf(&self, buf: &[u8], offset: usize) -> usize { + let mut file_buf = self.buffer.borrow_mut(); + let more_space = if file_buf.len() < offset { + (offset + buf.len()) - file_buf.len() + } else { + buf.len().saturating_sub(file_buf.len() - offset) + }; + if more_space > 0 { + file_buf.reserve(more_space); + for _ in 0..more_space { + file_buf.push(0); + } + } + + file_buf[offset..][0..buf.len()].copy_from_slice(buf); + buf.len() + } } impl File for MemorySimFile { @@ -113,10 +138,7 @@ impl File for MemorySimFile { completion: c.clone(), offset: pos, }; - self.callbacks.lock().push(Operation { - time: self.generate_latency(), - op, - }); + self.insert_op(op); Ok(c) } @@ -133,10 +155,26 @@ impl File for MemorySimFile { completion: c.clone(), offset: pos, }; - self.callbacks.lock().push(Operation { - time: self.generate_latency(), - op, - }); + self.insert_op(op); + Ok(c) + } + + fn pwritev( + &self, + pos: usize, + buffers: Vec>, + c: Completion, + ) -> Result { + if buffers.len() == 1 { + return self.pwrite(pos, buffers[0].clone(), c); + } + let op = OperationType::WriteV { + fd: self.fd.clone(), + buffers, + completion: c.clone(), + offset: pos, + }; + self.insert_op(op); Ok(c) } @@ -146,10 +184,7 @@ impl File for MemorySimFile { fd: self.fd.clone(), completion: c.clone(), }; - self.callbacks.lock().push(Operation { - time: self.generate_latency(), - op, - }); + self.insert_op(op); Ok(c) } @@ -165,10 +200,7 @@ impl File for MemorySimFile { completion: c.clone(), len, }; - self.callbacks.lock().push(Operation { - time: self.generate_latency(), - op, - }); + self.insert_op(op); Ok(c) } } diff --git a/simulator/runner/memory/io.rs b/simulator/runner/memory/io.rs index e1597100f..03e1ad0e1 100644 --- a/simulator/runner/memory/io.rs +++ b/simulator/runner/memory/io.rs @@ -26,6 +26,12 @@ pub enum OperationType { completion: Completion, offset: usize, }, + WriteV { + fd: Arc, + buffers: Vec>, + completion: Completion, + offset: usize, + }, Sync { fd: Arc, completion: Completion, @@ -42,6 +48,7 @@ impl OperationType { match self { OperationType::Read { fd, .. } | OperationType::Write { fd, .. } + | OperationType::WriteV { fd, .. } | OperationType::Sync { fd, .. } | OperationType::Truncate { fd, .. } => fd, } @@ -81,25 +88,26 @@ impl Operation { offset, } => { let file = files.get(fd.as_str()).unwrap(); - let buf_size = { - let mut file_buf = file.buffer.borrow_mut(); - let buf = buffer.as_slice(); - let more_space = if file_buf.len() < offset { - (offset + buf.len()) - file_buf.len() - } else { - buf.len().saturating_sub(file_buf.len() - offset) - }; - if more_space > 0 { - file_buf.reserve(more_space); - for _ in 0..more_space { - file_buf.push(0); - } - } - - file_buf[offset..][0..buf.len()].copy_from_slice(buf); - buf.len() as i32 - }; - completion.complete(buf_size); + let buf_size = file.write_buf(buffer.as_slice(), offset); + completion.complete(buf_size as i32); + } + OperationType::WriteV { + fd, + buffers, + completion, + offset, + } => { + if buffers.is_empty() { + return; + } + let file = files.get(fd.as_str()).unwrap(); + let mut pos = offset; + let written = buffers.into_iter().fold(0, |written, buffer| { + let buf_size = file.write_buf(buffer.as_slice(), pos); + pos += buf_size; + written + buf_size + }); + completion.complete(written as i32); } OperationType::Sync { completion, .. } => { // There is no Sync for in memory