From: David Howells
Sent: 15 September 2023 13:36
David Laight David.Laight@ACULAB.COM wrote:
I was thinking of import_iovec() - or whatever its current name is.
That doesn't actually access the buffer described by the iovec[].
That really needs a single structure that contains the iov_iter and the cache[] (which the caller pretty much always allocates in the same place).
cache[]?
Ah it is usually called iovstack[].
That is the code that reads the iovec[] from user. For small counts there is an on-stack cache[], for large counts it has call kmalloc(). So when the io completes you have to free the allocated buffer.
A canonical example is:
static ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, unsigned long vlen, loff_t *pos, rwf_t flags) { struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; struct iov_iter iter; ssize_t ret;
ret = import_iovec(ITER_DEST, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); if (ret >= 0) { ret = do_iter_read(file, &iter, pos, flags); kfree(iov); }
return ret; }
If 'iter' and 'iovstack' are put together in a structure the calling sequence becomes much less annoying. The kfree() can (probably) check iter.iovec != iovsatack (as an inline).
But io_uring manages to allocate the iov_iter and iovstack[] in entirely different places - and then copies them about.
David
- Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)