Skip to content

Commit a9016ed

Browse files
committed
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/ Signed-off-by: Rob Norris <robn@despairlabs.com>
1 parent 1a8f5ad commit a9016ed

File tree

3 files changed

+13
-16
lines changed

3 files changed

+13
-16
lines changed

include/os/linux/spl/sys/uio.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ zfs_uio_bvec_init(zfs_uio_t *uio, struct bio *bio, struct request *rq)
174174

175175
static inline void
176176
zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
177-
ssize_t resid, size_t skip)
177+
ssize_t resid)
178178
{
179179
uio->uio_iter = iter;
180180
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,
184184
uio->uio_fmode = 0;
185185
uio->uio_extflg = 0;
186186
uio->uio_resid = resid;
187-
uio->uio_skip = skip;
187+
uio->uio_skip = 0;
188188
uio->uio_soffset = uio->uio_loffset;
189189
memset(&uio->uio_dio, 0, sizeof (zfs_uio_dio_t));
190190
}

module/os/linux/zfs/zfs_uio.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,6 @@ zfs_uiomove_iter(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio,
233233
{
234234
size_t cnt = MIN(n, uio->uio_resid);
235235

236-
if (uio->uio_skip)
237-
iov_iter_advance(uio->uio_iter, uio->uio_skip);
238-
239236
if (rw == UIO_READ)
240237
cnt = copy_to_iter(p, cnt, uio->uio_iter);
241238
else
@@ -507,12 +504,14 @@ static int
507504
zfs_uio_pin_user_pages(zfs_uio_t *uio, zfs_uio_rw_t rw)
508505
{
509506
long res;
510-
size_t skip = uio->uio_skip;
507+
size_t skip = uio->uio_iter->iov_offset;
511508
size_t len = uio->uio_resid - skip;
512509
unsigned int gup_flags = 0;
513510
unsigned long addr;
514511
unsigned long nr_pages;
515512

513+
ASSERT3U(uio->uio_segflg, ==, UIO_ITER);
514+
516515
/*
517516
* Kernel 6.2 introduced the FOLL_PCI_P2PDMA flag. This flag could
518517
* possibly be used here in the future to allow for P2P operations with
@@ -528,7 +527,7 @@ zfs_uio_pin_user_pages(zfs_uio_t *uio, zfs_uio_rw_t rw)
528527
#if defined(HAVE_ITER_IS_UBUF)
529528
if (iter_is_ubuf(uio->uio_iter)) {
530529
nr_pages = DIV_ROUND_UP(len, PAGE_SIZE);
531-
addr = (unsigned long)uio->uio_iter->ubuf + skip;
530+
addr = (unsigned long)uio->uio_iter->ubuf;
532531
res = pin_user_pages_unlocked(addr, nr_pages,
533532
&uio->uio_dio.pages[uio->uio_dio.npages], gup_flags);
534533
if (res < 0) {
@@ -543,14 +542,13 @@ zfs_uio_pin_user_pages(zfs_uio_t *uio, zfs_uio_rw_t rw)
543542
#endif
544543
const struct iovec *iovp = zfs_uio_iter_iov(uio->uio_iter);
545544
for (int i = 0; i < uio->uio_iovcnt; i++) {
546-
size_t amt = iovp->iov_len - skip;
545+
size_t amt = iovp->iov_len;
547546
if (amt == 0) {
548547
iovp++;
549-
skip = 0;
550548
continue;
551549
}
552550

553-
addr = (unsigned long)iovp->iov_base + skip;
551+
addr = (unsigned long)iovp->iov_base;
554552
nr_pages = DIV_ROUND_UP(amt, PAGE_SIZE);
555553
res = pin_user_pages_unlocked(addr, nr_pages,
556554
&uio->uio_dio.pages[uio->uio_dio.npages], gup_flags);
@@ -563,7 +561,6 @@ zfs_uio_pin_user_pages(zfs_uio_t *uio, zfs_uio_rw_t rw)
563561

564562
len -= amt;
565563
uio->uio_dio.npages += res;
566-
skip = 0;
567564
iovp++;
568565
};
569566

@@ -577,7 +574,8 @@ static int
577574
zfs_uio_get_dio_pages_iov_iter(zfs_uio_t *uio, zfs_uio_rw_t rw)
578575
{
579576
size_t start;
580-
size_t wanted = uio->uio_resid - uio->uio_skip;
577+
size_t skip = uio->uio_iter->iov_offset;
578+
size_t wanted = uio->uio_resid - skip;
581579
ssize_t rollback = 0;
582580
ssize_t cnt;
583581
unsigned maxpages = DIV_ROUND_UP(wanted, PAGE_SIZE);
@@ -611,7 +609,7 @@ zfs_uio_get_dio_pages_iov_iter(zfs_uio_t *uio, zfs_uio_rw_t rw)
611609
#endif
612610

613611
}
614-
ASSERT3U(rollback, ==, uio->uio_resid - uio->uio_skip);
612+
ASSERT3U(rollback, ==, uio->uio_resid - skip);
615613
iov_iter_revert(uio->uio_iter, rollback);
616614

617615
return (0);

module/os/linux/zfs/zpl_file.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to)
226226
ssize_t count = iov_iter_count(to);
227227
zfs_uio_t uio;
228228

229-
zfs_uio_iov_iter_init(&uio, to, kiocb->ki_pos, count, 0);
229+
zfs_uio_iov_iter_init(&uio, to, kiocb->ki_pos, count);
230230

231231
crhold(cr);
232232
cookie = spl_fstrans_mark();
@@ -276,8 +276,7 @@ zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from)
276276
if (ret)
277277
return (ret);
278278

279-
zfs_uio_iov_iter_init(&uio, from, kiocb->ki_pos, count,
280-
from->iov_offset);
279+
zfs_uio_iov_iter_init(&uio, from, kiocb->ki_pos, count);
281280

282281
crhold(cr);
283282
cookie = spl_fstrans_mark();

0 commit comments

Comments
 (0)