Skip to content

Commit a41c7f3

Browse files
robntonyhutter
authored andcommitted
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 <[email protected]>
1 parent b7651b6 commit a41c7f3

File tree

3 files changed

+12
-17
lines changed

3 files changed

+12
-17
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: 8 additions & 12 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,13 @@ 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;
511-
size_t len = uio->uio_resid - skip;
507+
size_t len = uio->uio_resid;
512508
unsigned int gup_flags = 0;
513509
unsigned long addr;
514510
unsigned long nr_pages;
515511

512+
ASSERT3U(uio->uio_segflg, ==, UIO_ITER);
513+
516514
/*
517515
* Kernel 6.2 introduced the FOLL_PCI_P2PDMA flag. This flag could
518516
* possibly be used here in the future to allow for P2P operations with
@@ -528,7 +526,7 @@ zfs_uio_pin_user_pages(zfs_uio_t *uio, zfs_uio_rw_t rw)
528526
#if defined(HAVE_ITER_IS_UBUF)
529527
if (iter_is_ubuf(uio->uio_iter)) {
530528
nr_pages = DIV_ROUND_UP(len, PAGE_SIZE);
531-
addr = (unsigned long)uio->uio_iter->ubuf + skip;
529+
addr = (unsigned long)uio->uio_iter->ubuf;
532530
res = pin_user_pages_unlocked(addr, nr_pages,
533531
&uio->uio_dio.pages[uio->uio_dio.npages], gup_flags);
534532
if (res < 0) {
@@ -543,14 +541,13 @@ zfs_uio_pin_user_pages(zfs_uio_t *uio, zfs_uio_rw_t rw)
543541
#endif
544542
const struct iovec *iovp = zfs_uio_iter_iov(uio->uio_iter);
545543
for (int i = 0; i < uio->uio_iovcnt; i++) {
546-
size_t amt = iovp->iov_len - skip;
544+
size_t amt = iovp->iov_len;
547545
if (amt == 0) {
548546
iovp++;
549-
skip = 0;
550547
continue;
551548
}
552549

553-
addr = (unsigned long)iovp->iov_base + skip;
550+
addr = (unsigned long)iovp->iov_base;
554551
nr_pages = DIV_ROUND_UP(amt, PAGE_SIZE);
555552
res = pin_user_pages_unlocked(addr, nr_pages,
556553
&uio->uio_dio.pages[uio->uio_dio.npages], gup_flags);
@@ -563,7 +560,6 @@ zfs_uio_pin_user_pages(zfs_uio_t *uio, zfs_uio_rw_t rw)
563560

564561
len -= amt;
565562
uio->uio_dio.npages += res;
566-
skip = 0;
567563
iovp++;
568564
};
569565

@@ -577,7 +573,7 @@ static int
577573
zfs_uio_get_dio_pages_iov_iter(zfs_uio_t *uio, zfs_uio_rw_t rw)
578574
{
579575
size_t start;
580-
size_t wanted = uio->uio_resid - uio->uio_skip;
576+
size_t wanted = uio->uio_resid;
581577
ssize_t rollback = 0;
582578
ssize_t cnt;
583579
unsigned maxpages = DIV_ROUND_UP(wanted, PAGE_SIZE);
@@ -611,7 +607,7 @@ zfs_uio_get_dio_pages_iov_iter(zfs_uio_t *uio, zfs_uio_rw_t rw)
611607
#endif
612608

613609
}
614-
ASSERT3U(rollback, ==, uio->uio_resid - uio->uio_skip);
610+
ASSERT3U(rollback, ==, uio->uio_resid);
615611
iov_iter_revert(uio->uio_iter, rollback);
616612

617613
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)