On Tue, May 09, 2023 at 09:21:38PM +0000, Taylor R Campbell wrote: > I propose adding uiopeek(buf, n, uio) and uioskip(n, uio) which > together are equivalent to successful uiomove(buf, n, uio). > > This allows a driver to separately: > 1. transfer data into a buffer (uiopeek) first, and then > 2. advance the uio (uioskip) only after determining how much of the > data the driver was able to actually process. > > Thoughts?
I also prefer the name "uioadvance", because that seems like it characterizes the operation better. Otherwise, seems fine. > (a) Is ttwrite violating a contract by advancing the uio's iovs past > the number of bytes it consumed of uio_resid? Yes, IMO. That's supposed to be an invariant of the data structure, and it shouldn't get broken, even on error. > P.S. I suspect this issue will also apply in the EFAULT case. If you > try to uiomove (say) 2 bytes in separate iov entries, and the > first iov doesn't fault but the second iov does, uiomove will > advance the uio by one byte but return error. That also seems totally wrong. (In general, erroring in I/O is a whole additional can of worms; it's wrong to not report back however much work happened before the error when it can't be undone, but also impossible to both report work and raise an error. And unfortunately in the presence of things like generational garbage collectors, it's unsafe to assume that it doesn't matter because EFAULT is fatal/unrecoverable.) -- David A. Holland dholl...@netbsd.org