vhost_user_fs: Add support for indirect descriptors

Now that Queue supports indirect descriptors, expose the feature and
support them in vhost_user_fs too.

Signed-off-by: Sergio Lopez <slp@redhat.com>
This commit is contained in:
Sergio Lopez
2020-02-21 11:54:35 +01:00
committed by Rob Bradford
parent ea0bc240fd
commit eae4f1d249
2 changed files with 23 additions and 3 deletions
+4 -1
View File
@@ -25,6 +25,7 @@ use vhost_user_fs::passthrough::{self, PassthroughFs};
use vhost_user_fs::server::Server; use vhost_user_fs::server::Server;
use vhost_user_fs::Error as VhostUserFsError; use vhost_user_fs::Error as VhostUserFsError;
use virtio_bindings::bindings::virtio_net::*; use virtio_bindings::bindings::virtio_net::*;
use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_INDIRECT_DESC;
use vm_memory::GuestMemoryMmap; use vm_memory::GuestMemoryMmap;
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
@@ -138,7 +139,9 @@ impl<F: FileSystem + Send + Sync + 'static> VhostUserBackend for VhostUserFsBack
} }
fn features(&self) -> u64 { fn features(&self) -> u64 {
1 << VIRTIO_F_VERSION_1 | VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits() 1 << VIRTIO_F_VERSION_1
| 1 << VIRTIO_RING_F_INDIRECT_DESC
| VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits()
} }
fn protocol_features(&self) -> VhostUserProtocolFeatures { fn protocol_features(&self) -> VhostUserProtocolFeatures {
+19 -2
View File
@@ -15,6 +15,7 @@ use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap, Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap,
GuestMemoryRegion, Le16, Le32, Le64, VolatileMemory, VolatileMemoryError, VolatileSlice, GuestMemoryRegion, Le16, Le32, Le64, VolatileMemory, VolatileMemoryError, VolatileSlice,
}; };
use vm_virtio::queue::Error as QueueError;
use vm_virtio::DescriptorChain; use vm_virtio::DescriptorChain;
use crate::file_traits::{FileReadWriteAtVolatile, FileReadWriteVolatile}; use crate::file_traits::{FileReadWriteAtVolatile, FileReadWriteVolatile};
@@ -25,6 +26,7 @@ pub enum Error {
FindMemoryRegion, FindMemoryRegion,
GuestMemoryError(GuestMemoryError), GuestMemoryError(GuestMemoryError),
InvalidChain, InvalidChain,
ConvertIndirectDescriptor(QueueError),
IoError(io::Error), IoError(io::Error),
SplitOutOfBounds(usize), SplitOutOfBounds(usize),
VolatileMemoryError(VolatileMemoryError), VolatileMemoryError(VolatileMemoryError),
@@ -35,6 +37,7 @@ impl Display for Error {
use self::Error::*; use self::Error::*;
match self { match self {
ConvertIndirectDescriptor(e) => write!(f, "invalid indirect descriptor: {}", e),
DescriptorChainOverflow => write!( DescriptorChainOverflow => write!(
f, f,
"the combined length of all the buffers in a `DescriptorChain` would overflow" "the combined length of all the buffers in a `DescriptorChain` would overflow"
@@ -191,7 +194,14 @@ impl<'a> Reader<'a> {
/// Construct a new Reader wrapper over `desc_chain`. /// Construct a new Reader wrapper over `desc_chain`.
pub fn new(mem: &'a GuestMemoryMmap, desc_chain: DescriptorChain<'a>) -> Result<Reader<'a>> { pub fn new(mem: &'a GuestMemoryMmap, desc_chain: DescriptorChain<'a>) -> Result<Reader<'a>> {
let mut total_len: usize = 0; let mut total_len: usize = 0;
let buffers = desc_chain let chain = if desc_chain.is_indirect() {
desc_chain
.new_from_indirect()
.map_err(Error::ConvertIndirectDescriptor)?
} else {
desc_chain
};
let buffers = chain
.into_iter() .into_iter()
.readable() .readable()
.map(|desc| { .map(|desc| {
@@ -343,7 +353,14 @@ impl<'a> Writer<'a> {
/// Construct a new Writer wrapper over `desc_chain`. /// Construct a new Writer wrapper over `desc_chain`.
pub fn new(mem: &'a GuestMemoryMmap, desc_chain: DescriptorChain<'a>) -> Result<Writer<'a>> { pub fn new(mem: &'a GuestMemoryMmap, desc_chain: DescriptorChain<'a>) -> Result<Writer<'a>> {
let mut total_len: usize = 0; let mut total_len: usize = 0;
let buffers = desc_chain let chain = if desc_chain.is_indirect() {
desc_chain
.new_from_indirect()
.map_err(Error::ConvertIndirectDescriptor)?
} else {
desc_chain
};
let buffers = chain
.into_iter() .into_iter()
.writable() .writable()
.map(|desc| { .map(|desc| {