block: use BLKDISCARD/BLKZEROOUT ioctls for block devices

Some block devices (ZFS volume) may require BLKDISCARD and BLKZEROOUT
ioctls for discard and write_zeroes operations respectively.

There is no good way to probe whether fallocate is supported on a block
device. Arguably, punch_hole and write_zeroes are rare. Instead of
having a complex scheme for the IO uring backend, we force it to always
use ioctls. The code can be changed if the synchronized ioctls become a
performance issue.

Changes:
- Detect block devices at construction time
- Use BLKDISCARD ioctl for punch_hole (discard) on block devices
- Use BLKZEROOUT ioctl for write_zeroes on block devices
- Add BLKDISCARD/BLKZEROOUT to VirtioBlock seccomp whitelist
- Keep fallocate() path for regular files (no behavior change)
- Consolidate some helper functions to the new sparse module

Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
Wei Liu
2026-05-12 16:07:27 +00:00
committed by Bo Chen
parent 12919dbce9
commit 2fe775fce2
6 changed files with 185 additions and 79 deletions

View File

@@ -4,6 +4,7 @@
//
// SPDX-License-Identifier: Apache-2.0
use block::{BLKDISCARD, BLKZEROOUT};
use libc::{FIONBIO, TIOCGWINSZ, TUNSETOFFLOAD};
use seccompiler::SeccompCmpOp::Eq;
use seccompiler::{
@@ -113,8 +114,7 @@ fn virtio_block_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
(libc::SYS_fsync, vec![]),
(libc::SYS_ftruncate, vec![]),
(libc::SYS_getrandom, vec![]),
#[cfg(feature = "sev_snp")]
(libc::SYS_ioctl, create_mshv_sev_snp_ioctl_seccomp_rule()),
(libc::SYS_ioctl, create_virtio_block_ioctl_seccomp_rule()),
(libc::SYS_io_destroy, vec![]),
(libc::SYS_io_getevents, vec![]),
(libc::SYS_io_submit, vec![]),
@@ -131,6 +131,15 @@ fn virtio_block_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
]
}
fn create_virtio_block_ioctl_seccomp_rule() -> Vec<SeccompRule> {
or![
and![Cond::new(1, ArgLen::Dword, Eq, BLKDISCARD as _).unwrap()],
and![Cond::new(1, ArgLen::Dword, Eq, BLKZEROOUT as _).unwrap()],
#[cfg(feature = "sev_snp")]
mshv_sev_snp_ioctl_seccomp_rule(),
]
}
fn virtio_console_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
vec![
(libc::SYS_ioctl, create_virtio_console_ioctl_seccomp_rule()),