public inbox for [email protected]
 help / color / mirror / Atom feed
* [BUG] ->flush and links
@ 2020-06-07 16:01 Pavel Begunkov
  0 siblings, 0 replies; only message in thread
From: Pavel Begunkov @ 2020-06-07 16:01 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe

There is a problem with io_uring_cancel_files -- it doesn't care about
links. If a request with ->files is not a head of a link, it won't be
found it in io-wq or elsewhere, and will wait for the head to be completed.
The problem is when the head won't ever complete.

e.g. req1: read empty pipe -> req2: openat
This leaves an uninterruptedly and indefinitely sleeping process.
see liburing patch below.

I was thinking about making dependant links traversable by io-wq cancel().

The similar problem can manifest itself with pending drained requests,
but solving this one would need cancellation of every prior request
in the drain queue, that's kind of nasty side effect for closing an
fd alias.

Any thoughts how to better deal with it?

diff --git a/test/lfs-openat.c b/test/lfs-openat.c
index d69096e..9fb96b7 100644
--- a/test/lfs-openat.c
+++ b/test/lfs-openat.c
@@ -75,6 +75,58 @@ static int prepare_file(int dfd, const char* fn)
 	return res < 0 ? res : 0;
 }
 
+static int test_linked_files(int dfd, const char *fn)
+{
+	struct io_uring ring;
+	struct io_uring_sqe *sqe;
+	char buffer[128];
+	struct iovec iov = {.iov_base = buffer, .iov_len = sizeof(buffer), };
+	int ret, fd;
+	int fds[2];
+
+	ret = io_uring_queue_init(10, &ring, 0);
+	if (ret < 0)
+		DIE("failed to init io_uring: %s\n", strerror(-ret));
+
+	if (pipe(fds)) {
+		perror("pipe");
+		return 1;
+	}
+
+	sqe = io_uring_get_sqe(&ring);
+	if (!sqe) {
+		printf("get sqe failed\n");
+		return -1;
+	}
+	io_uring_prep_readv(sqe, fds[0], &iov, 1, 0);
+	sqe->flags |= IOSQE_IO_LINK;
+
+	sqe = io_uring_get_sqe(&ring);
+	if (!sqe) {
+		fprintf(stderr, "failed to get sqe\n");
+		return 1;
+	}
+	io_uring_prep_openat(sqe, dfd, fn, OPEN_FLAGS, OPEN_MODE);
+
+	ret = io_uring_submit(&ring);
+	if (ret != 2) {
+		fprintf(stderr, "failed to submit openat: %s\n", strerror(-ret));
+		return 1;
+	}
+
+	fd = dup(ring.ring_fd);
+	if (fd < 0) {
+		fprintf(stderr, "dup() failed: %s\n", strerror(-fd));
+		return 1;
+	}
+
+	/* io_uring->flush() */
+	close(fd);
+
+	io_uring_queue_exit(&ring);
+	return 0;
+}
+
 int main(int argc, char *argv[])
 {
 	const char *fn = "io_uring_openat_test";
@@ -93,7 +145,17 @@ int main(int argc, char *argv[])
 		return 1;
 
 	ret = open_io_uring(&ring, dfd, fn);
+	if (ret) {
+		fprintf(stderr, "open_io_uring() failed\n");
+		goto out;
+	}
 
+	ret = test_linked_files(dfd, fn);
+	if (ret) {
+		fprintf(stderr, "test_linked_files() failed\n");
+		goto out;
+	}
+out:
 	io_uring_queue_exit(&ring);
 	close(dfd);
 	unlink("/tmp/io_uring_openat_test");


-- 
Pavel Begunkov

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-06-07 16:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-07 16:01 [BUG] ->flush and links Pavel Begunkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox