Skip to content

Commit

Permalink
block: Error out on write/flush if device is read-only
Browse files Browse the repository at this point in the history
TEST=Boot cloud-hypervisor with read-only block device and observe that
writes generate errors in the EFI/boot loader code but the OS continues
to boot.

Fixes: #209

Signed-off-by: Rob Bradford <[email protected]>
  • Loading branch information
rbradford authored and retrage committed Nov 15, 2022
1 parent a7bc284 commit 7f2ebd8
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ struct UsedElem {
pub struct VirtioBlockDevice<'a> {
transport: &'a mut dyn VirtioTransport,
state: RefCell<DriverState>,
read_only: bool,
}

#[repr(C)]
Expand Down Expand Up @@ -147,12 +148,14 @@ impl<'a> VirtioBlockDevice<'a> {
VirtioBlockDevice {
transport,
state: RefCell::new(DriverState::default()),
read_only: false,
}
}

pub fn init(&mut self) -> Result<(), VirtioError> {
const VIRTIO_SUBSYSTEM_BLOCK: u32 = 0x2;
const VIRTIO_F_VERSION_1: u64 = 1 << 32;
const VIRTIO_BLK_F_RO: u64 = 1 << 5;

const VIRTIO_STATUS_RESET: u32 = 0;
const VIRTIO_STATUS_ACKNOWLEDGE: u32 = 1;
Expand Down Expand Up @@ -181,8 +184,11 @@ impl<'a> VirtioBlockDevice<'a> {
return Err(VirtioError::LegacyOnly);
}

// Detect if device is read-only
self.read_only = (device_features & VIRTIO_BLK_F_RO) == VIRTIO_BLK_F_RO;

// Don't support any advanced features for now
let supported_features = VIRTIO_F_VERSION_1;
let supported_features = VIRTIO_F_VERSION_1 | VIRTIO_BLK_F_RO;

// Report driver features
self.transport
Expand Down Expand Up @@ -329,10 +335,16 @@ impl<'a> SectorRead for VirtioBlockDevice<'a> {

impl<'a> SectorWrite for VirtioBlockDevice<'a> {
fn write(&self, sector: u64, data: &mut [u8]) -> Result<(), Error> {
if self.read_only {
return Err(Error::BlockNotSupported);
}
self.request(sector, Some(data), RequestType::Write)
}

fn flush(&self) -> Result<(), Error> {
if self.read_only {
return Err(Error::BlockNotSupported);
}
self.request(0, None, RequestType::Flush)
}
}

0 comments on commit 7f2ebd8

Please sign in to comment.