diff options
Diffstat (limited to 'devices/src/virtio/block.rs')
-rw-r--r-- | devices/src/virtio/block.rs | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/devices/src/virtio/block.rs b/devices/src/virtio/block.rs index 30cf4f7..c9dda55 100644 --- a/devices/src/virtio/block.rs +++ b/devices/src/virtio/block.rs @@ -20,6 +20,7 @@ use sync::Mutex; use sys_util::Error as SysError; use sys_util::Result as SysResult; use sys_util::{error, info, iov_max, warn, EventFd, GuestMemory, PollContext, PollToken, TimerFd}; +use virtio_sys::virtio_ring::VIRTIO_RING_F_EVENT_IDX; use vm_control::{DiskControlCommand, DiskControlResponseSocket, DiskControlResult}; use super::{ @@ -298,13 +299,13 @@ impl Worker { queue_index: usize, flush_timer: &mut TimerFd, flush_timer_armed: &mut bool, - ) -> bool { + ) { let queue = &mut self.queues[queue_index]; let disk_size = self.disk_size.lock(); - let mut needs_interrupt = false; while let Some(avail_desc) = queue.pop(&self.mem) { + queue.set_notify(&self.mem, false); let desc_index = avail_desc.index; let len = match Worker::process_one_request( @@ -325,10 +326,9 @@ impl Worker { }; queue.add_used(&self.mem, desc_index, len as u32); - needs_interrupt = true; + queue.trigger_interrupt(&self.mem, &self.interrupt); + queue.set_notify(&self.mem, true); } - - needs_interrupt } fn resize(&mut self, new_size: u64) -> DiskControlResult { @@ -344,14 +344,14 @@ impl Worker { return DiskControlResult::Err(SysError::new(libc::EIO)); } - if !self.sparse { - // Allocate new space if the disk image is not sparse. - if let Err(e) = self.disk_image.allocate(0, new_size) { - error!("Allocating disk space after resize failed! {}", e); - return DiskControlResult::Err(SysError::new(libc::EIO)); - } + // Allocate new space if the disk image is not sparse. + if let Err(e) = self.disk_image.allocate(0, new_size) { + error!("Allocating disk space after resize failed! {}", e); + return DiskControlResult::Err(SysError::new(libc::EIO)); } + self.sparse = false; + if let Ok(new_disk_size) = self.disk_image.get_len() { let mut disk_size = self.disk_size.lock(); *disk_size = new_disk_size; @@ -419,9 +419,7 @@ impl Worker { error!("failed reading queue EventFd: {}", e); break 'poll; } - if self.process_queue(0, &mut flush_timer, &mut flush_timer_armed) { - self.interrupt.signal_used_queue(self.queues[0].vector); - } + self.process_queue(0, &mut flush_timer, &mut flush_timer_armed); } Token::ControlRequest => { let req = match self.control_socket.recv() { @@ -513,6 +511,7 @@ impl Block { } let mut avail_features: u64 = 1 << VIRTIO_BLK_F_FLUSH; + avail_features |= 1 << VIRTIO_RING_F_EVENT_IDX; if read_only { avail_features |= 1 << VIRTIO_BLK_F_RO; } else { @@ -627,7 +626,8 @@ impl Block { } VIRTIO_BLK_T_DISCARD | VIRTIO_BLK_T_WRITE_ZEROES => { if req_type == VIRTIO_BLK_T_DISCARD && !sparse { - return Err(ExecuteError::Unsupported(req_type)); + // Discard is a hint; if this is a non-sparse disk, just ignore it. + return Ok(()); } while reader.available_bytes() >= size_of::<virtio_blk_discard_write_zeroes>() { @@ -873,8 +873,8 @@ mod tests { let b = Block::new(Box::new(f), false, true, 512, None).unwrap(); // writable device should set VIRTIO_BLK_F_FLUSH + VIRTIO_BLK_F_DISCARD // + VIRTIO_BLK_F_WRITE_ZEROES + VIRTIO_F_VERSION_1 + VIRTIO_BLK_F_BLK_SIZE - // + VIRTIO_BLK_F_SEG_MAX - assert_eq!(0x100006244, b.features()); + // + VIRTIO_BLK_F_SEG_MAX + VIRTIO_RING_F_EVENT_IDX + assert_eq!(0x120006244, b.features()); } // read-write block device, non-sparse @@ -883,8 +883,8 @@ mod tests { let b = Block::new(Box::new(f), false, false, 512, None).unwrap(); // writable device should set VIRTIO_BLK_F_FLUSH // + VIRTIO_BLK_F_WRITE_ZEROES + VIRTIO_F_VERSION_1 + VIRTIO_BLK_F_BLK_SIZE - // + VIRTIO_BLK_F_SEG_MAX - assert_eq!(0x100004244, b.features()); + // + VIRTIO_BLK_F_SEG_MAX + VIRTIO_RING_F_EVENT_IDX + assert_eq!(0x120004244, b.features()); } // read-only block device @@ -893,7 +893,8 @@ mod tests { let b = Block::new(Box::new(f), true, true, 512, None).unwrap(); // read-only device should set VIRTIO_BLK_F_FLUSH and VIRTIO_BLK_F_RO // + VIRTIO_F_VERSION_1 + VIRTIO_BLK_F_BLK_SIZE + VIRTIO_BLK_F_SEG_MAX - assert_eq!(0x100000264, b.features()); + // + VIRTIO_RING_F_EVENT_IDX + assert_eq!(0x120000264, b.features()); } } |