[WIP PATCH] liburing: Support IORING_OP_OPENAT2_FIXED_FILE

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

 



Update io_uring.h to match the corresponding kernel changes.

Signed-off-by: Josh Triplett <josh@xxxxxxxxxxxxxxxx>
---

I've tested this, and it works. The test I'd propose is "open two files,
read bytes from both files, test if they have the expected values", to
make sure each operation operates on the right file. I've attached a
draft of that test that submits the read operations in a separate batch,
which passes.

 src/include/liburing.h          | 10 ++++++++++
 src/include/liburing/io_uring.h |  6 +++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/include/liburing.h b/src/include/liburing.h
index 0505a4f..0352837 100644
--- a/src/include/liburing.h
+++ b/src/include/liburing.h
@@ -412,6 +412,16 @@ static inline void io_uring_prep_openat2(struct io_uring_sqe *sqe, int dfd,
 				(uint64_t) (uintptr_t) how);
 }
 
+static inline void io_uring_prep_openat2_fixed_file(struct io_uring_sqe *sqe,
+                                                    int dfd, const char *path,
+                                                    struct open_how *how,
+                                                    uint32_t index)
+{
+        io_uring_prep_rw(IORING_OP_OPENAT2_FIXED_FILE, sqe, dfd, path,
+                                sizeof(*how), (uint64_t) (uintptr_t) how);
+        sqe->open_fixed_idx = index;
+}
+
 struct epoll_event;
 static inline void io_uring_prep_epoll_ctl(struct io_uring_sqe *sqe, int epfd,
 					   int fd, int op,
diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h
index d39b45f..0d2c41b 100644
--- a/src/include/liburing/io_uring.h
+++ b/src/include/liburing/io_uring.h
@@ -59,7 +59,10 @@ struct io_uring_sqe {
 			} __attribute__((packed));
 			/* personality to use, if used */
 			__u16	personality;
-			__s32	splice_fd_in;
+			union {
+				__s32	splice_fd_in;
+				__s32	open_fixed_idx;
+			};
 		};
 		__u64	__pad2[3];
 	};
@@ -135,6 +138,7 @@ enum {
 	IORING_OP_PROVIDE_BUFFERS,
 	IORING_OP_REMOVE_BUFFERS,
 	IORING_OP_TEE,
+	IORING_OP_OPENAT2_FIXED_FILE,
 
 	/* this goes last, obviously */
 	IORING_OP_LAST,
-- 
2.28.0.rc0

/* SPDX-License-Identifier: MIT */
/*
 * Description: test open with fixed-file support
 *
 */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

#include "liburing.h"

static int create_file(const char *file, size_t size, int byte)
{
	ssize_t ret;
	char *buf;
	int fd;

	buf = malloc(size);
	memset(buf, byte, size);

	fd = open(file, O_WRONLY | O_CREAT, 0644);
	if (fd < 0) {
		perror("open file");
		return 1;
	}
	ret = write(fd, buf, size);
	close(fd);
	return ret != size;
}

static int test_openat2_fixed_file(struct io_uring *ring, const char *path1, const char *path2)
{
	struct io_uring_cqe *cqe;
	struct io_uring_sqe *sqe;
	struct open_how how = { .flags = O_RDONLY };
	int ret;
	int fds[2] = { -1, -1 };
	unsigned char byte1 = 0, byte2 = 0;
	int i;

	ret = io_uring_register_files(ring, fds, 2);

	sqe = io_uring_get_sqe(ring);
	io_uring_prep_openat2_fixed_file(sqe, -1, path1, &how, 0);
	sqe->flags |= IOSQE_IO_LINK;

	sqe = io_uring_get_sqe(ring);
	io_uring_prep_openat2_fixed_file(sqe, -1, path2, &how, 1);
	sqe->flags |= IOSQE_IO_LINK;

	ret = io_uring_submit(ring);
	if (ret != 2) {
		fprintf(stderr, "sqe submit failed: %d\n", ret);
		goto err;
	}

	for (i = 0; i < 2; i++) {
		ret = io_uring_wait_cqe(ring, &cqe);
		if (ret < 0) {
			fprintf(stderr, "wait completion %d\n", ret);
			goto err;
		}

		ret = cqe->res;
		if (ret < 0) {
			fprintf(stderr, "operation %d failed: %d\n", i, ret);
			goto err;
		}
		io_uring_cqe_seen(ring, cqe);
	}

	sqe = io_uring_get_sqe(ring);
	io_uring_prep_read(sqe, 0, &byte1, 1, 0);
	sqe->flags |= IOSQE_FIXED_FILE;

	sqe = io_uring_get_sqe(ring);
	io_uring_prep_read(sqe, 1, &byte2, 1, 0);
	sqe->flags |= IOSQE_FIXED_FILE;

	ret = io_uring_submit(ring);
	if (ret != 2) {
		fprintf(stderr, "sqe submit failed: %d\n", ret);
		goto err;
	}

	for (i = 0; i < 2; i++) {
		ret = io_uring_wait_cqe(ring, &cqe);
		if (ret < 0) {
			fprintf(stderr, "wait completion %d\n", ret);
			goto err;
		}

		ret = cqe->res;
		if (ret < 0) {
			fprintf(stderr, "operation %d failed: %d\n", i, ret);
			goto err;
		}
		io_uring_cqe_seen(ring, cqe);
	}

	if (byte1 != 0x11 || byte2 != 0x22) {
		fprintf(stderr, "bytes did not have expected values: %x %x\n",
			(unsigned)byte1, (unsigned)byte2);
		ret = -1;
		goto err;
	}

err:
	return ret;
}

int main(int argc, char *argv[])
{
	struct io_uring ring;
	const char *path1, *path2;
	int ret;

	ret = io_uring_queue_init(8, &ring, 0);
	if (ret) {
		fprintf(stderr, "ring setup failed\n");
		return 1;
	}

	path1 = "/tmp/.open.close.1";
	path2 = "/tmp/.open.close.2";

	if (create_file(path1, 4096, 0x11) || create_file(path2, 4096, 0x22)) {
		fprintf(stderr, "file create failed\n");
		return 1;
	}

	ret = test_openat2_fixed_file(&ring, path1, path2);
	if (ret < 0) {
		if (ret == -EINVAL) {
			fprintf(stdout, "openat2 not supported, skipping\n");
			goto done;
		}
		fprintf(stderr, "test_openat2 failed: %d\n", ret);
		goto err;
	}

done:
	unlink(path1);
	unlink(path2);
	return 0;
err:
	unlink(path1);
	unlink(path2);
	return 1;
}


[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