Add an internal struct iovec that we can return as a pointer, with the fields of the iovec overlapping with the ITER_UBUF ubuf and length fields. This allows doing: struct iovec *vec = &iter->__ubuf_iovec; interchangably with iter->iov for the first segment, enabling writing code that deals with both without needing to check if we're dealing with ITER_IOVEC or ITER_UBUF. Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> --- include/linux/uio.h | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/include/linux/uio.h b/include/linux/uio.h index 3b4403efcce1..192831775d2b 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -49,14 +49,29 @@ struct iov_iter { size_t iov_offset; int last_offset; }; - size_t count; + /* + * Hack alert: overlay ubuf_iovec with iovec + count, so + * that the members resolve correctly regardless of the type + * of iterator used. This means that you can use: + * + * &iter->ubuf or iter->iov + * + * interchangably for the user_backed cases, hence simplifying + * some of the cases that need to deal with both. + */ union { - const struct iovec *iov; - const struct kvec *kvec; - const struct bio_vec *bvec; - struct xarray *xarray; - struct pipe_inode_info *pipe; - void __user *ubuf; + struct iovec __ubuf_iovec; + struct { + union { + const struct iovec *iov; + const struct kvec *kvec; + const struct bio_vec *bvec; + struct xarray *xarray; + struct pipe_inode_info *pipe; + void __user *ubuf; + }; + size_t count; + }; }; union { unsigned long nr_segs; -- 2.39.2