Construct a thread safe backing file reader.
(bf: BackingFile)
| 148 | |
| 149 | /// Construct a thread safe backing file reader. |
| 150 | pub fn shared_backing_from(bf: BackingFile) -> BlockResult<Arc<dyn BackingRead>> { |
| 151 | let (kind, virtual_size) = bf.into_kind(); |
| 152 | |
| 153 | let dup_fd = |fd: BorrowedFd<'_>| -> BlockResult<OwnedFd> { |
| 154 | fd.try_clone_to_owned().map_err(|e| { |
| 155 | BlockError::new( |
| 156 | BlockErrorKind::Io, |
| 157 | QcowError::BackingFileIo(String::new(), e), |
| 158 | ) |
| 159 | .with_op(ErrorOp::DupBackingFd) |
| 160 | }) |
| 161 | }; |
| 162 | |
| 163 | match kind { |
| 164 | BackingKind::Raw(raw_file) => { |
| 165 | let fd = dup_fd(raw_file.as_fd())?; |
| 166 | Ok(Arc::new(RawBacking { fd, virtual_size })) |
| 167 | } |
| 168 | BackingKind::Qcow { inner, backing } => { |
| 169 | let data_fd = dup_fd(inner.raw_file.as_fd())?; |
| 170 | let metadata = Arc::new(QcowMetadata::new(*inner)); |
| 171 | Ok(Arc::new(Qcow2Backing { |
| 172 | cluster_size: metadata.cluster_size(), |
| 173 | decoder: metadata.decoder(), |
| 174 | metadata, |
| 175 | data_fd, |
| 176 | backing_file: backing.map(|bf| shared_backing_from(*bf)).transpose()?, |
| 177 | })) |
| 178 | } |
| 179 | #[cfg(test)] |
| 180 | BackingKind::QcowFile(_) => { |
| 181 | unreachable!("QcowFile variant is only used by set_backing_file() in tests") |
| 182 | } |
| 183 | } |
| 184 | } |