io_uring_prep_readv(3)
π io_uring_prep_readv β bestie's guide to vectored read prep π
okay so this one lives in the liburing manual (section 3, the library calls, you know the vibe) and it's literally called io_uring_prep_readv. say it with me. it's giving "read, but make it a vector." π¦
β¨ NAME β¨
io_uring_prep_readv β prepare vector I/O read request π
β¨ SYNOPSIS β¨
#include <sys/uio.h>
#include <liburing.h>
void io_uring_prep_readv(struct io_uring_sqe *sqe,
int fd,
const struct iovec *iovecs,
unsigned nr_vecs,
__u64 offset);
no return value, no drama, she just sets things up and hands them off. π
β¨ DESCRIPTION β¨
so io_uring_prep_readv(3) prepares a vectored IO read request. it takes your submission queue entry sqe and sets it all up to use the file descriptor fd to start reading nr_vecs into the iovecs array, at the offset you specify. that's the whole plot bestie, she's a prep function, not a submit function. π
now here's the tea on offsets. on files that support seeking, if offset is set to -1, the read operation commences at the file offset, and the file offset gets incremented by the number of bytes read. go read read(2) if you want the full lore on that one.
β οΈ but lowkey β for an async API, reading and updating the current file offset may result in unpredictable behavior, unless access to the file is serialized. it is not encouraged to use this feature if it's possible to provide the desired IO offset from the application or library. so like, if you can just pass the offset yourself? do that. π
and on files that are not capable of seeking, the offset must be 0 or -1. no in-between, no vibes-based offsets, okay? β
after the read has been prepared, you can submit it with one of the submit functions. that's the moment. the main character moment. π
β¨ RETURN VALUE β¨
None. nothing. void. she gives you nothing back and that's on purpose, the sqe is the gift. π«Ά
β¨ ERRORS β¨
the CQE res field will contain the result of the operation. see the related man page for details on possible values. π
and here's the important part β where synchronous system calls will return -1 on failure and set errno to the actual error value, io_uring never uses errno. instead it returns the negated errno directly in the CQE res field. no cap. so stop checking errno, she doesn't know her. π
β¨ NOTES β¨
okay bestie, listen up because this is the efficiency gossip:
- unless an application explicitly needs to pass in more than one iovec, it is more efficient to use
io_uring_prep_read(3)rather than this function, as no state has to be maintained for a non-vectored IO request. slay, but like, the frugal kind of slay. β¨
and now the validity rules, which are very much giving "read the fine print":
- as with any request that passes in data in a struct, that data must remain valid until the request has been successfully submitted. π«°
- it need not remain valid until completion. once a request has been submitted, the in-kernel state is stable. so you're free after submission, you're not hostage to completion. π
- very early kernels (5.4 and earlier) required state to be stable until the completion occurred. vintage behavior, honestly.
- applications can test for this behavior by inspecting the
IORING_FEAT_SUBMIT_STABLEflag passed back fromio_uring_queue_init_params(3). go check the flag, it'll tell you what kind of kernel you're dealing with. π
β¨ SEE ALSO β¨
the whole friend group, honestly. go say hi. π
okay that's the whole page bestie, you ate it, you understood it, periodt. this iconic little number is from liburing-2.1, dated November 15, 2021, brought to you by the liburing Manual β and yes, this is io_uring_prep_readv(3), the header and footer of the page, right where they belong. mwah. ππ¦πΈ
π¦ where this page comes from
- alpine 3.22: liburing-doc 2.9-r0 Β· LGPL-2.1-or-later OR MIT
- alpine 3.23: liburing-doc 2.12-r0 Β· LGPL-2.1-or-later OR MIT
- alpine 3.24: liburing-doc 2.14-r0 Β· LGPL-2.1-or-later OR MIT
- centos-stream 10: liburing-devel 2.12-1.el10 Β· (GPLv2 with exceptions and LGPLv2+) or MIT
- centos-stream 9: liburing-devel 2.12-1.el9 Β· (GPLv2 with exceptions and LGPLv2+) or MIT
- centos-stream 9: liburing-devel 2.12-1.el9 Β· (GPLv2 with exceptions and LGPLv2+) or MIT
- debian trixie: liburing-dev 2.9-1
- fedora 43: liburing-devel 2.9-2.fc43 Β· (GPL-2.0-only WITH Linux-syscall-note OR MIT) AND (LGPL-2.0-or-later OR MIT)
- fedora 43: liburing-devel 2.9-2.fc43 Β· (GPL-2.0-only WITH Linux-syscall-note OR MIT) AND (LGPL-2.0-or-later OR MIT)
- fedora 44: liburing-devel 2.13-2.fc44 Β· (GPL-2.0-only WITH Linux-syscall-note OR MIT) AND (LGPL-2.0-or-later OR MIT)
- fedora 44: liburing-devel 2.13-2.fc44 Β· (GPL-2.0-only WITH Linux-syscall-note OR MIT) AND (LGPL-2.0-or-later OR MIT)
- nixpkgs unstable: liburing 2.14
- opensuse-leap 16.0: liburing-devel 2.8-160000.3.1 Β· (GPL-2.0-only AND LGPL-2.1-or-later) OR MIT
- opensuse-leap 16.0: liburing-devel 2.8-160000.3.1 Β· (GPL-2.0-only AND LGPL-2.1-or-later) OR MIT
- opensuse-leap 16.0: liburing-devel 2.8-160000.3.1 Β· (GPL-2.0-only AND LGPL-2.1-or-later) OR MIT
- opensuse-leap 16.0: liburing-devel 2.8-160000.3.1 Β· (GPL-2.0-only AND LGPL-2.1-or-later) OR MIT
- ubuntu noble: liburing-dev 2.5-1build1
- ubuntu questing: liburing-dev 2.11-1
- ubuntu resolute: liburing-dev 2.14-1
- π the page's license: LGPL-2.0-or-later
- Copyright (C) 2021 Stefan Roesch <shr@fb.com>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms