--- /dev/null
+From 09007af2b627f0f195c6c53c4829b285cc3990ec Mon Sep 17 00:00:00 2001
+From: Dylan Yudaken <dylany@fb.com>
+Date: Thu, 30 Jun 2022 06:20:06 -0700
+Subject: io_uring: fix provided buffer import
+
+From: Dylan Yudaken <dylany@fb.com>
+
+commit 09007af2b627f0f195c6c53c4829b285cc3990ec upstream.
+
+io_import_iovec uses the s pointer, but this was changed immediately
+after the iovec was re-imported and so it was imported into the wrong
+place.
+
+Change the ordering.
+
+Fixes: 2be2eb02e2f5 ("io_uring: ensure reads re-import for selected buffers")
+Signed-off-by: Dylan Yudaken <dylany@fb.com>
+Link: https://lore.kernel.org/r/20220630132006.2825668-1-dylany@fb.com
+[axboe: ensure we don't half-import as well]
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/io_uring.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -3495,6 +3495,13 @@ static ssize_t io_iov_buffer_select(stru
+ return __io_iov_buffer_select(req, iov, issue_flags);
+ }
+
++static inline bool io_do_buffer_select(struct io_kiocb *req)
++{
++ if (!(req->flags & REQ_F_BUFFER_SELECT))
++ return false;
++ return !(req->flags & REQ_F_BUFFER_SELECTED);
++}
++
+ static struct iovec *__io_import_iovec(int rw, struct io_kiocb *req,
+ struct io_rw_state *s,
+ unsigned int issue_flags)
+@@ -3854,18 +3861,19 @@ static int io_read(struct io_kiocb *req,
+ if (unlikely(ret < 0))
+ return ret;
+ } else {
++ rw = req->async_data;
++ s = &rw->s;
++
+ /*
+ * Safe and required to re-import if we're using provided
+ * buffers, as we dropped the selected one before retry.
+ */
+- if (req->flags & REQ_F_BUFFER_SELECT) {
++ if (io_do_buffer_select(req)) {
+ ret = io_import_iovec(READ, req, &iovec, s, issue_flags);
+ if (unlikely(ret < 0))
+ return ret;
+ }
+
+- rw = req->async_data;
+- s = &rw->s;
+ /*
+ * We come here from an earlier attempt, restore our state to
+ * match in case it doesn't. It's cheap enough that we don't