Fields

fd: os.fd_t = -1,
flags: u32,
features: u32,

Functions

fn accept(self: *IO_Uring, user_data: u64, fd: os.fd_t, addr: ?*os.sockaddr, addrlen: ?*os.socklen_t, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform an accept4(2) on a socket. Ret…

Queues (but does not submit) an SQE to perform an accept4(2) on a socket. Returns a pointer to the SQE.

fn cancel(self: *IO_Uring, user_data: u64, cancel_user_data: u64, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to remove an existing operation. Returns a …

Queues (but does not submit) an SQE to remove an existing operation. Returns a pointer to the SQE.

The operation is identified by its user_data.

The completion event result will be 0 if the operation was found and cancelled successfully, -EALREADY if the operation was found but was already in progress, or -ENOENT if the operation was not found.

fn close(self: *IO_Uring, user_data: u64, fd: os.fd_t) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a close(2). Returns a pointer …

Queues (but does not submit) an SQE to perform a close(2). Returns a pointer to the SQE.

fn connect(self: *IO_Uring, user_data: u64, fd: os.fd_t, addr: *const os.sockaddr, addrlen: os.socklen_t) !*linux.io_uring_sqe

Queue (but does not submit) an SQE to perform a connect(2) on a socket. Retur…

Queue (but does not submit) an SQE to perform a connect(2) on a socket. Returns a pointer to the SQE.

fn copy_cqe(ring: *IO_Uring) !linux.io_uring_cqe

Returns a copy of an I/O completion, waiting for it if necessary, and advancing …

Returns a copy of an I/O completion, waiting for it if necessary, and advancing the CQ ring. A convenience method for copy_cqes() for when you don’t need to batch or peek.

fn copy_cqes(self: *IO_Uring, cqes: []linux.io_uring_cqe, wait_nr: u32) !u32

Copies as many CQEs as are ready, and that can fit into the destination cqes s…

Copies as many CQEs as are ready, and that can fit into the destination cqes slice. If none are available, enters into the kernel to wait for at most wait_nr CQEs. Returns the number of CQEs copied, advancing the CQ ring. Provides all the wait/peek methods found in liburing, but with batching and a single method. The rationale for copying CQEs rather than copying pointers is that pointers are 8 bytes whereas CQEs are not much more at only 16 bytes, and this provides a safer faster interface. Safer, because you no longer need to call cqe_seen(), avoiding idempotency bugs. Faster, because we can now amortize the atomic store release to cq.head across the batch. See https://github.com/axboe/liburing/issues/103#issuecomment-686665007. Matches the implementation of io_uring_peek_batch_cqe() in liburing, but supports waiting.

fn cq_advance(self: *IO_Uring, count: u32) void

For advanced use cases only that implement custom completion queue methods. Mat…

For advanced use cases only that implement custom completion queue methods. Matches the implementation of cq_advance() in liburing.

fn cq_ready(self: *IO_Uring) u32

Returns the number of CQEs in the completion queue, i.e. its length. These are …

Returns the number of CQEs in the completion queue, i.e. its length. These are CQEs that the application is yet to consume. Matches the implementation of io_uring_cq_ready in liburing.

fn cq_ring_needs_flush(self: *IO_Uring) bool

Matches the implementation of cq_ring_needs_flush() in liburing.

fn cqe_seen(self: *IO_Uring, cqe: *linux.io_uring_cqe) void

For advanced use cases only that implement custom completion queue methods. If …

For advanced use cases only that implement custom completion queue methods. If you use copy_cqes() or copy_cqe() you must not call cqe_seen() or cq_advance(). Must be called exactly once after a zero-copy CQE has been processed by your application. Not idempotent, calling more than once will result in other CQEs being lost. Matches the implementation of cqe_seen() in liburing.

fn deinit(self: *IO_Uring) void

No documentation provided.

fn enter(self: *IO_Uring, to_submit: u32, min_complete: u32, flags: u32) !u32

Tell the kernel we have submitted SQEs and/or want to wait for CQEs. Returns th…

Tell the kernel we have submitted SQEs and/or want to wait for CQEs. Returns the number of SQEs submitted.

fn epoll_ctl(self: *IO_Uring, user_data: u64, epfd: os.fd_t, fd: os.fd_t, op: u32, ev: ?*linux.epoll_event) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a epoll_ctl(2). Returns a poin…

Queues (but does not submit) an SQE to perform a epoll_ctl(2). Returns a pointer to the SQE.

fn fallocate(self: *IO_Uring, user_data: u64, fd: os.fd_t, mode: i32, offset: u64, len: u64) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform an fallocate(2). Returns a poi…

Queues (but does not submit) an SQE to perform an fallocate(2). Returns a pointer to the SQE.

fn flush_sq(self: *IO_Uring) u32

Sync internal state with kernel ring state on the SQ side. Returns the number o…

Sync internal state with kernel ring state on the SQ side. Returns the number of all pending events in the SQ ring, for the shared ring. This return value includes previously flushed SQEs, as per liburing. The rationale is to suggest that an io_uring_enter() call is needed rather than not. Matches the implementation of __io_uring_flush_sq() in liburing.

fn fsync(self: *IO_Uring, user_data: u64, fd: os.fd_t, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform an fsync(2). Returns a pointer…

Queues (but does not submit) an SQE to perform an fsync(2). Returns a pointer to the SQE so that you can further modify the SQE for advanced use cases. For example, for fdatasync() you can set IORING_FSYNC_DATASYNC in the SQE’s rw_flags. N.B. While SQEs are initiated in the order in which they appear in the submission queue, operations execute in parallel and completions are unordered. Therefore, an application that submits a write followed by an fsync in the submission queue cannot expect the fsync to apply to the write, since the fsync may complete before the write is issued to the disk. You should preferably use link_with_next_sqe() on a write’s SQE to link it with an fsync, or else insert a full write barrier using drain_previous_sqes() when queueing an fsync.

fn get_sqe(self: *IO_Uring) !*linux.io_uring_sqe

Returns a pointer to a vacant SQE, or an error if the submission queue is full. …

Returns a pointer to a vacant SQE, or an error if the submission queue is full. We follow the implementation (and atomics) of liburing’s io_uring_get_sqe() exactly. However, instead of a null we return an error to force safe handling. Any situation where the submission queue is full tends more towards a control flow error, and the null return in liburing is more a C idiom than anything else, for lack of a better alternative. In Zig, we have first-class error handling… so let’s use it. Matches the implementation of io_uring_get_sqe() in liburing.

fn init(entries: u13, flags: u32) !IO_Uring

A friendly way to setup an io_uring, with default linux.io_uring_params. `entri…

A friendly way to setup an io_uring, with default linux.io_uring_params. entries must be a power of two between 1 and 4096, although the kernel will make the final call on how many entries the submission and completion queues will ultimately have, see https://github.com/torvalds/linux/blob/v5.8/fs/io_uring.c#L8027-L8050. Matches the interface of io_uring_queue_init() in liburing.

fn init_params(entries: u13, p: *linux.io_uring_params) !IO_Uring

A powerful way to setup an io_uring, if you want to tweak linux.io_uring_params …

A powerful way to setup an io_uring, if you want to tweak linux.io_uring_params such as submission queue thread cpu affinity or thread idle timeout (the kernel and our default is 1 second). params is passed by reference because the kernel needs to modify the parameters. Matches the interface of io_uring_queue_init_params() in liburing.

fn link_timeout(self: *IO_Uring, user_data: u64, ts: *const os.linux.kernel_timespec, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to add a link timeout operation. Returns a …

Queues (but does not submit) an SQE to add a link timeout operation. Returns a pointer to the SQE.

You need to set linux.IOSQE_IO_LINK to flags of the target operation and then call this method right after the target operation. See https://lwn.net/Articles/803932/ for detail.

If the dependent request finishes before the linked timeout, the timeout is canceled. If the timeout finishes before the dependent request, the dependent request will be canceled.

The completion event result of the link_timeout will be -ETIME if the timeout finishes before the dependent request (in this case, the completion event result of the dependent request will be -ECANCELED), or -EALREADY if the dependent request finishes before the linked timeout.

fn linkat(self: *IO_Uring, user_data: u64, old_dir_fd: os.fd_t, old_path: [*:0]const u8, new_dir_fd: os.fd_t, new_path: [*:0]const u8, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a linkat(2). Returns a pointer…

Queues (but does not submit) an SQE to perform a linkat(2). Returns a pointer to the SQE.

fn mkdirat(self: *IO_Uring, user_data: u64, dir_fd: os.fd_t, path: [*:0]const u8, mode: os.mode_t) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a mkdirat(2). Returns a pointe…

Queues (but does not submit) an SQE to perform a mkdirat(2). Returns a pointer to the SQE.

fn nop(self: *IO_Uring, user_data: u64) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a no-op. Returns a pointer to th…

Queues (but does not submit) an SQE to perform a no-op. Returns a pointer to the SQE so that you can further modify the SQE for advanced use cases. A no-op is more useful than may appear at first glance. For example, you could call drain_previous_sqes() on the returned SQE, to use the no-op to know when the ring is idle before acting on a kill signal.

fn openat(self: *IO_Uring, user_data: u64, fd: os.fd_t, path: [*:0]const u8, flags: u32, mode: os.mode_t) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform an openat(2). Returns a pointe…

Queues (but does not submit) an SQE to perform an openat(2). Returns a pointer to the SQE.

fn poll_add(self: *IO_Uring, user_data: u64, fd: os.fd_t, poll_mask: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a poll(2). Returns a pointer t…

Queues (but does not submit) an SQE to perform a poll(2). Returns a pointer to the SQE.

fn poll_remove(self: *IO_Uring, user_data: u64, target_user_data: u64) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to remove an existing poll operation. Retur…

Queues (but does not submit) an SQE to remove an existing poll operation. Returns a pointer to the SQE.

fn poll_update(self: *IO_Uring, user_data: u64, old_user_data: u64, new_user_data: u64, poll_mask: u32, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to update the user data of an existing poll …

Queues (but does not submit) an SQE to update the user data of an existing poll operation. Returns a pointer to the SQE.

fn provide_buffers(self: *IO_Uring, user_data: u64, buffers: [*]u8, buffer_size: usize, buffers_count: usize, group_id: usize, buffer_id: usize) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to provide a group of buffers used for comma…

Queues (but does not submit) an SQE to provide a group of buffers used for commands that read/receive data. Returns a pointer to the SQE.

Provided buffers can be used in read, recv or recvmsg commands via .buffer_selection.

The kernel expects a contiguous block of memory of size (buffers_count * buffer_size).

fn read(self: *IO_Uring, user_data: u64, fd: os.fd_t, buffer: ReadBuffer, offset: u64) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a read(2) or preadv depending…

Queues (but does not submit) an SQE to perform a read(2) or preadv depending on the buffer type.

  • Reading into a ReadBuffer.buffer uses read(2)
  • Reading into a ReadBuffer.iovecs uses preadv(2) If you want to do a preadv2() then set rw_flags on the returned SQE. See https://linux.die.net/man/2/preadv.

Returns a pointer to the SQE.

fn read_fixed(self: *IO_Uring, user_data: u64, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a IORING_OP_READ_FIXED. The `buf…

Queues (but does not submit) an SQE to perform a IORING_OP_READ_FIXED. The buffer provided must be registered with the kernel by calling register_buffers first. The buffer_index must be the same as its index in the array provided to register_buffers.

Returns a pointer to the SQE so that you can further modify the SQE for advanced use cases.

fn recv(self: *IO_Uring, user_data: u64, fd: os.fd_t, buffer: RecvBuffer, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a recv(2). Returns a pointer t…

Queues (but does not submit) an SQE to perform a recv(2). Returns a pointer to the SQE.

fn recvmsg(self: *IO_Uring, user_data: u64, fd: os.fd_t, msg: *os.msghdr, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a recvmsg(2). Returns a pointe…

Queues (but does not submit) an SQE to perform a recvmsg(2). Returns a pointer to the SQE.

fn register_buffers(self: *IO_Uring, buffers: []const os.iovec) !void

Registers an array of buffers for use with read_fixed and write_fixed.

fn register_eventfd(self: *IO_Uring, fd: os.fd_t) !void

Registers the file descriptor for an eventfd that will be notified of completion…

Registers the file descriptor for an eventfd that will be notified of completion events on an io_uring instance. Only a single a eventfd can be registered at any given point in time.

fn register_eventfd_async(self: *IO_Uring, fd: os.fd_t) !void

Registers the file descriptor for an eventfd that will be notified of completion…

Registers the file descriptor for an eventfd that will be notified of completion events on an io_uring instance. Notifications are only posted for events that complete in an async manner. This means that events that complete inline while being submitted do not trigger a notification event. Only a single eventfd can be registered at any given point in time.

fn register_files(self: *IO_Uring, fds: []const os.fd_t) !void

Registers an array of file descriptors. Every time a file descriptor is put in …

Registers an array of file descriptors. Every time a file descriptor is put in an SQE and submitted to the kernel, the kernel must retrieve a reference to the file, and once I/O has completed the file reference must be dropped. The atomic nature of this file reference can be a slowdown for high IOPS workloads. This slowdown can be avoided by pre-registering file descriptors. To refer to a registered file descriptor, IOSQE_FIXED_FILE must be set in the SQE’s flags, and the SQE’s fd must be set to the index of the file descriptor in the registered array. Registering file descriptors will wait for the ring to idle. Files are automatically unregistered by the kernel when the ring is torn down. An application need unregister only if it wants to register a new array of file descriptors.

fn register_files_update(self: *IO_Uring, offset: u32, fds: []const os.fd_t) !void

Updates registered file descriptors.

Updates registered file descriptors.

Updates are applied starting at the provided offset in the original file descriptors slice. There are three kind of updates:

  • turning a sparse entry (where the fd is -1) into a real one
  • removing an existing entry (set the fd to -1)
  • replacing an existing entry with a new fd Adding new file descriptors must be done with register_files.
fn remove_buffers(self: *IO_Uring, user_data: u64, buffers_count: usize, group_id: usize) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to remove a group of provided buffers. Retu…

Queues (but does not submit) an SQE to remove a group of provided buffers. Returns a pointer to the SQE.

fn renameat(self: *IO_Uring, user_data: u64, old_dir_fd: os.fd_t, old_path: [*:0]const u8, new_dir_fd: os.fd_t, new_path: [*:0]const u8, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a renameat2(2). Returns a poin…

Queues (but does not submit) an SQE to perform a renameat2(2). Returns a pointer to the SQE.

fn send(self: *IO_Uring, user_data: u64, fd: os.fd_t, buffer: []const u8, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a send(2). Returns a pointer t…

Queues (but does not submit) an SQE to perform a send(2). Returns a pointer to the SQE.

fn sendmsg(self: *IO_Uring, user_data: u64, fd: os.fd_t, msg: *const os.msghdr_const, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a sendmsg(2). Returns a pointe…

Queues (but does not submit) an SQE to perform a sendmsg(2). Returns a pointer to the SQE.

fn shutdown(self: *IO_Uring, user_data: u64, sockfd: os.socket_t, how: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a shutdown(2). Returns a point…

Queues (but does not submit) an SQE to perform a shutdown(2). Returns a pointer to the SQE.

The operation is identified by its user_data.

fn sq_ready(self: *IO_Uring) u32

Returns the number of flushed and unflushed SQEs pending in the submission queue…

Returns the number of flushed and unflushed SQEs pending in the submission queue. In other words, this is the number of SQEs in the submission queue, i.e. its length. These are SQEs that the kernel is yet to consume. Matches the implementation of io_uring_sq_ready in liburing.

fn sq_ring_needs_enter(self: *IO_Uring, flags: *u32) bool

Returns true if we are not using an SQ thread (thus nobody submits but us), or …

Returns true if we are not using an SQ thread (thus nobody submits but us), or if IORING_SQ_NEED_WAKEUP is set and the SQ thread must be explicitly awakened. For the latter case, we set the SQ thread wakeup flag. Matches the implementation of sq_ring_needs_enter() in liburing.

fn statx(self: *IO_Uring, user_data: u64, fd: os.fd_t, path: [:0]const u8, flags: u32, mask: u32, buf: *linux.Statx) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform an statx(2). Returns a pointer…

Queues (but does not submit) an SQE to perform an statx(2). Returns a pointer to the SQE.

fn submit(self: *IO_Uring) !u32

Submits the SQEs acquired via get_sqe() to the kernel. You can call this once af…

Submits the SQEs acquired via get_sqe() to the kernel. You can call this once after you have called get_sqe() multiple times to setup multiple I/O requests. Returns the number of SQEs submitted. Matches the implementation of io_uring_submit() in liburing.

fn submit_and_wait(self: *IO_Uring, wait_nr: u32) !u32

Like submit(), but allows waiting for events as well. Returns the number of SQE…

Like submit(), but allows waiting for events as well. Returns the number of SQEs submitted. Matches the implementation of io_uring_submit_and_wait() in liburing.

fn symlinkat(self: *IO_Uring, user_data: u64, target: [*:0]const u8, new_dir_fd: os.fd_t, link_path: [*:0]const u8) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a symlinkat(2). Returns a poin…

Queues (but does not submit) an SQE to perform a symlinkat(2). Returns a pointer to the SQE.

fn timeout(self: *IO_Uring, user_data: u64, ts: *const os.linux.kernel_timespec, count: u32, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to register a timeout operation. Returns a …

Queues (but does not submit) an SQE to register a timeout operation. Returns a pointer to the SQE.

The timeout will complete when either the timeout expires, or after the specified number of events complete (if count is greater than 0).

flags may be 0 for a relative timeout, or IORING_TIMEOUT_ABS for an absolute timeout.

The completion event result will be -ETIME if the timeout completed through expiration, 0 if the timeout completed after the specified number of events, or -ECANCELED if the timeout was removed before it expired.

io_uring timeouts use the CLOCK.MONOTONIC clock source.

fn timeout_remove(self: *IO_Uring, user_data: u64, timeout_user_data: u64, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to remove an existing timeout operation. Re…

Queues (but does not submit) an SQE to remove an existing timeout operation. Returns a pointer to the SQE.

The timeout is identified by its user_data.

The completion event result will be 0 if the timeout was found and cancelled successfully, -EBUSY if the timeout was found but expiration was already in progress, or -ENOENT if the timeout was not found.

fn unlinkat(self: *IO_Uring, user_data: u64, dir_fd: os.fd_t, path: [*:0]const u8, flags: u32) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a unlinkat(2). Returns a point…

Queues (but does not submit) an SQE to perform a unlinkat(2). Returns a pointer to the SQE.

fn unregister_buffers(self: *IO_Uring) !void

Unregister the registered buffers.

fn unregister_eventfd(self: *IO_Uring) !void

Unregister the registered eventfd file descriptor.

fn unregister_files(self: *IO_Uring) !void

Unregisters all registered file descriptors previously associated with the ring.

fn write(self: *IO_Uring, user_data: u64, fd: os.fd_t, buffer: []const u8, offset: u64) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a write(2). Returns a pointer …

Queues (but does not submit) an SQE to perform a write(2). Returns a pointer to the SQE.

fn write_fixed(self: *IO_Uring, user_data: u64, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a IORING_OP_WRITE_FIXED. The `bu…

Queues (but does not submit) an SQE to perform a IORING_OP_WRITE_FIXED. The buffer provided must be registered with the kernel by calling register_buffers first. The buffer_index must be the same as its index in the array provided to register_buffers.

Returns a pointer to the SQE so that you can further modify the SQE for advanced use cases.

fn writev(self: *IO_Uring, user_data: u64, fd: os.fd_t, iovecs: []const os.iovec_const, offset: u64) !*linux.io_uring_sqe

Queues (but does not submit) an SQE to perform a pwritev(). Returns a pointer…

Queues (but does not submit) an SQE to perform a pwritev(). Returns a pointer to the SQE so that you can further modify the SQE for advanced use cases. For example, if you want to do a pwritev2() then set rw_flags on the returned SQE. See https://linux.die.net/man/2/pwritev.