Commit Graph

41 Commits

Author SHA1 Message Date
Wei Liu
2fe775fce2 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>
2026-05-14 22:35:02 +00:00
Dylan Reid
6b44e7b190 block: raw_async: reject batch atomically when SQ lacks capacity
submit_batch_requests pushed each BatchRequest into the io_uring SQ in
turn and used `?` to bail on the first push failure.
Leaving the initial SQEs visible to the kernel — but submitter.submit()
was never called, and every other call site in this file gates submit()
behind a preceding sq.push() that now also fails on the full ring.

This could allow a guest to DoS it's own queue or worse if the buffer is
freed early.

Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-05-14 19:53:22 +00:00
Keith Adler
f3263d0988 block: preserve async queue push errors
Keep the underlying io_uring submission queue push error in raw async
I/O paths instead of replacing it with a generic full-queue message.

Signed-off-by: Keith Adler <kadler@cloudflare.com>
2026-05-07 16:37:57 +00:00
Anatol Belski
701767e5be block: Use RawDisk in factory, remove old wrappers
Update open_raw to construct RawDisk instead of choosing between
RawFileDisk, RawFileDiskSync and RawFileDiskAio. The backend decision
is now made inside RawDisk::create_async_io.

Remove the DiskFile wrapper structs from raw_sync.rs, raw_async.rs
and raw_async_aio.rs. Only the AsyncIo worker structs remain in those
files. Reduce their module visibility to pub(crate).

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-23 20:15:49 +00:00
Anatol Belski
21cd13df01 block: Rename AsyncDiskFile::new_async_io to create_async_io
The new_ prefix in Rust conventionally denotes constructors that return
Self (e.g. Vec::new(), File::new()). AsyncDiskFile::new_async_io does
not return Self. It is a factory method that constructs and returns a
Box<dyn AsyncIo> worker bound to the disk file descriptor and
metadata. The create_ prefix communicates this: the caller receives
a freshly constructed object of a different type.

This rename touches every format backend in block plus two external
callers in virtio-devices and performance-metrics. Every change is a
mechanical s/new_async_io/create_async_io/ substitution. No functional
change.

Ref: #7877 (task 3.2.8)
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-21 10:36:52 +00:00
Anatol Belski
7294ca99cf block: raw: Return BlockResult from RawFileAsync::new
Change RawFileAsync::new() from std::io::Result to BlockResult,
aligning it with RawFileAsyncAio::new(). Each fallible call inside
the constructor now maps to BlockErrorKind::Io explicitly.

FixedVhdAsync::new() follows the same change since its only
fallible operation is constructing a RawFileAsync. The intermediate
DiskFileError::NewAsyncIo wrapping in both new_async_io() call
sites is no longer needed and is removed.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-20 18:09:27 +00:00
Vincent Thomas
fd8ded9d78 block: Fix resize for block device backends
Block devices (LVM volumes, loop devices, RBD, etc.) cannot be resized
via ftruncate - they are resized externally. When vm.resize-disk is
called for a block device backend, verify the device size matches the
requested size instead of attempting ftruncate.

This enables the resize-disk API to work with block device backends by
validating the externally-resized device matches the expected size.

Signed-off-by: Vincent Thomas <vincent@v-thomas.com>
2026-04-17 07:57:35 +00:00
Muminul Islam
573f3af77d vmm: Switch RawFileDisk to DiskBackend::Next
Update device_manager.rs to construct DiskBackend::Next
instead of DiskBackend::Legacy for the io_uring raw backend.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Muminul Islam
491c5493c5 block: Implement AsyncDiskFile trait for RawFileDisk
Add disk_file::AsyncDiskFile trait implementation for
RawFileDisk with try_clone() and new_async_io() methods.

try_clone() duplicates the underlying file descriptor and
wraps it in a new RawFileDisk. new_async_io() creates a
RawFileAsync (io_uring) backend, wrapping errors in
BlockError instead of DiskFileError.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Muminul Islam
607a2c769d block: Implement DiskFile marker trait for RawFileDisk
Add empty disk_file::DiskFile impl for RawFileDisk. This
marker supertrait requires DiskSize + Geometry + Sync, all
of which are now satisfied.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Muminul Islam
64b65caddd block: Implement Resizable trait for RawFileDisk
Add disk_file::Resizable trait implementation for
RawFileDisk. Calls file.set_len(size) and wraps the I/O
error in BlockError on failure.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Muminul Islam
899dec4c04 block: Implement SparseCapable trait for RawFileDisk
Add disk_file::SparseCapable trait implementation for
RawFileDisk. Delegates to probe_sparse_support() to detect
whether the underlying file supports hole-punching.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Muminul Islam
7e514d8d0e block: Implement Geometry trait for RawFileDisk
Add disk_file::Geometry trait implementation for RawFileDisk.
Probes disk topology from the file, falling back to defaults
on failure. Takes &self instead of &mut self and uses
unwrap_or_else for cleaner error handling.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Muminul Islam
ca1f48a717 block: Implement DiskFd trait for RawFileDisk
Add disk_file::DiskFd trait implementation for RawFileDisk.
Delegates to file.as_raw_fd() via BorrowedDiskFd, taking
&self instead of &mut self.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Muminul Islam
aa6a7aea0e block: Implement PhysicalSize trait for RawFileDisk
Add disk_file::PhysicalSize trait implementation for
RawFileDisk. Returns metadata().len() wrapped in BlockError
on failure, consistent with the DiskSize impl.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Muminul Islam
0647202215 block: Implement DiskSize trait for RawFileDisk
Add disk_file::DiskSize trait implementation for RawFileDisk
using BlockError and BlockResult. Uses metadata().len()
instead of seek(SeekFrom::End(0)), taking &self instead of
&mut self.

