On Wed, Jun 23, 2021 at 02:58:32PM -0700, Omar Sandoval wrote: > Ah, I was stuck on thinking about this calling convention: > > struct encoded_iov encoded_iov; > char compressed_data[...]; > struct iovec iov[] = { > { &encoded_iov, sizeof(encoded_iov) }, > { compressed_data, sizeof(compressed_data) }, > }; > preadv2(fd, iov, 2, -1, RWF_ENCODED); > > But what you described would look more like: > > // Needs to be large enough for maximum returned header + data. > char buffer[...]; > struct iovec iov[] = { > { buffer, sizeof(buffer) }, > }; > preadv2(fd, iov, 2, -1, RWF_ENCODED); > // We should probably align the buffer. > struct encoded_iov *encoded_iov = (void *)buffer; > char *data = buffer + encoded_iov->size; > > That's a little uglier, but it should work, and allows for arbitrary > extensions. So, among these three alternatives (fixed size structure > with reserved space, variable size structure like above, or ioctl), > which would you prefer? Variable-sized structure would seem to be the easiest from the kernel POV and the interface is the easiest to describe - "you read the encoded data preceded by the header"...