On Tue, Mar 28, 2023 at 11:43:34AM -0700, Linus Torvalds wrote: > - size_t count; > - 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; > + > + /* > + * This has the same layout as 'struct iovec'! > + * In particular, the ITER_UBUF form can create > + * a single-entry 'struct iovec' by casting the > + * address of the 'ubuf' member to that. > + */ > + 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; > > and if you accept the above, then you can do > > #define iter_ubuf_to_iov(iter) ((const struct iovec *)&(iter)->ubuf) > > which I will admit is not *pretty*, but it's kind of clever, I think. I think it'll annoy gcc, and particularly the randstruct plugin. How about: union { struct iovec ubuf; struct { const struct iovec *iov; size_t count; /* Also valid for subsequent types */ }; const struct kvec *kvec; const struct bio_vec *bvec; struct xarray *xarray; struct pipe_inode_info *pipe; }