public inbox for [email protected]
 help / color / mirror / Atom feed
From: Pavel Begunkov <[email protected]>
To: io-uring <[email protected]>
Cc: Jens Axboe <[email protected]>
Subject: [BUG] ->flush and links
Date: Sun, 7 Jun 2020 19:01:27 +0300	[thread overview]
Message-ID: <[email protected]> (raw)

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

                 reply	other threads:[~2020-06-07 16:02 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox