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

Method try_map_read

block/src/qcow/metadata.rs:355–430  ·  view source on GitHub ↗

Fast path read mapping under read lock only. Returns None on cache miss. All access here is through shared reference. CacheMap::get, VecCache::get and index operations are all shared reference compatible.

(
        &self,
        address: u64,
        count: usize,
        has_backing_file: bool,
    )

Source from the content-addressed store, hash-verified

353 /// All access here is through shared reference. CacheMap::get,
354 /// VecCache::get and index operations are all shared reference compatible.
355 fn try_map_read(
356 &self,
357 address: u64,
358 count: usize,
359 has_backing_file: bool,
360 ) -> io::Result<Option<ClusterReadMapping>> {
361 if address >= self.header.size {
362 return Err(io::Error::from_raw_os_error(EINVAL));
363 }
364
365 let l1_index = self.l1_table_index(address) as usize;
366 let l2_addr_disk = match self.l1_table.get(l1_index) {
367 Some(&addr) => addr,
368 None => return Err(io::Error::from_raw_os_error(EINVAL)),
369 };
370
371 if l2_addr_disk == 0 {
372 return Ok(Some(self.unallocated_read_mapping(
373 address,
374 count,
375 has_backing_file,
376 )));
377 }
378
379 let l2_table = match self.l2_cache.get(l1_index) {
380 Some(table) => table,
381 None => return Ok(None), // cache miss, need write lock
382 };
383
384 let l2_index = self.l2_table_index(address) as usize;
385 let l2_entry = l2_table[l2_index];
386
387 // Compressed entries: extract layout from L2 entry under read lock.
388 // The caller reads and decompresses on its own fd without holding
389 // the metadata lock.
390 if l2_entry_is_compressed(l2_entry) {
391 let (host_offset, compressed_size) =
392 l2_entry_compressed_cluster_layout(l2_entry, self.header.cluster_bits);
393 let cluster_offset = self.raw_file.cluster_offset(address) as usize;
394 return Ok(Some(ClusterReadMapping::Compressed {
395 host_offset,
396 compressed_size,
397 cluster_offset,
398 length: count,
399 }));
400 }
401
402 if l2_entry_is_empty(l2_entry) {
403 Ok(Some(self.unallocated_read_mapping(
404 address,
405 count,
406 has_backing_file,
407 )))
408 } else if l2_entry_is_zero(l2_entry) {
409 // Match original QcowFile::file_read semantics where zero flagged
410 // entries fall through to backing file when one exists or return
411 // zeros otherwise.
412 Ok(Some(self.unallocated_read_mapping(

Callers 2

map_clusters_for_readMethod · 0.80
map_cluster_readMethod · 0.80

Calls 11

l2_entry_is_compressedFunction · 0.85
l2_entry_is_emptyFunction · 0.85
l2_entry_is_zeroFunction · 0.85
cluster_offsetMethod · 0.80
l1_table_indexMethod · 0.45
getMethod · 0.45
l2_table_indexMethod · 0.45
cluster_sizeMethod · 0.45

Tested by

no test coverage detected