From: Kevin Wolf <kwolf@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-block@nongnu.org, hreitz@redhat.com,
manos.pitsidianakis@linaro.org, qemu-devel@nongnu.org,
qemu-rust@nongnu.org
Subject: Re: [PATCH 09/11] rust/block: Add read support for block drivers
Date: Wed, 12 Feb 2025 21:52:25 +0100 [thread overview]
Message-ID: <Z60KCVt38X59J9TN@redhat.com> (raw)
In-Reply-To: <f515a321-8f76-4d94-97d5-309fba14aa85@redhat.com>
Am 12.02.2025 um 16:05 hat Paolo Bonzini geschrieben:
> On 2/11/25 22:43, Kevin Wolf wrote:
> > +/// A request to a block driver
> > +pub enum Request {
> > + Read { offset: u64, len: u64 },
> > +}
> > +
>
> Maybe add flags already?
> > +#[allow(dead_code)]
> > +pub enum MappingTarget {
> > + /// The described blocks are unallocated. Reading from them yields zeros.
> > + Unmapped,
> > +
> > + /// The described blocks are stored in a child node.
> > + Data {
> > + /// Child node in which the data is stored
> > + node: (),
>
> Make it already a *mut BlockDriverState, or *mut BdrvChild? Or are you worried of
> irritating the borrow checker? :)
Mostly I just didn't need it yet and was too lazy to think about the
details.
The right type would probably be Arc<driver::BdrvChild> (which contains
the raw *mut pointer). But I haven't thought much about how this plays
together with graph changes.
> > + /// Offset in the child node at which the data is stored
> > + offset: u64,
> > + },
> > +}
> > +
> > +/// A mapping for a number of contiguous guest blocks
> > +pub struct Mapping {
> > + /// Offset of the mapped blocks from the perspective of the guest
> > + pub offset: u64,
> > + /// Length of the mapping in bytes
> > + pub len: u64,
> > + /// Where the data for the described blocks is stored
> > + pub target: MappingTarget,
> > +}
> > +
> > /// A trait for writing block drivers.
> > ///
> > /// Types that implement this trait can be registered as QEMU block drivers using the
> > @@ -37,6 +72,11 @@ unsafe fn open(
> > /// Returns the size of the image in bytes
> > fn size(&self) -> u64;
> > +
> > + /// Returns the mapping for the first part of `req`. If the returned mapping is shorter than
> > + /// the request, the function can be called again with a shortened request to get the mapping
> > + /// for the remaining part.
> > + async fn map(&self, req: &Request) -> io::Result<Mapping>;
>
> I am not sure I like the idea of making this the only way to do a read.
We'll clearly need a way for drivers to have explicit functions when the
blocks aren't just mapped to somewhere else, e.g. with compression or
encryption. (My idea for that was that it would be another MappingTarget
branch.)
But using map() as the primary interface is intentional as it enables a
few things, even though this isn't visible in the code yet. Of course,
that basically every block driver duplicates the same loop is a reason
to unify it, but as you say there are other ways to do that.
One thing map() can do in the common case is provide the caller just a
list of mappings to a file descriptor and an offset. This may in the
future allow some block exports like ublk or fuse to use zero copy
operations. You can't do that if the block driver already does an
explicit read into a buffer.
You can cache mappings outside of the block driver and even of QEMU.
Block exports could tell the kernel that it shouldn't even bother with
going to userspace if a request can be completed using a cached mapping.
Two hosts with shared storage could access the same qcow2 image without
one of them sending all data across the network (like we did in KubeSAN
with NBD), but it's enough if metadata (= mappings) are synchronised.
So I think this is a useful interface to have, even if we don't know
which of the possibilities we'll actually make use of. And it should be
the primary interface, because if you want to do caching, then cache
invalidation must be done properly by block drivers, which is more
likely to go wrong if it's just an additional interface that isn't
normally used.
Kevin
next prev parent reply other threads:[~2025-02-12 20:53 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-11 21:43 [PATCH 00/11] rust/block: Add minimal block driver bindings Kevin Wolf
2025-02-11 21:43 ` [PATCH 01/11] rust: Build separate qemu_api_tools and qemu_api_system Kevin Wolf
2025-02-12 10:01 ` Paolo Bonzini
2025-02-12 15:29 ` Kevin Wolf
2025-02-12 16:59 ` Paolo Bonzini
2025-02-11 21:43 ` [PATCH 02/11] meson: Add rust_block_ss and link tools with it Kevin Wolf
2025-02-12 7:38 ` Philippe Mathieu-Daudé
2025-02-11 21:43 ` [PATCH 03/11] rust: Add some block layer bindings Kevin Wolf
2025-02-12 9:29 ` Paolo Bonzini
2025-02-12 13:13 ` Kevin Wolf
2025-02-12 13:47 ` Paolo Bonzini
2025-02-12 15:13 ` Kevin Wolf
2025-02-12 17:16 ` Paolo Bonzini
2025-02-12 19:52 ` Kevin Wolf
2025-02-13 11:06 ` Paolo Bonzini
2025-02-11 21:43 ` [PATCH 04/11] rust/qemu-api: Add wrappers to run futures in QEMU Kevin Wolf
2025-02-12 9:28 ` Paolo Bonzini
2025-02-12 12:47 ` Kevin Wolf
2025-02-12 13:22 ` Paolo Bonzini
2025-02-18 17:25 ` Kevin Wolf
2025-02-11 21:43 ` [PATCH 05/11] rust/block: Add empty crate Kevin Wolf
2025-02-11 21:43 ` [PATCH 06/11] rust/block: Add I/O buffer traits Kevin Wolf
2025-02-12 16:48 ` Paolo Bonzini
2025-02-12 17:22 ` Kevin Wolf
2025-02-12 17:41 ` Paolo Bonzini
2025-02-11 21:43 ` [PATCH 07/11] block: Add bdrv_open_blockdev_ref_file() Kevin Wolf
2025-02-12 7:43 ` Philippe Mathieu-Daudé
2025-02-11 21:43 ` [PATCH 08/11] rust/block: Add driver module Kevin Wolf
2025-02-12 16:43 ` Paolo Bonzini
2025-02-12 17:32 ` Kevin Wolf
2025-02-12 18:17 ` Paolo Bonzini
2025-02-11 21:43 ` [PATCH 09/11] rust/block: Add read support for block drivers Kevin Wolf
2025-02-12 15:05 ` Paolo Bonzini
2025-02-12 20:52 ` Kevin Wolf [this message]
2025-02-11 21:43 ` [PATCH 10/11] bochs-rs: Add bochs block driver reimplementation in Rust Kevin Wolf
2025-02-12 7:45 ` Philippe Mathieu-Daudé
2025-02-12 12:59 ` Kevin Wolf
2025-02-12 13:52 ` Philippe Mathieu-Daudé
2025-02-12 9:14 ` Daniel P. Berrangé
2025-02-12 9:41 ` Daniel P. Berrangé
2025-02-12 12:58 ` Kevin Wolf
2025-02-12 13:07 ` Daniel P. Berrangé
2025-02-11 21:43 ` [PATCH 11/11] rust/block: Add format probing Kevin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z60KCVt38X59J9TN@redhat.com \
--to=kwolf@redhat.com \
--cc=hreitz@redhat.com \
--cc=manos.pitsidianakis@linaro.org \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-rust@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).