ext2: Use memory offset instead of block id for mmaping info

ext2's mmaping information is used to perform mmap() in crosvm's main
process. Previously, the struct has a block id field so we needed to
calculate the offset by multiplying block size.
Instead, the struct now contains memory offset for convenience.

BUG=b:329359333
TEST=run VM on workstation with pmem-ext2

Change-Id: I845fc021c715a4b490e80142823855832fe3bc41
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5771636
Commit-Queue: Keiichi Watanabe <keiichiw@chromium.org>
Reviewed-by: Takaya Saeki <takayas@chromium.org>
This commit is contained in:
Keiichi Watanabe 2024-08-08 20:03:44 +09:00 committed by crosvm LUCI
parent c7a790d1cf
commit 0d2ad4007e
2 changed files with 15 additions and 15 deletions

View file

@ -168,8 +168,8 @@ impl BlockId {
/// Information on how to mmap a host file to ext2 blocks. /// Information on how to mmap a host file to ext2 blocks.
pub struct FileMappingInfo { pub struct FileMappingInfo {
/// The ext2 disk block id that the memory region maps to. /// Offset in the memory that a file is mapped to.
pub start_block: BlockId, pub mem_offset: usize,
/// The file to be mmap'd. /// The file to be mmap'd.
pub file: File, pub file: File,
/// The length of the mapping. /// The length of the mapping.
@ -205,18 +205,17 @@ impl<'a> Arena<'a> {
} }
/// A helper function to mark a region as reserved. /// A helper function to mark a region as reserved.
fn reserve(&self, block: BlockId, block_offset: usize, len: usize) -> Result<()> { fn reserve(&self, mem_offset: usize, len: usize) -> Result<()> {
let offset = u32::from(block) as usize * self.block_size + block_offset; let mem_end = mem_offset.checked_add(len).context("mem_end overflow")?;
let mem_end = offset.checked_add(len).context("mem_end overflow")?;
if mem_end > self.mem.size() { if mem_end > self.mem.size() {
bail!( bail!(
"out of memory region: {offset} + {len} > {}", "out of memory region: {mem_offset} + {len} > {}",
self.mem.size() self.mem.size()
); );
} }
self.regions.borrow_mut().allocate(offset, len)?; self.regions.borrow_mut().allocate(mem_offset, len)?;
Ok(()) Ok(())
} }
@ -226,14 +225,14 @@ impl<'a> Arena<'a> {
/// `into_mapping_info()` to retrieve the mapping information and call mmap later instead. /// `into_mapping_info()` to retrieve the mapping information and call mmap later instead.
pub fn reserve_for_mmap( pub fn reserve_for_mmap(
&self, &self,
start_block: BlockId, mem_offset: usize,
length: usize, length: usize,
file: File, file: File,
file_offset: usize, file_offset: usize,
) -> Result<()> { ) -> Result<()> {
self.reserve(start_block, 0, length)?; self.reserve(mem_offset, length)?;
self.mappings.borrow_mut().push(FileMappingInfo { self.mappings.borrow_mut().push(FileMappingInfo {
start_block, mem_offset,
length, length,
file: file.try_clone()?, file: file.try_clone()?,
file_offset, file_offset,
@ -250,9 +249,9 @@ impl<'a> Arena<'a> {
block_offset: usize, block_offset: usize,
len: usize, len: usize,
) -> Result<&'a mut [u8]> { ) -> Result<&'a mut [u8]> {
self.reserve(block, block_offset, len)?;
let offset = u32::from(block) as usize * self.block_size + block_offset; let offset = u32::from(block) as usize * self.block_size + block_offset;
self.reserve(offset, len)?;
let new_addr = (self.mem.as_ptr() as usize) let new_addr = (self.mem.as_ptr() as usize)
.checked_add(offset) .checked_add(offset)
.context("address overflow")?; .context("address overflow")?;

View file

@ -482,10 +482,11 @@ impl<'a> Ext2<'a> {
} }
let length = std::cmp::min(remaining, BLOCK_SIZE * blocks.len()); let length = std::cmp::min(remaining, BLOCK_SIZE * blocks.len());
let start_block = blocks[0]; let start_block = blocks[0];
let mem_offset = u32::from(start_block) as usize * BLOCK_SIZE;
// Reserve the region in arena to prevent from overwriting metadata. // Reserve the region in arena to prevent from overwriting metadata.
arena arena
.reserve_for_mmap( .reserve_for_mmap(
start_block, mem_offset,
length, length,
file.try_clone().context("failed to clone file")?, file.try_clone().context("failed to clone file")?,
file_offset, file_offset,
@ -814,14 +815,14 @@ pub fn create_ext2_region(cfg: &Config, src_dir: Option<&Path>) -> Result<Memory
mem.msync()?; mem.msync()?;
let mut mmap_arena = MemoryMappingArena::from(mem); let mut mmap_arena = MemoryMappingArena::from(mem);
for FileMappingInfo { for FileMappingInfo {
start_block, mem_offset,
file, file,
length, length,
file_offset, file_offset,
} in file_mappings } in file_mappings
{ {
mmap_arena.add_fd_mapping( mmap_arena.add_fd_mapping(
u32::from(start_block) as usize * BLOCK_SIZE, mem_offset,
length, length,
&file, &file,
file_offset as u64, /* fd_offset */ file_offset as u64, /* fd_offset */