All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 5.10 02/63] iov_iter: add helper to save iov_iter state
Date: Tue,  3 Jan 2023 09:13:32 +0100	[thread overview]
Message-ID: <20230103081308.699550936@linuxfoundation.org> (raw)
In-Reply-To: <20230103081308.548338576@linuxfoundation.org>

From: Jens Axboe <axboe@kernel.dk>

[ Upstream commit 8fb0f47a9d7acf620d0fd97831b69da9bc5e22ed ]

In an ideal world, when someone is passed an iov_iter and returns X bytes,
then X bytes would have been consumed/advanced from the iov_iter. But we
have use cases that always consume the entire iterator, a few examples
of that are iomap and bdev O_DIRECT. This means we cannot rely on the
state of the iov_iter once we've called ->read_iter() or ->write_iter().

This would be easier if we didn't always have to deal with truncate of
the iov_iter, as rewinding would be trivial without that. We recently
added a commit to track the truncate state, but that grew the iov_iter
by 8 bytes and wasn't the best solution.

Implement a helper to save enough of the iov_iter state to sanely restore
it after we've called the read/write iterator helpers. This currently
only works for IOVEC/BVEC/KVEC as that's all we need, support for other
iterator types are left as an exercise for the reader.

Link: https://lore.kernel.org/linux-fsdevel/CAHk-=wiacKV4Gh-MYjteU0LwNBSGpWrK-Ov25HdqB1ewinrFPg@mail.gmail.com/
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/uio.h |   15 +++++++++++++++
 lib/iov_iter.c      |   52 +++++++++++++++++++++++++++++++++-------------------
 2 files changed, 48 insertions(+), 19 deletions(-)

--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -26,6 +26,12 @@ enum iter_type {
 	ITER_DISCARD = 64,
 };
 
