io_uring_prep_openat_direct() and link/drain

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I'm trying to read multiple files with io_uring and getting stuck,
because the link and drain flags don't seem to do what they are
documented to do.

Kernel is v5.17 and liburing is compiled from the git tree at
7a3a27b6a384 ("add tests for nonblocking accept sockets").

Without those flags the attached example works some of the time, but
that's probably accidental since ordering is not ensured.

Adding the drain or link flags make it even worse (fail in casese that
the unordered one didn't).

What am I missing?

Thanks,
Miklos
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <err.h>
#include "liburing.h"

#define CHECK_NEGERR(_expr) \
	({ typeof(_expr) _ret = (_expr); if (_ret < 0) { errno = -_ret; err(1, #_expr); } _ret; })
#define CHECK_NULL(_expr) \
	({ typeof(_expr) _ret = (_expr); if (_ret == NULL) { errx(1, #_expr " returned NULL"); } _ret; })


int main(int argc, char *argv[])
{
	struct io_uring ring;
	int ret, o, i, j, x, num, slot;
	struct io_uring_sqe *sqe;
	struct io_uring_cqe *cqe;
	char *s, **bufs;
	int *fds;
	const size_t bufsize = 131072;
	const int ops_per_file = 2;

	if (argc < 2)
		errx(1, "usage: %s file [...]", argv[0]);

	num = argc - 1;
	bufs = CHECK_NULL(calloc(num, sizeof(bufs[0])));
	fds = CHECK_NULL(calloc(num, sizeof(fds[0])));
	for (i = 0; i < num; i++) {
		bufs[i] = CHECK_NULL(malloc(bufsize));
		fds[i] = -1;
	}

	ret = CHECK_NEGERR(io_uring_queue_init(num * ops_per_file, &ring, 0));
	ret = CHECK_NEGERR(io_uring_register_files(&ring, fds, num));

	for (i = 0; i < num; i++) {
		slot = i;

		sqe = CHECK_NULL(io_uring_get_sqe(&ring));
		sqe->user_data = i * ops_per_file;
		io_uring_prep_openat_direct(sqe, AT_FDCWD, argv[i + 1],
					    O_RDONLY, 0, slot);
//		sqe->flags |= IOSQE_IO_DRAIN;
//		sqe->flags |= IOSQE_IO_LINK;

		sqe = CHECK_NULL(io_uring_get_sqe(&ring));
		sqe->user_data = i * ops_per_file + 1;
		io_uring_prep_read(sqe, slot, bufs[i], bufsize, 0);
		sqe->flags |= IOSQE_FIXED_FILE;
//		sqe->flags |= IOSQE_IO_DRAIN;
//		sqe->flags |= IOSQE_IO_LINK;
	}

	ret = CHECK_NEGERR(io_uring_submit(&ring));
	if (ret != num * ops_per_file)
		warnx("io_uring_submit submitted less: %d\n", ret);

	for (j = ret; j; j--) {
		CHECK_NEGERR(io_uring_wait_cqe(&ring, &cqe));

		x = cqe->user_data % ops_per_file;
		i = cqe->user_data / ops_per_file;
		printf("%i/%i [%s] = ", i, x, argv[i + 1]);

		ret = cqe->res;
		if (ret < 0) {
			printf("ERROR: %s (%i)\n", strerror(-ret), ret);
		} else if (x == 1) {
			s = bufs[i];

			for (o = 0; o < ret; o += strlen(s + o) + 1)
				printf("\"%.*s\" ", ret - o, s + o);

			printf("(len=%i)\n", ret);
		} else if (x == 0) {
			printf("SUCCESS open\n");
		} else {
			printf("SUCCESS ???\n");
		}
		io_uring_cqe_seen(&ring, cqe);
	}

	io_uring_queue_exit(&ring);
	return 0;
}

[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux