1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) Crackerjack Project., 2007 4f08c3bdfSopenharmony_ci * Ported from Crackerjack to LTP by Masatake YAMATO <yamato@redhat.com> 5f08c3bdfSopenharmony_ci * Copyright (c) 2011-2017 Cyril Hrubis <chrubis@suse.cz> 6f08c3bdfSopenharmony_ci * Copyright (c) 2021 Xie Ziyao <xieziyao@huawei.com> 7f08c3bdfSopenharmony_ci */ 8f08c3bdfSopenharmony_ci 9f08c3bdfSopenharmony_ci/*\ 10f08c3bdfSopenharmony_ci * [Description] 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * Test io_submit invoked via syscall(2): 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * 1. io_submit() returns the number of iocbs submitted. 15f08c3bdfSopenharmony_ci * 2. io_submit() returns 0 if nr is zero. 16f08c3bdfSopenharmony_ci */ 17f08c3bdfSopenharmony_ci 18f08c3bdfSopenharmony_ci#include <linux/aio_abi.h> 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#include "config.h" 21f08c3bdfSopenharmony_ci#include "tst_test.h" 22f08c3bdfSopenharmony_ci#include "lapi/syscalls.h" 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_ci#define TEST_FILE "test_file" 25f08c3bdfSopenharmony_ci#define MODE 0777 26f08c3bdfSopenharmony_ci 27f08c3bdfSopenharmony_cistatic int fd; 28f08c3bdfSopenharmony_cistatic char buf[100]; 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_cistatic aio_context_t ctx; 31f08c3bdfSopenharmony_cistatic struct iocb iocb; 32f08c3bdfSopenharmony_cistatic struct iocb *iocbs[] = {&iocb}; 33f08c3bdfSopenharmony_ci 34f08c3bdfSopenharmony_cistatic struct tcase { 35f08c3bdfSopenharmony_ci aio_context_t *ctx; 36f08c3bdfSopenharmony_ci long nr; 37f08c3bdfSopenharmony_ci struct iocb **iocbs; 38f08c3bdfSopenharmony_ci const char *desc; 39f08c3bdfSopenharmony_ci} tc[] = { 40f08c3bdfSopenharmony_ci {&ctx, 1, iocbs, "returns the number of iocbs submitted"}, 41f08c3bdfSopenharmony_ci {&ctx, 0, NULL, "returns 0 if nr is zero"}, 42f08c3bdfSopenharmony_ci}; 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_cistatic inline void io_prep_option(struct iocb *cb, int fd, void *buf, 45f08c3bdfSopenharmony_ci size_t count, long long offset, unsigned opcode) 46f08c3bdfSopenharmony_ci{ 47f08c3bdfSopenharmony_ci memset(cb, 0, sizeof(*cb)); 48f08c3bdfSopenharmony_ci cb->aio_fildes = fd; 49f08c3bdfSopenharmony_ci cb->aio_lio_opcode = opcode; 50f08c3bdfSopenharmony_ci cb->aio_buf = (uint64_t)buf; 51f08c3bdfSopenharmony_ci cb->aio_offset = offset; 52f08c3bdfSopenharmony_ci cb->aio_nbytes = count; 53f08c3bdfSopenharmony_ci} 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_cistatic void setup(void) 56f08c3bdfSopenharmony_ci{ 57f08c3bdfSopenharmony_ci TST_EXP_PASS_SILENT(tst_syscall(__NR_io_setup, 1, &ctx)); 58f08c3bdfSopenharmony_ci fd = SAFE_OPEN(TEST_FILE, O_RDONLY | O_CREAT, MODE); 59f08c3bdfSopenharmony_ci io_prep_option(&iocb, fd, buf, 0, 0, IOCB_CMD_PREAD); 60f08c3bdfSopenharmony_ci} 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_cistatic void cleanup(void) 63f08c3bdfSopenharmony_ci{ 64f08c3bdfSopenharmony_ci if (fd > 0) 65f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_ci if (tst_syscall(__NR_io_destroy, ctx)) 68f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "io_destroy() failed"); 69f08c3bdfSopenharmony_ci} 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_cistatic void run(unsigned int i) 72f08c3bdfSopenharmony_ci{ 73f08c3bdfSopenharmony_ci struct io_event evbuf; 74f08c3bdfSopenharmony_ci struct timespec timeout = { .tv_sec = 1 }; 75f08c3bdfSopenharmony_ci long j; 76f08c3bdfSopenharmony_ci 77f08c3bdfSopenharmony_ci TEST(tst_syscall(__NR_io_submit, *tc[i].ctx, tc[i].nr, tc[i].iocbs)); 78f08c3bdfSopenharmony_ci 79f08c3bdfSopenharmony_ci if (TST_RET == tc[i].nr) 80f08c3bdfSopenharmony_ci tst_res(TPASS, "io_submit() %s", tc[i].desc); 81f08c3bdfSopenharmony_ci else 82f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "io_submit() returns %ld, expected %ld", TST_RET, tc[i].nr); 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ci for (j = 0; j < TST_RET; j++) { 85f08c3bdfSopenharmony_ci tst_syscall(__NR_io_getevents, *tc[i].ctx, 1, 1, &evbuf, 86f08c3bdfSopenharmony_ci &timeout); 87f08c3bdfSopenharmony_ci } 88f08c3bdfSopenharmony_ci} 89f08c3bdfSopenharmony_ci 90f08c3bdfSopenharmony_cistatic struct tst_test test = { 91f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tc), 92f08c3bdfSopenharmony_ci .needs_tmpdir = 1, 93f08c3bdfSopenharmony_ci .needs_kconfigs = (const char *[]) { 94f08c3bdfSopenharmony_ci "CONFIG_AIO=y", 95f08c3bdfSopenharmony_ci NULL 96f08c3bdfSopenharmony_ci }, 97f08c3bdfSopenharmony_ci .setup = setup, 98f08c3bdfSopenharmony_ci .cleanup = cleanup, 99f08c3bdfSopenharmony_ci .test = run, 100f08c3bdfSopenharmony_ci}; 101