diff mbox series

[2/8] iov_iter: add iovec_nr_user_vecs() helper

Message ID 20230328173613.555192-3-axboe@kernel.dk (mailing list archive)
State Mainlined, archived
Headers show
Series Turn single segment imports into ITER_UBUF | expand

Commit Message

Jens Axboe March 28, 2023, 5:36 p.m. UTC
This returns the number of user segments in an iov_iter. The input can
either be an ITER_IOVEC, where it'll return the number of iovecs. Or it
can be an ITER_UBUF, in which case the number of segments is always 1.

Outside of those two, no user backed iterators exist. Just return 0 for
those.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 include/linux/uio.h | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Al Viro March 28, 2023, 6:42 p.m. UTC | #1
On Tue, Mar 28, 2023 at 11:36:07AM -0600, Jens Axboe wrote:
> This returns the number of user segments in an iov_iter. The input can
> either be an ITER_IOVEC, where it'll return the number of iovecs. Or it
> can be an ITER_UBUF, in which case the number of segments is always 1.
> 
> Outside of those two, no user backed iterators exist. Just return 0 for
> those.

Umm...  Why not set ->nr_segs to 1 in iov_iter_ubuf() instead?  Note that
it won't be more costly; that part of struct iov_iter (8 bytes at offset 40
on amd64) is *not* left uninitialized - zero gets stored there.  That way
you'll get constant 1 stored there, which is just as cheap...
Linus Torvalds March 28, 2023, 6:45 p.m. UTC | #2
On Tue, Mar 28, 2023 at 11:42 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> Umm...  Why not set ->nr_segs to 1 in iov_iter_ubuf() instead?  Note that
> it won't be more costly; that part of struct iov_iter (8 bytes at offset 40
> on amd64) is *not* left uninitialized - zero gets stored there.  That way
> you'll get constant 1 stored there, which is just as cheap...

Ack. And with my suggestion to embed a 'struct iov' in the 'struct
iov_iter' for the ITER_UBUF case (see previous email, try not to
barf), we really end up with a pretty cheap "ITER_UBUF can be used
almost as-is for any ITER_IOV case".

                 Linus
Jens Axboe March 28, 2023, 7:27 p.m. UTC | #3
On 3/28/23 12:42 PM, Al Viro wrote:
> On Tue, Mar 28, 2023 at 11:36:07AM -0600, Jens Axboe wrote:
>> This returns the number of user segments in an iov_iter. The input can
>> either be an ITER_IOVEC, where it'll return the number of iovecs. Or it
>> can be an ITER_UBUF, in which case the number of segments is always 1.
>>
>> Outside of those two, no user backed iterators exist. Just return 0 for
>> those.
> 
> Umm...  Why not set ->nr_segs to 1 in iov_iter_ubuf() instead?  Note that
> it won't be more costly; that part of struct iov_iter (8 bytes at offset 40
> on amd64) is *not* left uninitialized - zero gets stored there.  That way
> you'll get constant 1 stored there, which is just as cheap...

Good point, let's have a prep patch that does that too.
diff mbox series

Patch

diff --git a/include/linux/uio.h b/include/linux/uio.h
index 3b4403efcce1..8ba4d61e9e9b 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -168,6 +168,15 @@  static inline struct iovec iov_iter_iovec(const struct iov_iter *iter)
 	}
 }
 
+static inline int iovec_nr_user_vecs(const struct iov_iter *iter)
+{
+	if (iter_is_ubuf(iter))
+		return 1;
+	else if (iter->iter_type == ITER_IOVEC)
+		return iter->nr_segs;
+	return 0;
+}
+
 size_t copy_page_from_iter_atomic(struct page *page, unsigned offset,
 				  size_t bytes, struct iov_iter *i);
 void iov_iter_advance(struct iov_iter *i, size_t bytes);