Userspace can freely pass in whatever iovec it feels like, and it's perfectly
legal to pass an iovec which contains a zero length segment. In the current
implementation, uio_prefaultpages would touch an out of bound byte in the
"last byte" logic. While this probably wouldn't cause any critical error, we
would like uio_prefaultpages to be able to continue gracefully.
Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #4078
caddr_t p;
uint8_t tmp;
int iovcnt;
- size_t skip = uio->uio_skip;
+ size_t skip;
/* no need to fault in kernel pages */
switch (uio->uio_segflg) {
iov = uio->uio_iov;
iovcnt = uio->uio_iovcnt;
+ skip = uio->uio_skip;
- while ((n > 0) && (iovcnt > 0)) {
+ for (; n > 0 && iovcnt > 0; iov++, iovcnt--, skip = 0) {
cnt = MIN(iov->iov_len - skip, n);
+ /* empty iov */
+ if (cnt == 0)
+ continue;
n -= cnt;
/*
* touch each page in this segment.
p--;
if (fuword8((uint8_t *) p, &tmp))
return;
- iov++;
- iovcnt--;
- skip = 0;
}
}
EXPORT_SYMBOL(uio_prefaultpages);