### Example: Setup Buffer Ring Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Demonstrates how to set up a buffer ring with 32 entries. Check the returned error code if the setup fails. ```c int err = 0; struct io_uring_buf_ring *br = io_uring_setup_buf_ring(&ring, 32, 0, 0, &err); if (!br) { fprintf(stderr, "setup_buf_ring failed: %s\n", strerror(err)); return err; } ``` -------------------------------- ### Example: Setting User Data for a Read Operation Source: https://github.com/axboe/liburing/blob/master/_autodocs/2-submission-queue-api.md This example demonstrates how to prepare a read operation and associate a custom context pointer with the submission queue entry using `io_uring_sqe_set_data()`. ```c struct request_ctx *ctx = malloc(sizeof(*ctx)); struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); io_uring_prep_read(sqe, fd, buf, sizeof(buf), 0); io_uring_sqe_set_data(sqe, ctx); ``` -------------------------------- ### Multishot Operations Examples Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Illustrates how to prepare multishot operations that can generate multiple completions without resubmission. Examples include accept, poll, and recv. ```c /* Multishot accept - generates CQE for each connection */ io_uring_prep_multishot_accept(sqe, listen_fd, addr, addrlen, 0); /* Multishot poll - generates CQE for each event */ io_uring_prep_poll_multishot(sqe, fd, POLLIN); /* Multishot recv - generates CQE for each packet */ io_uring_prep_recv_multishot(sqe, fd, buf, len, 0); ``` -------------------------------- ### Build and Install liburing Source: https://github.com/axboe/liburing/blob/master/_autodocs/INDEX.md Standard build and installation commands for the liburing library. This process generates both shared (.so) and static (.a) library files, including FFI bindings. ```bash ./configure make -j$(nproc) sudo make install ``` -------------------------------- ### Example: Retrieving User Data and Operation Result Source: https://github.com/axboe/liburing/blob/master/_autodocs/2-submission-queue-api.md This example shows how to retrieve the user-provided context pointer from a completion queue entry and print the operation's result. ```c struct io_uring_cqe *cqe; struct request_ctx *ctx = (struct request_ctx *) io_uring_cqe_get_data(cqe); printf("Operation %p completed with result %d\n", ctx, cqe->res); ``` -------------------------------- ### Example: Check for Splice Operation Support Source: https://github.com/axboe/liburing/blob/master/_autodocs/6-registration-and-personality.md Demonstrates how to get a probe structure, check if the IORING_OP_SPLICE operation is supported, and then free the probe structure. ```c struct io_uring_probe *p = io_uring_get_probe(); if (io_uring_opcode_supported(p, IORING_OP_SPLICE)) { printf("Splice operations are supported\n"); } io_uring_free_probe(p); ``` -------------------------------- ### io_uring_setup Source: https://github.com/axboe/liburing/blob/master/_autodocs/7-syscall-interface.md Initializes an io_uring instance at the kernel level, returning a file descriptor for subsequent operations. The provided io_uring_params structure is populated by the kernel with actual setup values. ```APIDOC ## io_uring_setup ### Description Initialize an io_uring instance at the kernel level. ### Method syscall ### Endpoint io_uring_setup ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **entries** (unsigned int) - Required - Number of SQE entries (rounded to power of 2) - **p** (struct io_uring_params *) - Required - Input/output: setup parameters and results ### Return Value - File descriptor of io_uring instance on success - `-errno` on failure ### Description Raw syscall wrapper. Returns a file descriptor that can be used with `io_uring_enter()` and `io_uring_register()`. The `p` structure is filled in by the kernel with actual values. ### Request Example ```c struct io_uring_params p = {0}; int fd = io_uring_setup(256, &p); if (fd < 0) { fprintf(stderr, "io_uring_setup failed: %s\n", strerror(-fd)); return fd; } printf("Ring created. Features: 0x%x\n", p.features); ``` ``` -------------------------------- ### Iterate Over CQEs Using io_uring_cqe_iter Source: https://github.com/axboe/liburing/blob/master/_autodocs/3-completion-queue-api.md Example demonstrating how to use `io_uring_cqe_iter_init` and `io_uring_cqe_iter_next` to loop through all pending completion queue entries and process their results. ```c struct io_uring_cqe_iter iter = io_uring_cqe_iter_init(&ring); struct io_uring_cqe *cqe; while (io_uring_cqe_iter_next(&iter, &cqe)) { printf("Operation completed with result: %d\n", cqe->res); } io_uring_cq_advance(&ring, iter.head - *ring.cq.khead); ``` -------------------------------- ### Setup io_uring Buffer Ring and Add Buffers Source: https://github.com/axboe/liburing/wiki/io_uring-and-networking-in-2023 Demonstrates how to allocate memory for a buffer ring, register it with io_uring, initialize the ring, add buffers, and make them visible to the kernel. Requires pre-allocated buffer memory and a registered io_uring instance. ```c struct io_uring_buf_ring *setup_buffer_ring(struct io_uring *ring) { struct io_uring_buf_reg reg = { }; struct io_uring_buf_ring *br; int i; /* allocate mem for sharing buffer ring */ if (posix_memalign((void **) &br, 4096, BUFS_IN_GROUP * sizeof(struct io_uring_buf_ring))) return NULL; /* assign and register buffer ring */ eg.ring_addr = (unsigned long) br; eg.ring_entries = BUFS_IN_GROUP; eg.bgid = BUF_BGID; if (io_uring_register_buf_ring(ring, ®, 0)) return 1; /* add initial buffers to the ring */ io_uring_buf_ring_init(br); for (i = 0; i < BUFS_IN_GROUP; i++) { /* add each buffer, we'll use i buffer ID */ io_uring_buf_ring_add(br, bufs[i], BUF_SIZE, i, io_uring_buf_ring_mask(BUFS_IN_GROUP), i); } /* we've supplied buffers, make them visible to the kernel */ ``` -------------------------------- ### Initialize io_uring with Custom Parameters Source: https://github.com/axboe/liburing/blob/master/_autodocs/1-queue-initialization.md Employ io_uring_queue_init_params to initialize io_uring with custom parameters, such as IORING_SETUP_SQPOLL and sq_thread_idle. The kernel populates the actual CQ entries after successful setup. ```c int io_uring_queue_init_params(unsigned entries, struct io_uring *ring, struct io_uring_params *p); ``` ```c struct io_uring ring; struct io_uring_params p = {0}; p.flags = IORING_SETUP_SQPOLL; p.sq_thread_idle = 100; /* milliseconds */ int ret = io_uring_queue_init_params(256, &ring, &p); if (ret == 0) { printf("CQ entries: %u\n", p.cq_entries); } ``` -------------------------------- ### Example Commit Message Format Source: https://github.com/axboe/liburing/blob/master/CONTRIBUTING.md This is an example of the expected commit message format, including author, date, subject, body, and Signed-off-by tag. Ensure your commits follow this structure. ```git commit 0fe5c09195c0918f89582dd6ff098a58a0bdf62a Author: Jens Axboe Date: Fri Sep 6 15:54:04 2024 -0600 configure: fix ublk_cmd header check The previous commit is mixing private structures and defines with public uapi ones. Testing for UBLK_U_CMD_START_DEV is fine, CTRL_CMD_HAS_DATA is not. And struct ublk_ctrl_cmd_data is not a public struct. Fixes: 83bc535a3118 ("configure: don't enable ublk if modern commands not available") Signed-off-by: Jens Axboe ``` -------------------------------- ### Detect Supported Operations with Probe Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Shows how to get a probe of supported operations and check for specific operation support. Remember to free the probe when done. ```c /* Get probe of supported operations */ struct io_uring_probe *p = io_uring_get_probe(); if (!p) { fprintf(stderr, "Probe failed\n"); return -1; } /* Check if specific operation is supported */ if (io_uring_opcode_supported(p, IORING_OP_SPLICE)) { printf("Splice operations supported\n"); } io_uring_free_probe(p); ``` -------------------------------- ### Prepare io_uring File System Operations Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Code examples for preparing file system related operations like fsync and splice using io_uring. ```c io_uring_prep_fsync(sqe, fd, IORING_FSYNC_DATASYNC); io_uring_prep_splice(sqe, fd_in, off_in, fd_out, off_out, len, 0); ``` -------------------------------- ### io_uring_queue_init_params Source: https://github.com/axboe/liburing/blob/master/_autodocs/1-queue-initialization.md Initializes an io_uring instance with custom parameters, allowing for advanced configuration such as CQ multiplier and specific setup flags. ```APIDOC ## io_uring_queue_init_params ### Description Initializes an io_uring instance with custom parameters, allowing for advanced configuration such as CQ multiplier and specific setup flags. The kernel fills in actual values after setup succeeds. ### Function Signature ```c int io_uring_queue_init_params(unsigned entries, struct io_uring *ring, struct io_uring_params *p); ``` ### Parameters #### Path Parameters - **entries** (unsigned) - Required - Number of SQE entries - **ring** (struct io_uring *) - Required - Pointer to uninitialized io_uring structure - **p** (struct io_uring_params *) - Required - Setup parameters with flags and optional CQ multiplier ### Return Value - `0` on success - `-errno` on failure ### Example ```c struct io_uring ring; struct io_uring_params p = {0}; p.flags = IORING_SETUP_SQPOLL; p.sq_thread_idle = 100; /* milliseconds */ int ret = io_uring_queue_init_params(256, &ring, &p); if (ret == 0) { printf("CQ entries: %u\n", p.cq_entries); } ``` ``` -------------------------------- ### Iterate Over CQEs Using io_uring_for_each_cqe Macro Source: https://github.com/axboe/liburing/blob/master/_autodocs/3-completion-queue-api.md Example demonstrating the usage of the `io_uring_for_each_cqe` macro to conveniently iterate through all pending completion queue entries and process them. ```c unsigned head; struct io_uring_cqe *cqe; io_uring_for_each_cqe(&ring, head, cqe) { handle_completion(cqe); } io_uring_cq_advance(&ring, head - *ring.cq.khead); ``` -------------------------------- ### io_uring_queue_mmap Source: https://github.com/axboe/liburing/blob/master/_autodocs/1-queue-initialization.md Manually maps io_uring memory and initializes the ring, offering fine-grained control for applications that manage io_uring setup directly. ```APIDOC ## io_uring_queue_mmap ### Description Manually maps io_uring memory and initializes the ring, offering fine-grained control for applications that manage io_uring setup directly. This is useful for applications that call `io_uring_setup()` themselves before using liburing. ### Function Signature ```c int io_uring_queue_mmap(int fd, struct io_uring_params *p, struct io_uring *ring); ``` ### Parameters #### Path Parameters - **fd** (int) - Required - File descriptor from io_uring_setup() - **p** (struct io_uring_params *) - Required - Parameters from io_uring_setup() - **ring** (struct io_uring *) - Required - Pointer to uninitialized io_uring structure ### Return Value - `0` on success - `-errno` on failure ``` -------------------------------- ### Initialize io_uring with Standard Flags Source: https://github.com/axboe/liburing/blob/master/_autodocs/1-queue-initialization.md Use io_uring_queue_init for basic io_uring setup with standard flags. Ensure to check the return value for errors like invalid entries or memory allocation failures. ```c int io_uring_queue_init(unsigned entries, struct io_uring *ring, unsigned flags); ``` ```c struct io_uring ring; int ret = io_uring_queue_init(256, &ring, 0); if (ret) { fprintf(stderr, "io_uring_queue_init failed: %s\n", strerror(-ret)); return ret; } ``` -------------------------------- ### Basic io_uring Operation Flow Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Illustrates the fundamental steps for performing an asynchronous I/O operation using liburing: getting a submission queue entry (SQE), preparing the operation, submitting it to the kernel, waiting for completion, processing the result, and marking the completion as seen. ```c /* 1. Get a submission queue entry */ struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); /* 2. Prepare an operation */ io_uring_prep_read(sqe, fd, buf, 4096, 0); io_uring_sqe_set_data(sqe, my_context); /* 3. Submit to kernel */ int ret = io_uring_submit(&ring); if (ret < 0) { fprintf(stderr, "submit: %s\n", strerror(-ret)); } /* 4. Wait for completion */ struct io_uring_cqe *cqe; io_uring_wait_cqe(&ring, &cqe); /* 5. Process result */ printf("Read %d bytes\n", cqe->res); my_context = io_uring_cqe_get_data(cqe); /* 6. Mark as processed */ io_uring_cqe_seen(&ring, cqe); ``` -------------------------------- ### io_uring_enable_rings Source: https://github.com/axboe/liburing/blob/master/_autodocs/1-queue-initialization.md Enables the SQ and CQ rings after they have been disabled. This is typically used in conjunction with the IORING_SETUP_R_DISABLED flag for initial setup. ```APIDOC ## io_uring_enable_rings ### Description Enable SQ and CQ rings after being disabled. ### Signature ```c int io_uring_enable_rings(struct io_uring *ring); ``` ### Parameters #### Path Parameters - **ring** (struct io_uring *) - Required - Pointer to an initialized io_uring structure ### Return Value - `0` on success - `-errno` on failure ### Description Used with IORING_SETUP_R_DISABLED flag to re-enable rings after initial setup. ``` -------------------------------- ### Setup Kernel-Managed Buffer Ring Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Allocates and registers a kernel-managed buffer ring. Use this when you need to manage buffer pools directly by the kernel for operations like IORING_OP_RECV with IOSQE_BUFFER_SELECT. ```c struct io_uring_buf_ring *io_uring_setup_buf_ring(struct io_uring *ring, unsigned int nentries, int bgid, unsigned int flags, int *err); ``` -------------------------------- ### Retrieve and Reuse Buffer with io_uring Source: https://github.com/axboe/liburing/wiki/io_uring-and-networking-in-2023 Example of retrieving a completed buffer from the completion queue (CQE), performing work, and then adding it back to the buffer ring for reuse. Ensure to use sysconf(_SC_PAGESIZE) for page size in real applications. ```c io_uring_wait_cqe(ring, &cqe); /* IORING_CQE_F_BUFFER is set in cqe->flags, get buffer ID */ buffer_id = cqe->flags >> IORING_CQE_BUFFER_SHIFT; /* find the buffer from our buffer pool */ buf = bufs[buffer_id]; [... app work happens here ...] /* we’re done with the buffer, add it back */ io_uring_buf_ring_add(br, bufs[buffer_id], BUF_SIZE, buffer_id, io_uring_buf_ring_mask(BUFS_IN_GROUP), 0); /* make it visible */ io_uring_buf_ring_advance(br, 1); /* CQE has been seen */ io_uring_cqe_seen(ring, cqe); ``` -------------------------------- ### Incremental Provided Buffer Consumption Example Source: https://github.com/axboe/liburing/wiki/What's-new-with-io_uring-in-6.11-and-6.12 Illustrates how to interpret completion queue events (CQEs) for incremental buffer consumption. It shows how `cqe->res` and `cqe->flags` indicate received data size, buffer ID, and whether more data is expected from the same buffer. ```text cqe->res 0x1000 (4k bytes received) cqe->flags 0x11 (CQE_F_BUFFER|CQE_F_BUF_MORE set, buffer ID 0) ``` ```text cqe->res 0x2010 (8k bytes received) cqe->flags 0x11 (CQE_F_BUFFER|CQE_F_BUF_MORE set, buffer ID 0) ``` ```text cqe->res 0x5000 (20k bytes received) cqe->flags 0x1 (CQE_F_BUFFER set, buffer ID 0) ``` ```text cqe->res 0x1000 (4k bytes received) cqe->flags 0x10001 (CQE_F_BUFFER|CQE_F_BUF_MORE set, buffer ID 1) ``` -------------------------------- ### Basic Initialization and I/O Source: https://github.com/axboe/liburing/blob/master/_autodocs/INDEX.md Demonstrates the fundamental steps for initializing an io_uring instance, submitting a read operation, waiting for completion, and cleaning up. ```c struct io_uring ring; io_uring_queue_init(256, &ring, 0); struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); io_uring_prep_read(sqe, fd, buf, sizeof(buf), 0); io_uring_submit(&ring); struct io_uring_cqe *cqe; io_uring_wait_cqe(&ring, &cqe); printf("Read %d bytes\n", cqe->res); io_uring_cqe_seen(&ring, cqe); io_uring_queue_exit(&ring); ``` -------------------------------- ### Initialize io_uring Instance Source: https://github.com/axboe/liburing/blob/master/_autodocs/7-syscall-interface.md Use io_uring_setup to create a new io_uring instance. It returns a file descriptor for subsequent operations. The kernel fills in the io_uring_params structure with actual values. ```c int io_uring_setup(unsigned int entries, struct io_uring_params *p); ``` ```c struct io_uring_params p = {0}; int fd = io_uring_setup(256, &p); if (fd < 0) { fprintf(stderr, "io_uring_setup failed: %s\n", strerror(-fd)); return fd; } printf("Ring created. Features: 0x%x\n", p.features); ``` -------------------------------- ### Basic liburing I/O Operation Source: https://github.com/axboe/liburing/blob/master/_autodocs/00-START-HERE.md This snippet demonstrates the fundamental steps of initializing liburing, preparing a read operation, submitting it to the kernel, waiting for completion, and cleaning up the queue. It requires including the liburing header. ```c #include int main() { struct io_uring ring; /* Initialize with 256 entries */ io_uring_queue_init(256, &ring, 0); /* Get SQE and prepare operation */ struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); char buf[4096]; io_uring_prep_read(sqe, fd, buf, sizeof(buf), 0); /* Submit to kernel */ io_uring_submit(&ring); /* Wait for completion */ struct io_uring_cqe *cqe; io_uring_wait_cqe(&ring, &cqe); printf("Read %d bytes\n", cqe->res); io_uring_cqe_seen(&ring, cqe); /* Cleanup */ io_uring_queue_exit(&ring); return 0; } ``` -------------------------------- ### Setting up Buffer Ring for IOSQE_BUFFER_SELECT Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md The `IOSQE_BUFFER_SELECT` flag requires a buffer ring to be set up using `io_uring_setup_buf_ring()`. ```c /* IOSQE_BUFFER_SELECT requires buffer ring setup */ io_uring_setup_buf_ring(&ring, 32, bgid, 0, &err); ``` -------------------------------- ### Setting up a Provided Buffer Ring with Incremental Consumption Source: https://github.com/axboe/liburing/wiki/What's-new-with-io_uring-in-6.11-and-6.12 Demonstrates the flag required when registering a provided buffer ring to enable incremental consumption. This flag must be passed to `io_uring_setup_buf_ring` or `io_uring_register_buf_ring`. This feature is available from kernel 6.12. ```c #define IOU_PBUF_RING_INC 0x2 /* Incremental buffer consumption */ ``` -------------------------------- ### Initialize io_uring Ring Buffer Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Demonstrates three patterns for initializing an io_uring ring: simple initialization, initialization with custom parameters (e.g., SQPOLL), and initialization using pre-allocated memory. ```c /* Pattern 1: Simple initialization */ struct io_uring ring; io_uring_queue_init(256, &ring, 0); ``` ```c /* Pattern 2: With custom parameters */ struct io_uring_params p = {0}; p.flags = IORING_SETUP_SQPOLL; io_uring_queue_init_params(256, &ring, &p); ``` ```c /* Pattern 3: Pre-allocated memory */ char buf[8192]; io_uring_queue_init_mem(256, &ring, &p, buf, sizeof(buf)); ``` -------------------------------- ### Get io_uring Probe Structure Source: https://github.com/axboe/liburing/blob/master/_autodocs/6-registration-and-personality.md Creates a temporary io_uring instance internally, probes it, and returns the result. Caller must free with `io_uring_free_probe()`. ```c struct io_uring_probe *io_uring_get_probe(void); ``` -------------------------------- ### io_uring_submit_and_wait_reg Source: https://github.com/axboe/liburing/blob/master/_autodocs/9-advanced-features.md Submit and wait using a registered wait structure. This function allows submitting operations and waiting for completion using a pre-registered wait setup. ```APIDOC ## io_uring_submit_and_wait_reg ### Description Submit and wait using a registered wait structure. ### Parameters #### Path Parameters - **ring** (struct io_uring *) - Required - Initialized io_uring instance - **cqe_ptr** (struct io_uring_cqe **) - Required - Output: first CQE - **wait_nr** (unsigned) - Required - Number of CQEs to wait for - **reg_index** (int) - Required - Index of registered wait structure ### Return Value - Number of submitted SQEs on success - `-errno` on failure ``` -------------------------------- ### Free Kernel-Managed Buffer Ring Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Unregisters and frees a previously allocated kernel-managed buffer ring. Ensure all parameters match the ones used during setup. ```c int io_uring_free_buf_ring(struct io_uring *ring, struct io_uring_buf_ring *br, unsigned int nentries, int bgid); ``` -------------------------------- ### io_uring_prep_accept_direct Source: https://github.com/axboe/liburing/blob/master/_autodocs/5-operation-prep-functions.md Accept directly into the fixed file table. ```APIDOC ## io_uring_prep_accept_direct ### Description Accept directly into the fixed file table. The accepted socket file descriptor is placed directly into the fixed file table at the specified index, avoiding a separate register call. ### Parameters #### Path Parameters - **sqe** (struct io_uring_sqe *) - Required - Submission queue entry to initialize - **fd** (int) - Required - Listening socket file descriptor - **addr** (struct sockaddr *) - Required - Output: peer address - **addrlen** (socklen_t *) - Required - Input/output: address buffer size - **flags** (int) - Required - Accept flags - **file_index** (unsigned int) - Required - Target file index (or IORING_FILE_INDEX_ALLOC) ``` -------------------------------- ### Get io_uring Probe Structure from Existing Ring Source: https://github.com/axboe/liburing/blob/master/_autodocs/6-registration-and-personality.md Probes the kernel for supported operations using an existing ring. Requires an initialized io_uring instance. ```c struct io_uring_probe *io_uring_get_probe_ring(struct io_uring *ring); ``` -------------------------------- ### io_uring_cqe_shift_from_flags Source: https://github.com/axboe/liburing/blob/master/_autodocs/9-advanced-features.md Calculates the CQE array indexing shift based on the provided setup flags, determining the necessary bit shift for indexing completion queue entries. ```APIDOC ## io_uring_cqe_shift_from_flags ### Description Calculate CQE array indexing shift from setup flags. ### Method Signature ```c IOURINGINLINE unsigned io_uring_cqe_shift_from_flags(unsigned flags); ``` ### Parameters #### Path Parameters (No path parameters for this method) #### Query Parameters (No query parameters for this method) #### Request Body (No request body for this method) ### Parameters - **flags** (unsigned) - Yes - Setup flags from io_uring_params ### Return Value - `0` for normal CQEs (64 bytes) - `1` for big CQEs (128 bytes, requires IORING_SETUP_CQE32) ### Description Returns the bit shift needed to properly index the CQE array with variable CQE sizes. ``` -------------------------------- ### Prepare Accept Operation Source: https://github.com/axboe/liburing/blob/master/_autodocs/5-operation-prep-functions.md Use this function to set up an accept operation for incoming network connections. It prepares a submission queue entry (SQE) to accept a connection on a given file descriptor. ```c IOURINGINLINE void io_uring_prep_accept(struct io_uring_sqe *sqe, int fd, struct sockaddr *addr, socklen_t *addrlen, int flags); ``` ```c struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); io_uring_prep_accept(sqe, listen_fd, (struct sockaddr *)&addr, &addrlen, 0); ``` -------------------------------- ### liburing Useful Constants Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Commonly used constants and flags in liburing for operations such as timeouts, file indexing, SQE flags, CQE flags, and setup flags. ```c #define LIBURING_UDATA_TIMEOUT ((__u64) -1) /* File index allocation flag */ #define IORING_FILE_INDEX_ALLOC (~0U) /* SQE flags */ #define IOSQE_FIXED_FILE 0x00000001 #define IOSQE_IO_DRAIN 0x00000002 #define IOSQE_IO_LINK 0x00000004 #define IOSQE_IO_HARDLINK 0x00000008 #define IOSQE_ASYNC 0x00000010 #define IOSQE_BUFFER_SELECT 0x00000020 /* CQE flags */ #define IORING_CQE_F_NOTIF 0x00000001 #define IORING_CQE_F_MORE 0x00000002 #define IORING_CQE_F_DRAINING 0x00000004 /* Setup flags */ #define IORING_SETUP_IOPOLL 0x00000001 #define IORING_SETUP_SQPOLL 0x00000002 #define IORING_SETUP_SQ_AFF 0x00000004 #define IORING_SETUP_CQSIZE 0x00000008 #define IORING_SETUP_CLAMP 0x00000010 ``` -------------------------------- ### Example of Closing a GitHub Issue Source: https://github.com/axboe/liburing/blob/master/CONTRIBUTING.md If a commit resolves a GitHub issue, use the 'Closes' line to link to it. This automatically closes the issue on GitHub when the commit is merged. ```git Closes: https://github.com/axboe/liburing/issues/XXXX ``` -------------------------------- ### Using pkg-config for liburing Source: https://github.com/axboe/liburing/blob/master/_autodocs/MANIFEST.txt Utilize pkg-config to automatically fetch compiler and linker flags for liburing. ```c gcc myapp.c $(pkg-config --cflags --libs liburing) ``` -------------------------------- ### Compiling with liburing Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Link your application with the liburing library using GCC. The `pkg-config` utility can also be used to fetch the necessary compiler and linker flags. ```bash /* Link with liburing */ gcc -o myapp myapp.c -luring ``` ```bash /* Or use pkg-config */ gcc -o myapp myapp.c $(pkg-config --cflags --libs liburing) ``` ```bash /* For FFI (if needed) */ gcc -o myapp myapp.c -luring-ffi ``` -------------------------------- ### Get Buffer Ring Head Source: https://github.com/axboe/liburing/blob/master/_autodocs/9-advanced-features.md Retrieves the current head index of a specified buffer group within the io_uring instance. Use this to track available buffers. ```c int io_uring_buf_ring_head(struct io_uring *ring, int buf_group, uint16_t *head); ``` -------------------------------- ### Initialize and Prepare Basic Read Operation Source: https://github.com/axboe/liburing/blob/master/_autodocs/00-START-HERE.md Initializes the io_uring ring and prepares a single read operation. Ensure the ring is properly initialized before use. ```c io_uring_queue_init(256, &ring, 0); struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); io_uring_prep_read(sqe, fd, buf, len, offset); io_uring_submit(&ring); /* ... wait for completion ... */ ``` -------------------------------- ### Register File Allocation Range Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Sets the range for automatic file index allocation using `IORING_FILE_INDEX_ALLOC`. Specify the starting index and the number of available slots. ```c int io_uring_register_file_alloc_range(struct io_uring *ring, unsigned off, unsigned len); ``` -------------------------------- ### iovec Structure Source: https://github.com/axboe/liburing/blob/master/_autodocs/8-types-and-structures.md The standard POSIX structure for vector I/O, used to specify buffers for scatter-gather operations. It holds the starting address and length of a data buffer. ```c struct iovec { void *iov_base; /* Starting address */ size_t iov_len; /* Length of the buffer */ }; ``` -------------------------------- ### io_uring_prep_connect Source: https://github.com/axboe/liburing/blob/master/_autodocs/5-operation-prep-functions.md Prepare a connect operation. ```APIDOC ## io_uring_prep_connect ### Description Prepare a connect operation. ### Parameters #### Path Parameters - **sqe** (struct io_uring_sqe *) - Required - Submission queue entry to initialize - **fd** (int) - Required - Socket file descriptor - **addr** (const struct sockaddr *) - Required - Address to connect to - **addrlen** (socklen_t) - Required - Length of address structure ``` -------------------------------- ### io_uring_prep_accept Source: https://github.com/axboe/liburing/blob/master/_autodocs/5-operation-prep-functions.md Prepare an accept operation to accept incoming connections. ```APIDOC ## io_uring_prep_accept ### Description Prepare an accept operation to accept incoming connections. ### Parameters #### Path Parameters - **sqe** (struct io_uring_sqe *) - Required - Submission queue entry to initialize - **fd** (int) - Required - Listening socket file descriptor - **addr** (struct sockaddr *) - Required - Output: address of connected peer (or NULL) - **addrlen** (socklen_t *) - Required - Input/output: size of addr buffer (or NULL) - **flags** (int) - Required - Accept flags (SOCK_NONBLOCK, SOCK_CLOEXEC, etc.) ``` -------------------------------- ### Batch Processing with Iteration Source: https://github.com/axboe/liburing/blob/master/_autodocs/INDEX.md Shows how to efficiently iterate over all completed I/O events using `io_uring_for_each_cqe` and advance the completion queue. ```c struct io_uring_cqe *cqe; unsigned head; io_uring_for_each_cqe(&ring, head, cqe) { handle_completion(cqe); } io_uring_cq_advance(&ring, head); ``` -------------------------------- ### Initialize and Exit io_uring Queue Source: https://github.com/axboe/liburing/blob/master/_autodocs/1-queue-initialization.md Initializes an io_uring instance and demonstrates its subsequent exit. Must be called once for each successful init. ```c void io_uring_queue_exit(struct io_uring *ring); ``` ```c struct io_uring ring; io_uring_queue_init(256, &ring, 0); /* ... use ring ... */ io_uring_queue_exit(&ring); ``` -------------------------------- ### Example of Adding Link Metadata Source: https://github.com/axboe/liburing/blob/master/CONTRIBUTING.md You can include a 'Link' line in your commit message to reference external discussions or bug reports related to the change. This is useful for providing context. ```git Link: https://somesite/somewhere ``` -------------------------------- ### Registering Files for IOSQE_FIXED_FILE Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md The `IOSQE_FIXED_FILE` flag requires that file descriptors are registered using `io_uring_register_files()` before preparing the SQE. ```c /* IOSQE_FIXED_FILE requires io_uring_register_files() */ io_uring_register_files(&ring, fds, nfds); sqe->flags |= IOSQE_FIXED_FILE; ``` -------------------------------- ### Retrieve User Pointer from CQE Source: https://github.com/axboe/liburing/blob/master/_autodocs/2-submission-queue-api.md Use this function to get the opaque pointer that was previously associated with a submission queue entry via `io_uring_sqe_set_data()`. Returns NULL if no data was set. ```c IOURINGINLINE void *io_uring_cqe_get_data(const struct io_uring_cqe *cqe); ``` -------------------------------- ### Prepare Multishot Accept Operation Source: https://github.com/axboe/liburing/blob/master/_autodocs/5-operation-prep-functions.md Sets up a multishot accept operation, which allows for accepting multiple incoming connections on the same listening socket without resubmitting SQEs for each accept. ```c IOURINGINLINE void io_uring_prep_multishot_accept(struct io_uring_sqe *sqe, int fd, struct sockaddr *addr, socklen_t *addrlen, int flags); ``` -------------------------------- ### Get liburing CQE Entry Count Source: https://github.com/axboe/liburing/blob/master/_autodocs/3-completion-queue-api.md Returns the number of CQE entries occupied by a given CQE. This is 1 for normal CQEs and 2 for big CQEs (CQE32 format). ```c IOURINGINLINE unsigned io_uring_cqe_nr(const struct io_uring_cqe *cqe); ``` -------------------------------- ### io_uring_cqe_shift_from_flags Function Source: https://github.com/axboe/liburing/blob/master/_autodocs/9-advanced-features.md Calculates the CQE array indexing shift based on setup flags. Returns 0 for normal CQEs (64 bytes) and 1 for big CQEs (128 bytes). ```c IOURINGINLINE unsigned io_uring_cqe_shift_from_flags(unsigned flags); ``` -------------------------------- ### Prepare io_uring Vectored I/O Operations Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Demonstrates how to prepare vectored read (readv) and write (writev) operations using io_uring, allowing I/O across multiple buffers. ```c struct iovec iov[2] = { {.iov_base = buf1, .iov_len = 1024}, {.iov_base = buf2, .iov_len = 1024} }; io_uring_prep_readv(sqe, fd, iov, 2, offset); io_uring_prep_writev(sqe, fd, iov, 2, offset); ``` -------------------------------- ### Checking for NULL SQE Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Always check if `io_uring_get_sqe` returns NULL, which indicates the submission ring is full. If full, submit existing SQEs and wait before attempting to get a new one. ```c /* Wrong - SQE is NULL if ring full */ sqe = io_uring_get_sqe(&ring); io_uring_prep_read(sqe, fd, buf, 4096, 0); ``` ```c /* Right */ sqe = io_uring_get_sqe(&ring); if (!sqe) { /* Ring is full, need to submit and wait */ io_uring_submit_and_wait(&ring, 1); sqe = io_uring_get_sqe(&ring); } ``` -------------------------------- ### Clone Registered Buffers with Offset Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Clones a specified number of registered buffers between two io_uring instances, allowing control over starting offsets and flags. Use this for granular buffer copying. ```c int io_uring_clone_buffers_offset(struct io_uring *dst, struct io_uring *src, unsigned int dst_off, unsigned int src_off, unsigned int nr, unsigned int flags); ``` -------------------------------- ### io_uring_queue_init Source: https://github.com/axboe/liburing/blob/master/_autodocs/1-queue-initialization.md Initializes an io_uring instance with standard flags. It sets up the submission queue (SQ) and completion queue (CQ) with a specified number of entries. ```APIDOC ## io_uring_queue_init ### Description Initializes an io_uring instance with standard flags. It sets up the submission queue (SQ) and completion queue (CQ) with a specified number of entries. ### Function Signature ```c int io_uring_queue_init(unsigned entries, struct io_uring *ring, unsigned flags); ``` ### Parameters #### Path Parameters - **entries** (unsigned) - Required - Number of SQE entries (will be rounded to power of 2) - **ring** (struct io_uring *) - Required - Pointer to uninitialized io_uring structure - **flags** (unsigned) - Required - Setup flags (IORING_SETUP_*) ### Return Value - `0` on success - `-errno` on failure (e.g., EINVAL if entries is invalid, ENOMEM if memory allocation fails) ### Example ```c struct io_uring ring; int ret = io_uring_queue_init(256, &ring, 0); if (ret) { fprintf(stderr, "io_uring_queue_init failed: %s\n", strerror(-ret)); return ret; } ``` ``` -------------------------------- ### Prepare Connect Operation Source: https://github.com/axboe/liburing/blob/master/_autodocs/5-operation-prep-functions.md Prepares a connect operation to establish a connection to a specified address. This function initializes the SQE for a client-side connection attempt. ```c IOURINGINLINE void io_uring_prep_connect(struct io_uring_sqe *sqe, int fd, const struct sockaddr *addr, socklen_t addrlen); ``` -------------------------------- ### Get Next Submission Queue Entry (SQE) Source: https://github.com/axboe/liburing/blob/master/_autodocs/9-advanced-features.md Obtains a pointer to the next available submission queue entry (SQE) in the ring. Returns NULL if the ring is full, indicating no more entries can be submitted. ```c static inline struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring) ``` -------------------------------- ### Fixed Buffers Registration and Usage Source: https://github.com/axboe/liburing/blob/master/_autodocs/INDEX.md Illustrates how to register a set of fixed buffers for use with `io_uring` and prepare a read operation using one of these fixed buffers. ```c struct iovec iovecs[2] = { {.iov_base = buf1, .iov_len = 4096}, {.iov_base = buf2, .iov_len = 4096} }; io_uring_register_buffers(&ring, iovecs, 2); struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); io_uring_prep_read_fixed(sqe, fd, buf1, 4096, 0, 0); ``` -------------------------------- ### Updating or Adding Buffers with Tags Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Update existing registered buffers or add new ones to sparse slots, starting at a specified offset. Allows dynamic modification of the registered buffer set. ```c int io_uring_register_buffers_update_tag(struct io_uring *ring, unsigned off, const struct iovec *iovecs, const __u64 *tags, unsigned nr); ``` -------------------------------- ### io_uring_register_file_alloc_range Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Sets the range for automatic file index allocation within an io_uring instance. This function allows specifying the starting index and the number of slots available for automatic allocation using the IORING_FILE_INDEX_ALLOC flag. ```APIDOC ## io_uring_register_file_alloc_range ### Description Sets the range for automatic file index allocation. This function specifies which file indices can be automatically allocated via the `IORING_FILE_INDEX_ALLOC` flag. ### Method `int` ### Parameters #### Path Parameters - **ring** (struct io_uring *) - Required - Initialized io_uring instance - **off** (unsigned) - Required - Starting file index for allocation - **len** (unsigned) - Required - Number of slots available for allocation ### Return Value - `0` on success - `-errno` on failure ``` -------------------------------- ### Prepare Direct Accept Operation Source: https://github.com/axboe/liburing/blob/master/_autodocs/5-operation-prep-functions.md Prepares an accept operation that directly places the accepted socket file descriptor into the fixed file table. This avoids a separate registration call. ```c IOURINGINLINE void io_uring_prep_accept_direct(struct io_uring_sqe *sqe, int fd, struct sockaddr *addr, socklen_t *addrlen, int flags, unsigned int file_index); ``` -------------------------------- ### io_uring_clone_buffers_offset Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Clones a specified number of registered buffers from a source io_uring instance to a destination io_uring instance, with control over starting offsets and the number of buffers to clone. Flags can also be provided to modify the cloning behavior. ```APIDOC ## io_uring_clone_buffers_offset ### Description Clones buffers with offset control. ### Method `int` ### Parameters #### Path Parameters - **dst** (struct io_uring *) - Required - Destination io_uring instance - **src** (struct io_uring *) - Required - Source io_uring instance - **dst_off** (unsigned int) - Required - Starting index in destination - **src_off** (unsigned int) - Required - Starting index in source - **nr** (unsigned int) - Required - Number of buffers to clone - **flags** (unsigned int) - Required - Clone flags ### Return Value - `0` on success - `-errno` on failure ``` -------------------------------- ### Get liburing CQE Indexing Shift Source: https://github.com/axboe/liburing/blob/master/_autodocs/3-completion-queue-api.md Returns the bit shift value used for indexing CQEs. This is 0 for normal CQEs and 1 for big CQEs (CQE32 format), used internally for variable CQE sizes. ```c IOURINGINLINE unsigned io_uring_cqe_shift(const struct io_uring *ring); ``` -------------------------------- ### io_uring_setup_buf_ring Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Allocates and registers a kernel-managed buffer ring for use with io_uring operations like IORING_OP_RECV with IOSQE_BUFFER_SELECT. ```APIDOC ## io_uring_setup_buf_ring ### Description Creates a kernel-managed buffer ring that can be used with `IOSQE_BUFFER_SELECT` flag. Application can add buffers via buffer ring helpers. ### Method `io_uring_setup_buf_ring` ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Parameters - **ring** (`struct io_uring *`) - Required - Initialized io_uring instance - **nentries** (`unsigned int`) - Required - Number of buffer slots in the ring - **bgid** (`int`) - Required - Buffer group ID (0-65535) - **flags** (`unsigned int`) - Required - Registration flags (usually 0) - **err** (`int *`) - Required - Output: error code if allocation fails ### Return Value - Pointer to allocated buffer ring on success - NULL on failure (check `*err` for error code) ### Request Example ```c int err = 0; struct io_uring_buf_ring *br = io_uring_setup_buf_ring(&ring, 32, 0, 0, &err); if (!br) { fprintf(stderr, "setup_buf_ring failed: %s\n", strerror(err)); return err; } ``` ``` -------------------------------- ### io_uring_prep_multishot_accept Source: https://github.com/axboe/liburing/blob/master/_autodocs/5-operation-prep-functions.md Prepare a multishot accept operation. ```APIDOC ## io_uring_prep_multishot_accept ### Description Prepare a multishot accept operation. Generates multiple CQEs for successive accept operations on the same listening socket without needing to resubmit. ### Parameters #### Path Parameters - **sqe** (struct io_uring_sqe *) - Required - Submission queue entry to initialize - **fd** (int) - Required - Listening socket file descriptor - **addr** (struct sockaddr *) - Required - Output: peer address - **addrlen** (socklen_t *) - Required - Input/output: address buffer size - **flags** (int) - Required - Accept flags ``` -------------------------------- ### Prepare 64-bit Cancellation Operation Source: https://github.com/axboe/liburing/blob/master/_autodocs/5-operation-prep-functions.md Use io_uring_prep_cancel64 to initialize a submission queue entry for cancelling an operation identified by a 64-bit user_data. Ensure the sqe is properly initialized before calling. ```c IOURINGINLINE void io_uring_prep_cancel64(struct io_uring_sqe *sqe, __u64 user_data, int flags); ``` -------------------------------- ### io_uring_register_buffers_update_tag Source: https://github.com/axboe/liburing/blob/master/_autodocs/4-buffer-and-file-registration.md Updates or adds a buffer at a specific index in a registered set. This function is used to replace existing buffers or fill slots allocated by io_uring_register_buffers_sparse. It requires the io_uring instance, starting offset, iovec array, tags array, and the number of buffers to update. ```APIDOC ## io_uring_register_buffers_update_tag ### Description Updates or adds a buffer at a specific index in a registered set. This function is used to replace existing buffers or fill slots allocated by io_uring_register_buffers_sparse. It requires the io_uring instance, starting offset, iovec array, tags array, and the number of buffers to update. ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - **ring** (struct io_uring *) - Yes - Initialized io_uring instance - **off** (unsigned) - Yes - Starting buffer index - **iovecs** (const struct iovec *) - Yes - Array of iovec structures - **tags** (const __u64 *) - Yes - Array of 64-bit tags - **nr** (unsigned) - Yes - Number of buffers to update ### Request Example - No example provided in source. ### Response #### Success Response (0) - Success indicates the buffers were updated or added. #### Response Example ``` 0 ``` #### Error Response (-errno) - **EFAULT**: Invalid memory address. - **EINVAL**: Invalid argument. ``` -------------------------------- ### Batch io_uring Operations Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Shows how to efficiently submit multiple I/O operations at once and process multiple completions using liburing's batching capabilities. ```c /* Submit multiple ops at once */ for (int i = 0; i < 32; i++) { struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); io_uring_prep_read(sqe, fds[i], buffers[i], 4096, 0); } io_uring_submit(&ring); /* Process multiple completions */ struct io_uring_cqe *cqe; unsigned head; io_uring_for_each_cqe(&ring, head, cqe) { printf("Op completed: %d\n", cqe->res); } io_uring_cq_advance(&ring, head); ``` -------------------------------- ### Prepare io_uring Read/Write Operations Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Code snippets for preparing standard read and write operations within an io_uring submission queue entry (SQE). ```c io_uring_prep_read(sqe, fd, buf, len, offset); io_uring_prep_write(sqe, fd, buf, len, offset); ``` -------------------------------- ### Registering and Using Fixed Files Source: https://github.com/axboe/liburing/blob/master/_autodocs/QUICK-REFERENCE.md Register file descriptors to enable their use by index with the IOSQE_FIXED_FILE flag. Unregister when done. ```c /* Register file descriptors */ int files[4] = {fd1, fd2, fd3, fd4}; io_uring_register_files(&ring, files, 4); /* Use with IOSQE_FIXED_FILE flag */ sqe->flags |= IOSQE_FIXED_FILE; sqe->fd = 0; /* Index into registered files */ io_uring_prep_read(sqe, 0, buf, 4096, 0); /* Unregister when done */ io_uring_unregister_files(&ring); ``` -------------------------------- ### Initialize io_uring with Pre-allocated Memory Source: https://github.com/axboe/liburing/blob/master/_autodocs/1-queue-initialization.md Utilize io_uring_queue_init_mem when you need to provide your own memory buffer for the io_uring ring. This is beneficial for custom memory management or controlling memory locality. ```c int io_uring_queue_init_mem(unsigned entries, struct io_uring *ring, struct io_uring_params *p, void *buf, size_t buf_size); ```