(
features: u64,
request: &Request,
disable_sector0_writes: bool,
)
| 175 | |
| 176 | impl BlockEpollHandler { |
| 177 | fn check_request( |
| 178 | features: u64, |
| 179 | request: &Request, |
| 180 | disable_sector0_writes: bool, |
| 181 | ) -> result::Result<(), ExecuteError> { |
| 182 | let request_type = request.request_type(); |
| 183 | if (has_feature(features, VIRTIO_BLK_F_RO.into())) |
| 184 | && !(request_type == RequestType::In |
| 185 | || request_type == RequestType::GetDeviceId |
| 186 | || request_type == RequestType::Flush) |
| 187 | { |
| 188 | // For virtio spec compliance |
| 189 | // "A device MUST set the status byte to VIRTIO_BLK_S_IOERR for a write request |
| 190 | // if the VIRTIO_BLK_F_RO feature if offered, and MUST NOT write any data." |
| 191 | warn!( |
| 192 | "Rejecting block request {request_type:?}: device is read-only (VIRTIO_BLK_F_RO negotiated)" |
| 193 | ); |
| 194 | return Err(ExecuteError::ReadOnly); |
| 195 | } |
| 196 | |
| 197 | if request_type == RequestType::Out && disable_sector0_writes && request.sector() == 0 { |
| 198 | warn!("Attempting to write to sector 0 on a disk without specifying image_type"); |
| 199 | return Err(ExecuteError::ReadOnly); |
| 200 | } |
| 201 | |
| 202 | Ok(()) |
| 203 | } |
| 204 | |
| 205 | // A spec-compliant driver never reuses a virtqueue head_index while the |
| 206 | // corresponding chain is still available (virtio 1.x §2.7.13.4). |
nothing calls this directly
no test coverage detected