Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/vmm/src/devices/virtio/block/virtio/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,9 +722,12 @@ impl VirtioBlock {
}

fn drain_and_flush(&mut self, discard: bool) {
if let Err(err) = self.disk.file_engine.drain_and_flush(discard) {
error!("Failed to drain ops and flush block data: {:?}", err);
}
// If draining and/or flushing failed, hard crash to avoid continuing with a potentially
// not consistent underlying filesystem in the disk.
self.disk
.file_engine
.drain_and_flush(discard)
.expect("virtio-block: failed to drain ops and flush block data");
Comment thread
bchalios marked this conversation as resolved.
}

/// Prepare device for being snapshotted.
Expand Down
53 changes: 33 additions & 20 deletions src/vmm/src/io_uring/queue/submission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

use std::fmt::Debug;
use std::io::Error as IOError;
use std::io::{Error as IOError, ErrorKind};
use std::mem;
use std::num::Wrapping;
use std::os::unix::io::RawFd;
Expand Down Expand Up @@ -130,26 +130,39 @@ impl SubmissionQueue {
if min_complete > 0 {
flags |= generated::IORING_ENTER_GETEVENTS;
}
// SAFETY: Safe because values are valid and we check the return value.
let submitted = SyscallReturnCode(unsafe {
libc::syscall(
libc::SYS_io_uring_enter,
self.io_uring_fd,
self.to_submit,
min_complete,
flags,
std::ptr::null::<libc::sigset_t>(),
)
})
.into_result()?;
// It's safe to convert to u32 since the syscall didn't return an error.
let submitted = u32::try_from(submitted).unwrap();

// This is safe since submitted <= self.to_submit. However we use a saturating_sub
// for extra safety.
self.to_submit = self.to_submit.saturating_sub(submitted);

Ok(submitted)
// The number of retries is completely arbitrary here. I assume that this
// will happen rarely and that if it happens subsequent retry will immediately
// succeed. If we fall in a storm of interrupts something else is probably wrong
// so let the consumer know.
let mut eintr_retries = 3;
loop {
// SAFETY: Safe because values are valid and we check the return value.
let ret = SyscallReturnCode(unsafe {
libc::syscall(
libc::SYS_io_uring_enter,
self.io_uring_fd,
self.to_submit,
min_complete,
flags,
std::ptr::null::<libc::sigset_t>(),
)
})
.into_result();
match ret {
Ok(num) => {
// It's safe to convert to u32 since the syscall didn't return an error.
let submitted = u32::try_from(num).unwrap();
self.to_submit = self.to_submit.saturating_sub(submitted);
return Ok(submitted);
}
Err(err) if err.kind() == ErrorKind::Interrupted && eintr_retries > 0 => {
eintr_retries -= 1;
continue;
Comment thread
kalyazin marked this conversation as resolved.
}
Err(err) => return Err(SQueueError::from(err)),
}
}
}

fn mmap(
Expand Down
Loading