File test-io_uring_register-fix-errno-confusion-and-new-e.patch of Package liburing

From: Jens Axboe <axboe@kernel.dk>
Date: Wed, 28 Jun 2023 19:43:02 -0600
Subject: test/io_uring_register: fix errno confusion and new error
Git-commit: 2d3368b73b478a737b2247ef5630be56c3b176b5
Patch-mainline: 2.5
References: kernel 6.5

This test suffers from some serious errno vs liburing function return.
All liburing functions return a negative errno value on failure, there's
no use of errno at all. This means that rather than check for the return
being -1 and then relying on errno being set to EINVAL, liburing
functions return -EINVAL directly instead.

Outside of that, due to recent kernel changes, we may now get -EFAULT
when trying to register a file backed buffers. Before we always returned
-EOPNOTSUPP. Correct that as well.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 test/io_uring_register.c | 51 +++++++++++++++++++---------------------
 1 file changed, 24 insertions(+), 27 deletions(-)

diff --git a/test/io_uring_register.c b/test/io_uring_register.c
index ddd4fe374702..0f44af85eed3 100644
--- a/test/io_uring_register.c
+++ b/test/io_uring_register.c
@@ -32,7 +32,7 @@ static rlim_t mlock_limit;
 static int devnull;
 
 static int expect_fail(int fd, unsigned int opcode, void *arg,
-	    unsigned int nr_args, int error)
+		       unsigned int nr_args, int error, int error2)
 {
 	int ret;
 
@@ -55,8 +55,8 @@ static int expect_fail(int fd, unsigned int opcode, void *arg,
 		return 1;
 	}
 
-	if (ret != error) {
-		fprintf(stderr, "expected %d, got %d\n", error, ret);
+	if (ret != error && (error2 && ret != error2)) {
+		fprintf(stderr, "expected %d/%d, got %d\n", error, error2, ret);
 		return 1;
 	}
 	return 0;
@@ -195,8 +195,7 @@ static int test_max_fds(int uring_fd)
 		status = 0;
 		ret = io_uring_register(uring_fd, IORING_UNREGISTER_FILES, 0, 0);
 		if (ret < 0) {
-			ret = errno;
-			errno = ret;
+			errno = -ret;
 			perror("io_uring_register UNREGISTER_FILES");
 			exit(1);
 		}
@@ -230,22 +229,20 @@ static int test_memlock_exceeded(int fd)
 
 	while (iov.iov_len) {
 		ret = io_uring_register(fd, IORING_REGISTER_BUFFERS, &iov, 1);
-		if (ret < 0) {
-			if (errno == ENOMEM) {
-				iov.iov_len /= 2;
-				continue;
-			}
-			if (errno == EFAULT) {
-				free(buf);
-				return 0;
-			}
-			fprintf(stderr, "expected success or EFAULT, got %d\n", errno);
+		if (ret == -ENOMEM) {
+			iov.iov_len /= 2;
+			continue;
+		} else if (ret == -EFAULT) {
+			free(buf);
+			return 0;
+		} else if (ret) {
+			fprintf(stderr, "expected success or EFAULT, got %d\n", ret);
 			free(buf);
 			return 1;
 		}
 		ret = io_uring_register(fd, IORING_UNREGISTER_BUFFERS, NULL, 0);
 		if (ret != 0) {
-			fprintf(stderr, "error: unregister failed with %d\n", errno);
+			fprintf(stderr, "error: unregister failed with %d\n", ret);
 			free(buf);
 			return 1;
 		}
@@ -277,15 +274,15 @@ static int test_iovec_nr(int fd)
 		iovs[i].iov_len = pagesize;
 	}
 
-	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, iovs, nr, -EINVAL);
+	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, iovs, nr, -EINVAL, 0);
 
 	/* reduce to UIO_MAXIOV */
 	nr = UIO_MAXIOV;
 	ret = io_uring_register(fd, IORING_REGISTER_BUFFERS, iovs, nr);
-	if (ret && (errno == ENOMEM || errno == EPERM) && geteuid()) {
+	if ((ret == -ENOMEM || ret == -EPERM) && geteuid()) {
 		fprintf(stderr, "can't register large iovec for regular users, skip\n");
 	} else if (ret != 0) {
-		fprintf(stderr, "expected success, got %d\n", errno);
+		fprintf(stderr, "expected success, got %d\n", ret);
 		status = 1;
 	} else {
 		io_uring_register(fd, IORING_UNREGISTER_BUFFERS, 0, 0);
@@ -308,12 +305,12 @@ static int test_iovec_size(int fd)
 	/* NULL pointer for base */
 	iov.iov_base = 0;
 	iov.iov_len = 4096;
-	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT);
+	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT, 0);
 
 	/* valid base, 0 length */
 	iov.iov_base = &buf;
 	iov.iov_len = 0;
-	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT);
+	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT, 0);
 
 	/* valid base, length exceeds size */
 	/* this requires an unampped page directly after buf */
@@ -324,7 +321,7 @@ static int test_iovec_size(int fd)
 	assert(ret == 0);
 	iov.iov_base = buf;
 	iov.iov_len = 2 * pagesize;
-	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT);
+	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT, 0);
 	munmap(buf, pagesize);
 
 	/* huge page */
@@ -372,7 +369,7 @@ static int test_iovec_size(int fd)
 		status = 1;
 	iov.iov_base = buf;
 	iov.iov_len = 2*1024*1024;
-	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EOPNOTSUPP);
+	status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT, -EOPNOTSUPP);
 	munmap(buf, 2*1024*1024);
 
 	/* bump up against the soft limit and make sure we get EFAULT
@@ -442,7 +439,7 @@ static int test_poll_ringfd(void)
 	 * fail, because the kernel does not allow registering of the
 	 * ring_fd.
 	 */
-	status |= expect_fail(fd, IORING_REGISTER_FILES, &fd, 1, -EBADF);
+	status |= expect_fail(fd, IORING_REGISTER_FILES, &fd, 1, -EBADF, 0);
 
 	/* tear down queue */
 	io_uring_queue_exit(&ring);
@@ -475,14 +472,14 @@ int main(int argc, char **argv)
 	}
 
 	/* invalid fd */
-	status |= expect_fail(-1, 0, NULL, 0, -EBADF);
+	status |= expect_fail(-1, 0, NULL, 0, -EBADF, 0);
 	/* valid fd that is not an io_uring fd */
-	status |= expect_fail(devnull, 0, NULL, 0, -EOPNOTSUPP);
+	status |= expect_fail(devnull, 0, NULL, 0, -EOPNOTSUPP, 0);
 
 	/* invalid opcode */
 	memset(&p, 0, sizeof(p));
 	fd = new_io_uring(1, &p);
-	ret = expect_fail(fd, ~0U, NULL, 0, -EINVAL);
+	ret = expect_fail(fd, ~0U, NULL, 0, -EINVAL, 0);
 	if (ret) {
 		/* if this succeeds, tear down the io_uring instance
 		 * and start clean for the next test. */
-- 
2.42.0

openSUSE Build Service is sponsored by