Add BlockError, BlockErrorKind, BlockResult, and disk_file
imports needed by this and subsequent trait impls.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Muminul Islam
4586ca133a block: Derive Debug on RawFileDisk
Add #[derive(Debug)] to RawFileDisk. This is required by the
new disk_file traits which have Send + Debug bounds.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Anatol Belski
f14e2d2b40 block: raw_async: Use query_device_size() for size queries
Use query_device_size() instead of seek(End(0)) and metadata().len()
to correctly handle block device and regular file handles.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-27 11:05:07 +00:00
Anatol Belski
1733e08a0f block: raw: Replace FALLOC_FL_* consts with libc::* in raw backends
raw_sync, raw_async, and raw_async_aio each defined
FALLOC_FL_PUNCH_HOLE, FALLOC_FL_KEEP_SIZE, and FALLOC_FL_ZERO_RANGE as
local constants in their punch_hole() and write_zeroes()
implementations. These are available from the libc crate directly.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-14 14:00:29 +00:00
Anatol Belski
b7b38df99c block: raw: Use map_or instead of map().unwrap_or()
Do the necessary replacements to satisfy clippy::map_unwrap_or.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-06 12:32:38 +00:00
Saravanan D
00c05f4761 block: Use logical block size for alignment
O_DIRECT requires buffer addresses to be aligned to the backend
device's logical block size. The existing bounce buffer logic in
execute_async() hardcodes SECTOR_SIZE (512) for the alignment check
and bounce buffer allocation. This is insufficient for devices with
a 4096-byte logical block size, where misaligned buffers cause
-EINVAL from the host kernel.

Add an alignment() method to the AsyncIo trait that returns the
backend's logical block size, defaulting to SECTOR_SIZE. The three
raw I/O backends (io_uring, AIO, synchronous) probe the device
topology via DiskTopology::probe() at creation time and return the
actual logical block size. All image format backends would simply
use the default value of 512 bytes since their underlying are
not block devices.

execute_async() now queries disk_image.alignment() instead of using
the hardcoded SECTOR_SIZE

Fixes: #7720

Signed-off-by: Saravanan D <saravanand@crusoe.ai>
2026-02-26 15:47:17 +00:00
Anatol Belski
45b115aeb0 block: raw: Implement punch_hole and write_zeroes
Implement punch_hole() and write_zeroes() for raw file backends using
io_uring and fallocate.

punch_hole() uses FALLOC_FL_PUNCH_HOLE to deallocate storage.
write_zeroes() uses FALLOC_FL_ZERO_RANGE to write zeros efficiently.

Both use FALLOC_FL_KEEP_SIZE to maintain file size.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-13 18:44:30 +00:00
Anatol Belski
7f4b56b217 block: Add sparse operations capability query
Add capability query to DiskFile trait to check backend
support for sparse operations (punch hole, write zeroes,
discard). Only advertise VIRTIO_BLK_F_DISCARD and
VIRTIO_BLK_F_WRITE_ZEROES when the backend supports these
operations.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-13 18:44:30 +00:00
Anatol Belski
7095605d84 block: Add punch_hole and write_zeroes to AsyncIo trait
Add punch_hole() and write_zeroes() methods to the AsyncIo trait
with stub implementations for all backends. These will be used to
support DISCARD and WRITE_ZEROES operations.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-13 18:44:30 +00:00
Thomas Prescher
aac240d076 block: raw_async: implement disk resizing
Support for resize events for raw_async disks.

On-behalf-of: SAP thomas.prescher@sap.com
Signed-off-by: Thomas Prescher <thomas.prescher@cyberus-technology.de>
2025-12-17 13:54:52 +00:00
Philipp Schuster
603b5e862c block: add DiskFile::physical_size()
This is a pre-requisite for the bug fix in the following commit.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-12-14 17:02:36 +00:00
Philipp Schuster
53092359b4 block: rename DiskFile::size() -> DiskFile::logical_size()
This better reflects the actual usage.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-12-14 17:02:36 +00:00
Philipp Schuster
5f66a26b2e misc: block: drop extern crate, use modern rust
This commit is part of a series of similar commits.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-24 22:36:46 +00:00
Philipp Schuster
b4c62bf159 misc: clippy: add semicolon_if_nothing_returned
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-21 09:32:11 +00:00
Philipp Schuster
363273111a build: treewide: fmt for edition 2024
`cargo +nightly fmt`

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Muminul Islam
c4bab33020 block: Enable request submission in batch when using io_uring
Implement the batch submission function for raw disk, default it is
enabled. After parsing the requests this method is
called for better IO latency and bandwidth.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-02 16:29:25 +00:00
Jinank Jain
2bc8d51a60 misc: Fix missing lifetime syntax clippy warning
This was caught by the nightly compiler during cargo fuzz build.

