diff --git a/block/src/lib.rs b/block/src/lib.rs index c02b315cc..2c8556c39 100644 --- a/block/src/lib.rs +++ b/block/src/lib.rs @@ -621,15 +621,18 @@ impl Request { } let mut wz_sector = [0u8; 8]; - let mut wz_num_sectors = [0u8; 4]; + let mut wz_flags = [0u8; 4]; mem.read_slice(&mut wz_sector, data_addr) .map_err(ExecuteError::Read)?; mem.read_slice(&mut wz_num_sectors, data_addr.checked_add(8).unwrap()) .map_err(ExecuteError::Read)?; + mem.read_slice(&mut wz_flags, data_addr.checked_add(12).unwrap()) + .map_err(ExecuteError::Read)?; let wz_sector = u64::from_le_bytes(wz_sector); let wz_num_sectors = u32::from_le_bytes(wz_num_sectors); + let wz_flags = u32::from_le_bytes(wz_flags); let wz_offset = wz_sector * SECTOR_SIZE; if wz_offset == 0 && disable_sector0_writes { @@ -637,9 +640,15 @@ impl Request { } let wz_length = (wz_num_sectors as u64) * SECTOR_SIZE; - disk_image - .write_zeroes(wz_offset, wz_length, user_data) - .map_err(ExecuteError::AsyncWriteZeroes)?; + if wz_flags & VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP != 0 { + disk_image + .punch_hole(wz_offset, wz_length, user_data) + .map_err(ExecuteError::AsyncPunchHole)?; + } else { + disk_image + .write_zeroes(wz_offset, wz_length, user_data) + .map_err(ExecuteError::AsyncWriteZeroes)?; + } } RequestType::Unsupported(t) => return Err(ExecuteError::Unsupported(t)), }