+struct iov_iter_state {
+	size_t iov_offset;
+	size_t count;
+	unsigned long nr_segs;
+};
+
 struct iov_iter {
 	/*
 	 * Bit 0 is the read/write bit, set if we're writing.
@@ -55,6 +61,14 @@ static inline enum iter_type iov_iter_ty
 	return i->type & ~(READ | WRITE);
 }
 
+static inline void iov_iter_save_state(struct iov_iter *iter,
+				       struct iov_iter_state *state)
+{
+	state->iov_offset = iter->iov_offset;
+	state->count = iter->count;
+	state->nr_segs = iter->nr_segs;
+}
+
 static inline bool iter_is_iovec(const struct iov_iter *i)
 {
 	return iov_iter_type(i) == ITER_IOVEC;
@@ -226,6 +240,7 @@ ssize_t iov_iter_get_pages(struct iov_it
 ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages,
 			size_t maxsize, size_t *start);
 int iov_iter_npages(const struct iov_iter *i, int maxpages);
+void iov_iter_restore(struct iov_iter *i, struct iov_iter_state *state);
 
 const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags);
 
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -1836,24 +1836,38 @@ int import_single_range(int rw, void __u
 }
 EXPORT_SYMBOL(import_single_range);
 
-int iov_iter_for_each_range(struct iov_iter *i, size_t bytes,
-			    int (*f)(struct kvec *vec, void *context),
-			    void *context)
+/**
+ * iov_iter_restore() - Restore a &struct iov_iter to the same state as when
+ *     iov_iter_save_state() was called.
+ *
+ * @i: &struct iov_iter to restore
+ * @state: state to restore from
+ *
+ * Used after iov_iter_save_state() to bring restore @i, if operations may
+ * have advanced it.
+ *
+ * Note: only works on ITER_IOVEC, ITER_BVEC, and ITER_KVEC
+ */
+void iov_iter_restore(struct iov_iter *i, struct iov_iter_state *state)
 {
-	struct kvec w;
-	int err = -EINVAL;
-	if (!bytes)
-		return 0;
-
-	iterate_all_kinds(i, bytes, v, -EINVAL, ({
-		w.iov_base = kmap(v.bv_page) + v.bv_offset;
-		w.iov_len = v.bv_len;
-		err = f(&w, context);
-		kunmap(v.bv_page);
-		err;}), ({
-		w = v;
-		err = f(&w, context);})
-	)
-	return err;
+	if (WARN_ON_ONCE(!iov_iter_is_bvec(i) && !iter_is_iovec(i)) &&
+			 !iov_iter_is_kvec(i))
+		return;
+	i->iov_offset = state->iov_offset;
+	i->count = state->count;
+	/*
+	 * For the *vec iters, nr_segs + iov is constant - if we increment
+	 * the vec, then we also decrement the nr_segs count. Hence we don't
+	 * need to track both of these, just one is enough and we can deduct
+	 * the other from that. ITER_KVEC and ITER_IOVEC are the same struct
+	 * size, so we can just increment the iov pointer as they are unionzed.
+	 * ITER_BVEC _may_ be the same size on some archs, but on others it is
+	 * not. Be safe and handle it separately.
+	 */
+	BUILD_BUG_ON(sizeof(struct iovec) != sizeof(struct kvec));
+	if (iov_iter_is_bvec(i))
+		i->bvec -= state->nr_segs - i->nr_segs;
+	else
+		i->iov -= state->nr_segs - i->nr_segs;
+	i->nr_segs = state->nr_segs;
 }
-EXPORT_SYMBOL(iov_iter_for_each_range);



  parent reply	other threads:[~2023-01-03  8:14 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-03  8:13 [PATCH 5.10 00/63] 5.10.162-rc1 review Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 01/63] kernel: provide create_io_thread() helper Greg Kroah-Hartman
2023-01-03  8:13 ` Greg Kroah-Hartman [this message]
2023-01-03  8:13 ` [PATCH 5.10 03/63] saner calling conventions for unlazy_child() Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 04/63] fs: add support for LOOKUP_CACHED Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 05/63] fix handling of nd->depth on LOOKUP_CACHED failures in try_to_unlazy* Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 06/63] Make sure nd->path.mnt and nd->path.dentry are always valid pointers Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 07/63] fs: expose LOOKUP_CACHED through openat2() RESOLVE_CACHED Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 08/63] tools headers UAPI: Sync openat2.h with the kernel sources Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 09/63] net: provide __sys_shutdown_sock() that takes a socket Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 10/63] net: add accept helper not installing fd Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 11/63] signal: Add task_sigpending() helper Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 12/63] fs: make do_renameat2() take struct filename Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 13/63] file: Rename __close_fd_get_file close_fd_get_file Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 14/63] fs: provide locked helper variant of close_fd_get_file() Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 15/63] entry: Add support for TIF_NOTIFY_SIGNAL Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 16/63] task_work: Use TIF_NOTIFY_SIGNAL if available Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 17/63] x86: Wire up TIF_NOTIFY_SIGNAL Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 18/63] arc: add support for TIF_NOTIFY_SIGNAL Greg Kroah-Hartman
2023-01-03  8:13   ` Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 19/63] arm64: " Greg Kroah-Hartman
2023-01-03  8:13   ` Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 20/63] m68k: " Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 21/63] nios32: " Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 22/63] parisc: " Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 23/63] powerpc: " Greg Kroah-Hartman
2023-01-03  8:13   ` Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 24/63] mips: " Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 25/63] s390: " Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 26/63] um: " Greg Kroah-Hartman
2023-01-03  8:13   ` Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 27/63] sh: " Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 28/63] openrisc: " Greg Kroah-Hartman
2023-01-03  8:13   ` Greg Kroah-Hartman
2023-01-03  8:13 ` [PATCH 5.10 29/63] csky: " Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 30/63] hexagon: " Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 31/63] microblaze: " Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 32/63] arm: " Greg Kroah-Hartman
2023-01-03  8:14   ` Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 33/63] xtensa: " Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 34/63] alpha: " Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 35/63] c6x: " Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 36/63] h8300: " Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 37/63] ia64: " Greg Kroah-Hartman
2023-01-03  8:14   ` Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 38/63] nds32: " Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 39/63] riscv: " Greg Kroah-Hartman
2023-01-03  8:14   ` Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 40/63] sparc: " Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 41/63] ia64: dont call handle_signal() unless theres actually a signal queued Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 42/63] ARC: unbork 5.11 bootup: fix snafu in _TIF_NOTIFY_SIGNAL handling Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 43/63] alpha: fix TIF_NOTIFY_SIGNAL handling Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 44/63] task_work: remove legacy TWA_SIGNAL path Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 45/63] kernel: remove checking for TIF_NOTIFY_SIGNAL Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 46/63] coredump: Limit what can interrupt coredumps Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 47/63] kernel: allow fork with TIF_NOTIFY_SIGNAL pending Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 48/63] entry/kvm: Exit to user mode when TIF_NOTIFY_SIGNAL is set Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 49/63] arch: setup PF_IO_WORKER threads like PF_KTHREAD Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 50/63] arch: ensure parisc/powerpc handle PF_IO_WORKER in copy_thread() Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 51/63] x86/process: setup io_threads more like normal user space threads Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 52/63] kernel: stop masking signals in create_io_thread() Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 53/63] kernel: dont call do_exit() for PF_IO_WORKER threads Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 54/63] task_work: add helper for more targeted task_work canceling Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 55/63] io_uring: import 5.15-stable io_uring Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 56/63] signal: kill JOBCTL_TASK_WORK Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 57/63] task_work: unconditionally run task_work from get_signal() Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 58/63] net: remove cmsg restriction from io_uring based send/recvmsg calls Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 59/63] Revert "proc: dont allow async path resolution of /proc/thread-self components" Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 60/63] Revert "proc: dont allow async path resolution of /proc/self components" Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 61/63] eventpoll: add EPOLL_URING_WAKE poll wakeup flag Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 62/63] eventfd: provide a eventfd_signal_mask() helper Greg Kroah-Hartman
2023-01-03  8:14 ` [PATCH 5.10 63/63] io_uring: pass in EPOLL_URING_WAKE for eventfd signaling and wakeups Greg Kroah-Hartman
2023-01-03 13:44 ` [PATCH 5.10 00/63] 5.10.162-rc1 review Pavel Machek
2023-01-03 14:51 ` Guenter Roeck
2023-01-03 15:32 ` Jon Hunter
2023-01-03 16:16 ` Joel Fernandes
2023-01-04  5:29   ` Greg Kroah-Hartman
2023-01-04 21:56     ` Joel Fernandes
2023-01-05 11:43       ` Greg Kroah-Hartman
2023-01-03 18:16 ` Naresh Kamboju
2023-01-03 18:27 ` Florian Fainelli
2023-01-03 18:59 ` Allen Pais

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 \
    --in-reply-to=20230103081308.699550936@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=axboe@kernel.dk \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.