[LTP] [RFC] [PATCH 1/2] io_uring: Test IORING READ and WRITE operations
Sachin Sant
sachinp@linux.ibm.com
Fri Mar 20 06:06:44 CET 2026
On 19/03/26 10:19 pm, Cyril Hrubis wrote:
> Hi!
>> # Tests below may cause kernel memory leak
>> perf_event_open03 perf_event_open03
>> diff --git a/testcases/kernel/syscalls/io_uring/.gitignore b/testcases/kernel/syscalls/io_uring/.gitignore
>> index 749db17db..9382ae413 100644
>> --- a/testcases/kernel/syscalls/io_uring/.gitignore
>> +++ b/testcases/kernel/syscalls/io_uring/.gitignore
>> @@ -1,2 +1,3 @@
>> /io_uring01
>> /io_uring02
>> +/io_uring03
>> diff --git a/testcases/kernel/syscalls/io_uring/io_uring03.c b/testcases/kernel/syscalls/io_uring/io_uring03.c
>> new file mode 100644
>> index 000000000..53d4feae5
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/io_uring/io_uring03.c
>> @@ -0,0 +1,145 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (C) 2026 IBM
>> + * Author: Sachin Sant <sachinp@linux.ibm.com>
>> + *
>> + * Test IORING_OP_READ and IORING_OP_WRITE operations.
>> + *
>> + * This test validates basic read and write operations using io_uring.
>> + * It tests:
>> + * 1. IORING_OP_WRITE - Writing data to a file
>> + * 2. IORING_OP_READ - Reading data from a file
>> + * 3. Data integrity verification
>> + */
> The second half of the comment should be doc comment (starts with /*\)
> so that it's picked up by the documentation parser and exported into the
> online documentation.
Ah yes, will modify.
>> +#include "io_uring_common.h"
>> +
>> +#define TEST_FILE "io_uring_test_file"
>> +#define QUEUE_DEPTH 2
>> +#define BLOCK_SZ 4096
>> +
>> +static char write_buf[BLOCK_SZ];
>> +static char read_buf[BLOCK_SZ];
>> +static struct io_uring_submit s;
>> +static sigset_t sig;
>> +
>> +static void test_write_read(void)
>> +{
>> + int fd;
>> + size_t i;
>> +
>> + /* Prepare write buffer with pattern */
> There a lot of comments like this that are commenting the
> obvious. Comments that comment obvious does not add any value and
> shouldn't be added.
Will revisit the code.
>> + for (i = 0; i < BLOCK_SZ; i++)
>> + write_buf[i] = 'A' + (i % 26);
> This should be done only once in the test setup.
Will address this in v2.
>> + /* Open file for writing */
>> + fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
>> +
>> + /* Test IORING_OP_WRITE */
>> + tst_res(TINFO, "Testing IORING_OP_WRITE");
>> + io_uring_submit_sqe(&s, fd, IORING_OP_WRITE, write_buf, BLOCK_SZ, 0);
>
>
>> + if (io_uring_wait_cqe(&s, BLOCK_SZ, IORING_OP_WRITE, &sig) == 0)
>> + tst_res(TPASS, "IORING_OP_WRITE completed successfully");
>> +
>> + /* Sync to ensure data is written */
>> + SAFE_FSYNC(fd);
>> +
>> + /* Test IORING_OP_READ */
>> + tst_res(TINFO, "Testing IORING_OP_READ");
>> + memset(read_buf, 0, BLOCK_SZ);
>> + io_uring_submit_sqe(&s, fd, IORING_OP_READ, read_buf, BLOCK_SZ, 0);
>> +
>> + if (io_uring_wait_cqe(&s, BLOCK_SZ, IORING_OP_READ, &sig) == 0)
>> + tst_res(TPASS, "IORING_OP_READ completed successfully");
>> +
>> + /* Verify data integrity */
>> + if (memcmp(write_buf, read_buf, BLOCK_SZ) == 0) {
>> + tst_res(TPASS, "Data integrity verified");
>> + } else {
>> + tst_res(TFAIL, "Data mismatch after read");
>> + for (i = 0; i < BLOCK_SZ && i < 64; i++) {
>> + if (write_buf[i] != read_buf[i]) {
>> + tst_res(TINFO, "First mismatch at offset %zu: "
>> + "wrote 0x%02x, read 0x%02x",
>> + i, write_buf[i], read_buf[i]);
>> + break;
>> + }
>> + }
>> + }
> This should really be put into a function and used in both test cases.
Will address it.
>> + SAFE_CLOSE(fd);
>> +}
>> +
>> +static void test_partial_io(void)
>> +{
>> + int fd;
>> + size_t half = BLOCK_SZ / 2;
>> + size_t i;
>> +
>> + tst_res(TINFO, "Testing partial I/O operations");
>> +
>> + /* Prepare buffer */
>> + for (i = 0; i < BLOCK_SZ; i++)
>> + write_buf[i] = 'a' + (i % 26);
>> +
>> + fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
>> +
>> + /* Write first half */
>> + io_uring_submit_sqe(&s, fd, IORING_OP_WRITE, write_buf, half, 0);
>> + if (io_uring_wait_cqe(&s, half, IORING_OP_WRITE, &sig) == 0)
>> + tst_res(TPASS, "Partial write (first half) succeeded");
>> +
>> + /* Write second half */
>> + io_uring_submit_sqe(&s, fd, IORING_OP_WRITE, write_buf + half,
>> + half, half);
>> + if (io_uring_wait_cqe(&s, half, IORING_OP_WRITE, &sig) == 0)
>> + tst_res(TPASS, "Partial write (second half) succeeded");
>> +
>> + SAFE_FSYNC(fd);
>> +
>> + /* Read back in one operation */
>> + memset(read_buf, 0, BLOCK_SZ);
>> + io_uring_submit_sqe(&s, fd, IORING_OP_READ, read_buf, BLOCK_SZ, 0);
>> + if (io_uring_wait_cqe(&s, BLOCK_SZ, IORING_OP_READ, &sig) == 0)
>> + tst_res(TPASS, "Full read after partial writes succeeded");
>> +
>> + /* Verify */
>> + if (memcmp(write_buf, read_buf, BLOCK_SZ) == 0)
>> + tst_res(TPASS, "Partial I/O data integrity verified");
>> + else
>> + tst_res(TFAIL, "Partial I/O data mismatch");
>> +
>> + SAFE_CLOSE(fd);
>> +}
>> +
>> +static void run(void)
>> +{
>> + io_uring_setup_queue(&s, QUEUE_DEPTH);
>> + test_write_read();
>> + test_partial_io();
>> + io_uring_cleanup_queue(&s, QUEUE_DEPTH);
>> +}
>> +
>> +static void setup(void)
>> +{
>> + io_uring_setup_supported_by_kernel();
>> + sigemptyset(&sig);
>> + memset(&s, 0, sizeof(s));
>> +}
>> +
>> +static struct tst_test test = {
>> + .test_all = run,
>> + .setup = setup,
>> + .needs_tmpdir = 1,
>> + .save_restore = (const struct tst_path_val[]) {
>> + {"/proc/sys/kernel/io_uring_disabled", "0",
>> + TST_SR_SKIP_MISSING | TST_SR_TCONF_RO},
>> + {}
>> + },
>> + .tags = (const struct tst_tag[]) {
>> + {"linux-git", "5d17b4a4b48c"},
> This commit does not appear to exist in linux kernel git tree.
I will double check on this. Thanks for the review.
>
>> + {"linux-git", "2b188cc1bb85"},
> And this is a commit that added io_uring. Commit hashes in tests are
> used only for cases where the test is a regression test for some bug and
> point to a commit that fixed the problem.
Understood. Based on the review, I will then remove this code since this is
a new testcase to improve coverage and not a regression test.
>
>> + {}
>> + }
>> +};
>> diff --git a/testcases/kernel/syscalls/io_uring/io_uring_common.h b/testcases/kernel/syscalls/io_uring/io_uring_common.h
> Since you are pulling the common code into header it would be nice to
> convert the io_uring01.c so that it uses the common header as well.
>
Will address this in V2.
Thanks again for the review.
--
Thanks
- Sachin
More information about the ltp
mailing list