Am 22.10.2025 um 17:55 hat ~abombo geschrieben:
> From: Aurélien Bombo <[email protected]>
>
> 984a32f17e8d introduced support for prep_writev2 as released in liburing 2.2
> and libaio 0.3.111. However, it also broke users of older versions of these
> libraries (without prep_writev2) who relied on flags being no-op, so we remove
> the check on flags.
>
> Fixes: 984a32f17e8d
>
> Signed-off-by: Aurélien Bombo <[email protected]>
> ---
> block/io_uring.c | 1 -
> block/linux-aio.c | 1 -
> 2 files changed, 2 deletions(-)
>
> diff --git a/block/io_uring.c b/block/io_uring.c
> index dd4f304910..b44edcd7a4 100644
> --- a/block/io_uring.c
> +++ b/block/io_uring.c
> @@ -349,7 +349,6 @@ static int luring_do_submit(int fd, LuringAIOCB
> *luringcb, LuringState *s,
> luringcb->qiov->niov, offset, luring_flags);
> }
> #else
> - assert(flags == 0);
> io_uring_prep_writev(sqes, fd, luringcb->qiov->iov,
> luringcb->qiov->niov, offset);
> #endif
This doesn't look right to me. We're now silently ignoring the flags,
i.e. with BDRV_REQ_FUA the caller believes the data is stable on disk
when it really isn't. That's a data corruption bug.
The right question to ask is which flag is set and why it's set when we
can't handle it. raw_open_common() has this code:
bs->supported_write_flags = BDRV_REQ_FUA;
if (s->use_linux_aio && !laio_has_fua()) {
bs->supported_write_flags &= ~BDRV_REQ_FUA;
} else if (s->use_linux_io_uring && !luring_has_fua()) {
bs->supported_write_flags &= ~BDRV_REQ_FUA;
}
The *_has_fua() functions look like this:
bool luring_has_fua(void)
{
#ifdef HAVE_IO_URING_PREP_WRITEV2
return true;
#else
return false;
#endif
}
So with a library version that doesn't support prep_writev2, the
expected state is bs->supported_write_flags == 0. This should mean that
bdrv_driver_pwritev() clears all flags before calling into file-posix
(and therefore Linux AIO or io_uring) code.
Can you please debug where these assumptions break down in your case?
Kevin