error: lifetime flowing from input to output with different syntax can be confusing
   --> /home/runner/work/cloud-hypervisor/cloud-hypervisor/hypervisor/src/arch/x86/emulator/mod.rs:493:26
    |
493 |     pub fn new(platform: &mut dyn PlatformEmulator<CpuState = T>) -> Emulator<T> {
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     ----------- the lifetime gets resolved as `'_`
    |                          |
    |                          this lifetime flows to the output
    |
    = note: `-D mismatched-lifetime-syntaxes` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(mismatched_lifetime_syntaxes)]`
help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
    |
493 |     pub fn new(platform: &mut dyn PlatformEmulator<CpuState = T>) -> Emulator<'_, T> {

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2025-06-09 11:19:11 +00:00
Philipp Schuster
2da5e10689 block: bind FD lifetime of DiskFile
As we can't use BorrowedFd, we should at least create a similar
safe alternative.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-05-16 08:07:32 +00:00
Philipp Schuster
a647d7863c block: enable to get a raw FD of each block device's DiskFile
This is a prerequisite for the next steps.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-05-16 08:07:32 +00:00
Wei Liu
57e331db0e block: drop the ASYNC flag from io_uring entries
The ASYNC flag forces requests to go to worker threads. Worker threads
are expensive. Let the kernel decide what to do.

With this change, I no longer see an excessive amount of io_uring worker
threads.

Quote from the manual for io_uring_sqe_set_flags(3):

```
   IOSQE_ASYNC
          Normal operation for io_uring is to try and issue an sqe
          as non-blocking first, and if that fails, execute it in an
          async manner. To support more efficient overlapped
          operation of requests that the application knows/assumes
          will always (or most of the time) block, the application
          can ask for an sqe to be issued async from the start. Note
          that this flag immediately causes the SQE to be offloaded
          to an async helper thread with no initial non-blocking
          attempt.  This may be less efficient and should not be
          used liberally or without understanding the performance
          and efficiency tradeoffs.
```

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-21 10:47:29 +00:00
Wei Liu
090fcebfec block: do not ignore failures when pushing to io_uring submission queue
Instead of silently ignoring the error, return an error to the callers.

This in practice should never happen, because the submission queue size
(ring depth) is the same as the virtio queue size. Virtio queue won't
push more requests than there are submission queue entries.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-21 10:47:29 +00:00
Rob Bradford
88a9f79944 misc: Adapt consistent import style formatting
Historically the Cloud Hypervisor coding style has been to ensure that
all imports are ordered and placed in a single group. Unfortunately
cargo fmt has no support for ensuring that all imports are in a single
group so if whitespace lines were added as part of the import statements
then they would only be odered correctly in the group.

By adopting "group_imports="StdExternalCrate" we can enforce a style
where imports are placed in at most three groups for std, external
crates and the crate itself. Choosing a style enforceable by the tooling
reduces the reviewer burden.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-09-29 13:08:12 +01:00
Rob Bradford
9ca2c336f2 block: Move DiskTopology to common code
It doens't make sense to limit this to the async_io module and import
across modules so place in default create module.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-09-05 13:09:49 -07:00
Rob Bradford
11c58870c4 block: async_io: Remove unnecessary mut from reference
warning: this argument is a mutable reference, but not used mutably
  --> block/src/async_io.rs:68:28
   |
68 |     fn query_block_size(f: &mut File, block_size_type: BlockSize) -> std::io::Result<u64> {
   |                            ^^^^^^^^^ help: consider changing to: `&File`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-22 12:01:54 +01:00
dependabot[bot]
fe97785a9f build: Bump io-uring from 0.5.13 to 0.6.0
Includes fixes for changed function prototypes.

bumps [io-uring](https://github.com/tokio-rs/io-uring) from 0.5.13 to 0.6.0.
- [Commits](https://github.com/tokio-rs/io-uring/commits)

---
updated-dependencies:
- dependency-name: io-uring
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2023-08-01 14:27:54 +01:00
Yu Li
447cad3861 block: merge qcow, vhdx and block_util into block crate
This commit merges crates `qcow`, `vhdx` and `block_util` into the
crate `block`, which can allow `qcow` to use functions from `block_util`
without introducing a circular crate dependency.

This commit is based on crosvm implementation:
f2eecc4152

Signed-off-by: Yu Li <liyu.yukiteru@bytedance.com>
2023-07-19 13:52:43 +01:00