linux/uio: remove "skip" offset for UIO_ITER

For UIO_ITER, we are just wrapping a kernel iterator. It will take care
of its own offsets if necessary. We don't need to do anything, and if we
do try to do anything with it (like advancing the iterator by the skip
in zfs_uio_advance) we're just confusing the kernel iterator, ending up
at the wrong position or worse, off the end of the memory region.

Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Tino Reichardt <milky-zfs@mcmilk.de>
Reviewed-by: Brian Atkinson <batkinson@lanl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #17298
This commit is contained in:
Rob Norris 2025-05-12 02:46:40 +10:00 committed by GitHub
parent c17bdc4914
commit 2ee5b51a57
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 9 additions and 11 deletions

View File

@ -174,7 +174,7 @@ zfs_uio_bvec_init(zfs_uio_t *uio, struct bio *bio, struct request *rq)
static inline void
zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
ssize_t resid, size_t skip)
ssize_t resid)
{
uio->uio_iter = iter;
uio->uio_iovcnt = iter->nr_segs;
@ -184,7 +184,7 @@ zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
uio->uio_fmode = 0;
uio->uio_extflg = 0;
uio->uio_resid = resid;
uio->uio_skip = skip;
uio->uio_skip = 0;
uio->uio_soffset = uio->uio_loffset;
memset(&uio->uio_dio, 0, sizeof (zfs_uio_dio_t));
}

View File

@ -233,9 +233,6 @@ zfs_uiomove_iter(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio,
{
size_t cnt = MIN(n, uio->uio_resid);
if (uio->uio_skip)
iov_iter_advance(uio->uio_iter, uio->uio_skip);
if (rw == UIO_READ)
cnt = copy_to_iter(p, cnt, uio->uio_iter);
else
@ -507,12 +504,14 @@ static int
zfs_uio_pin_user_pages(zfs_uio_t *uio, zfs_uio_rw_t rw)
{
long res;
size_t skip = uio->uio_skip;
size_t skip = uio->uio_iter->iov_offset;
size_t len = uio->uio_resid - skip;
unsigned int gup_flags = 0;
unsigned long addr;
unsigned long nr_pages;
ASSERT3U(uio->uio_segflg, ==, UIO_ITER);
/*
* Kernel 6.2 introduced the FOLL_PCI_P2PDMA flag. This flag could
* possibly be used here in the future to allow for P2P operations with
@ -577,7 +576,7 @@ static int
zfs_uio_get_dio_pages_iov_iter(zfs_uio_t *uio, zfs_uio_rw_t rw)
{
size_t start;
size_t wanted = uio->uio_resid - uio->uio_skip;
size_t wanted = uio->uio_resid;
ssize_t rollback = 0;
ssize_t cnt;
unsigned maxpages = DIV_ROUND_UP(wanted, PAGE_SIZE);
@ -611,7 +610,7 @@ zfs_uio_get_dio_pages_iov_iter(zfs_uio_t *uio, zfs_uio_rw_t rw)
#endif
}
ASSERT3U(rollback, ==, uio->uio_resid - uio->uio_skip);
ASSERT3U(rollback, ==, uio->uio_resid);
iov_iter_revert(uio->uio_iter, rollback);
return (0);

View File

@ -226,7 +226,7 @@ zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to)
ssize_t count = iov_iter_count(to);
zfs_uio_t uio;
zfs_uio_iov_iter_init(&uio, to, kiocb->ki_pos, count, 0);
zfs_uio_iov_iter_init(&uio, to, kiocb->ki_pos, count);
crhold(cr);
cookie = spl_fstrans_mark();
@ -276,8 +276,7 @@ zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from)
if (ret)
return (ret);
zfs_uio_iov_iter_init(&uio, from, kiocb->ki_pos, count,
from->iov_offset);
zfs_uio_iov_iter_init(&uio, from, kiocb->ki_pos, count);
crhold(cr);
cookie = spl_fstrans_mark();