mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user