vhost_user_block: fix process_queue unwraps

process_queue() unwrapped four guest-reachable Results.

Convert each unwrap to a logged error path. A failed status write is
demoted to len = 0 so the head is still retired via add_used; an
add_used failure breaks the batch (queue is in a bad state); a
needs_notification failure  signals; a signal failure is logged. The
daemon stays up.

Signed-off-by: Dylan Reid <dgreid@fb.com>
This commit is contained in:
Dylan Reid
2026-04-24 17:14:17 -07:00
committed by Rob Bradford
parent 1f0a78b766
commit 3fc0ff00d5

View File

@@ -141,11 +141,16 @@ impl VhostUserBlkThread {
Ok(l) => (VIRTIO_BLK_S_OK as u8, l + 1), Ok(l) => (VIRTIO_BLK_S_OK as u8, l + 1),
Err(e) => (e.status(), 1), Err(e) => (e.status(), 1),
}; };
desc_chain
.memory() if let Err(e) = desc_chain.memory().write_obj(status, request.status_addr()) {
.write_obj(status, request.status_addr()) warn!(
.unwrap(); "vhost-user-blk: failed to write status to 0x{:x}: {e:?}",
len request.status_addr().0
);
0
} else {
len
}
} }
Err(err) => { Err(err) => {
error!("failed to parse available descriptor chain: {err:?}"); error!("failed to parse available descriptor chain: {err:?}");
@@ -153,32 +158,44 @@ impl VhostUserBlkThread {
} }
}; };
vring if let Err(e) =
.get_queue_mut() vring
.add_used(desc_chain.memory(), desc_chain.head_index(), len) .get_queue_mut()
.unwrap(); .add_used(desc_chain.memory(), desc_chain.head_index(), len)
{
error!("vhost-user-blk: add_used failed: {e:?}");
// Stop processing this batch — the queue is in a bad state.
break;
}
used_descs = true; used_descs = true;
} }
let mut needs_signalling = false; let needs_signalling = if self.event_idx {
if self.event_idx { match vring
if vring
.get_queue_mut() .get_queue_mut()
.needs_notification(self.mem.memory().deref()) .needs_notification(self.mem.memory().deref())
.unwrap()
{ {
debug!("signalling queue"); Ok(true) => {
needs_signalling = true; debug!("signalling queue");
} else { true
debug!("omitting signal (event_idx)"); }
Ok(false) => {
debug!("omitting signal (event_idx)");
false
}
Err(e) => {
error!("vhost-user-blk: needs_notification failed: {e:?}");
// Just signal — the guest can re-check.
true
}
} }
} else { } else {
debug!("signalling queue"); debug!("signalling queue");
needs_signalling = true; true
} };
if needs_signalling { if needs_signalling && let Err(e) = vring.signal_used_queue() {
vring.signal_used_queue().unwrap(); error!("vhost-user-blk: signal_used_queue failed: {e:?}");
} }
used_descs used_descs