Skip to content

Commit 9149ac4

Browse files
committed
virtio/block: implement support for F_WRITE_ZEROES
The F_WRITE_ZEROES feature enables the guest to instruct the host to write zeroes to the disk image without actually having to copy any data around. Since imago does the heavy lifting for us, we just need to announce the feature and call to the right method when needed. Signed-off-by: Sergio Lopez <[email protected]>
1 parent 6a3686a commit 9149ac4

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

src/devices/src/virtio/block/device.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ impl Block {
277277
| (1u64 << VIRTIO_BLK_F_FLUSH)
278278
| (1u64 << VIRTIO_BLK_F_SEG_MAX)
279279
| (1u64 << VIRTIO_BLK_F_DISCARD)
280+
| (1u64 << VIRTIO_BLK_F_WRITE_ZEROES)
280281
| (1u64 << VIRTIO_RING_F_EVENT_IDX);
281282

282283
if is_disk_read_only {
@@ -295,6 +296,9 @@ impl Block {
295296
max_discard_sectors: u32::MAX,
296297
max_discard_seg: 1,
297298
discard_sector_alignment: discard_alignment as u32 / 512,
299+
max_write_zeroes_sectors: u32::MAX,
300+
max_write_zeroes_seg: 1,
301+
write_zeroes_may_unmap: 1,
298302
..Default::default()
299303
};
300304

src/devices/src/virtio/block/worker.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ use vm_memory::{ByteValued, GuestMemoryMmap};
1717
#[derive(Debug)]
1818
pub enum RequestError {
1919
Discarding(io::Error),
20+
DiscardingToZero(io::Error),
2021
FlushingToDisk(io::Error),
2122
InvalidDataLength,
2223
ReadingFromDescriptor(io::Error),
2324
WritingToDescriptor(io::Error),
25+
WritingZeroes(io::Error),
2426
UnknownRequest,
2527
}
2628

@@ -272,6 +274,34 @@ impl BlockWorker {
272274
.map_err(RequestError::Discarding)?;
273275
Ok(0)
274276
}
277+
VIRTIO_BLK_T_WRITE_ZEROES => {
278+
let discard_write_data: DiscardWriteData = reader
279+
.read_obj()
280+
.map_err(RequestError::ReadingFromDescriptor)?;
281+
let unmap = (discard_write_data.flags & VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP) != 0;
282+
if unmap {
283+
self.disk
284+
.file
285+
.lock()
286+
.unwrap()
287+
.discard_to_zero(
288+
discard_write_data.sector * 512,
289+
discard_write_data.num_sectors as u64 * 512,
290+
)
291+
.map_err(RequestError::DiscardingToZero)?;
292+
} else {
293+
self.disk
294+
.file
295+
.lock()
296+
.unwrap()
297+
.write_zeroes(
298+
discard_write_data.sector * 512,
299+
discard_write_data.num_sectors as u64 * 512,
300+
)
301+
.map_err(RequestError::WritingZeroes)?;
302+
}
303+
Ok(0)
304+
}
275305
_ => Err(RequestError::UnknownRequest),
276306
}
277307
}

0 commit comments

Comments
 (0)