MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / parse

Method parse

block/src/request.rs:85–181  ·  view source on GitHub ↗
(
        desc_chain: &mut DescriptorChain<GuestMemoryLoadGuard<vm_memory::GuestMemoryMmap<B>>>,
        access_platform: Option<&dyn AccessPlatform>,
    )

Source from the content-addressed store, hash-verified

83
84impl Request {
85 pub fn parse<B: Bitmap + 'static>(
86 desc_chain: &mut DescriptorChain<GuestMemoryLoadGuard<vm_memory::GuestMemoryMmap<B>>>,
87 access_platform: Option<&dyn AccessPlatform>,
88 ) -> Result<Request, Error> {
89 let hdr_desc = desc_chain
90 .next()
91 .ok_or(Error::DescriptorChainTooShort)
92 .inspect_err(|_| {
93 error!("Missing head descriptor");
94 })?;
95
96 // The head contains the request type which MUST be readable.
97 if hdr_desc.is_write_only() {
98 return Err(Error::UnexpectedWriteOnlyDescriptor);
99 }
100
101 let hdr_desc_addr = hdr_desc
102 .addr()
103 .translate_gva(access_platform, hdr_desc.len() as usize)
104 .map_err(|e| Error::GuestMemory(GuestMemoryError::IOError(e)))?;
105
106 let mut req = Request {
107 request_type: request_type(desc_chain.memory(), hdr_desc_addr)?,
108 sector: sector(desc_chain.memory(), hdr_desc_addr)?,
109 data_descriptors: SmallVec::with_capacity(DEFAULT_DESCRIPTOR_VEC_SIZE),
110 status_addr: GuestAddress(0),
111 writeback: true,
112 aligned_operations: SmallVec::with_capacity(DEFAULT_DESCRIPTOR_VEC_SIZE),
113 start: Instant::now(),
114 };
115
116 let status_desc;
117 let mut desc = desc_chain
118 .next()
119 .ok_or(Error::DescriptorChainTooShort)
120 .inspect_err(|_| {
121 error!("Only head descriptor present: request = {req:?}");
122 })?;
123
124 if desc.has_next() {
125 req.data_descriptors.reserve_exact(1);
126 while desc.has_next() {
127 if desc.is_write_only() && req.request_type == RequestType::Out {
128 return Err(Error::UnexpectedWriteOnlyDescriptor);
129 }
130 if desc.is_write_only() && req.request_type == RequestType::Discard {
131 return Err(Error::UnexpectedWriteOnlyDescriptor);
132 }
133 if desc.is_write_only() && req.request_type == RequestType::WriteZeroes {
134 return Err(Error::UnexpectedWriteOnlyDescriptor);
135 }
136 if !desc.is_write_only() && req.request_type == RequestType::In {
137 return Err(Error::UnexpectedReadOnlyDescriptor);
138 }
139 if !desc.is_write_only() && req.request_type == RequestType::GetDeviceId {
140 return Err(Error::UnexpectedReadOnlyDescriptor);
141 }
142

Callers 1

Calls 8

request_typeFunction · 0.85
sectorFunction · 0.85
memoryMethod · 0.80
nextMethod · 0.45
translate_gvaMethod · 0.45
addrMethod · 0.45
lenMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected