diff --git a/module/os/linux/zfs/abd_os.c b/module/os/linux/zfs/abd_os.c index 18f2426fb..37d9007a6 100644 --- a/module/os/linux/zfs/abd_os.c +++ b/module/os/linux/zfs/abd_os.c @@ -915,7 +915,14 @@ abd_iter_map(struct abd_iter *aiter) aiter->iter_mapsize = MIN(aiter->iter_sg->length - offset, aiter->iter_abd->abd_size - aiter->iter_pos); - paddr = zfs_kmap_local(sg_page(aiter->iter_sg)); + struct page *page = sg_page(aiter->iter_sg); + if (PageHighMem(page)) { + page = nth_page(page, offset / PAGE_SIZE); + offset &= PAGE_SIZE - 1; + aiter->iter_mapsize = MIN(aiter->iter_mapsize, + PAGE_SIZE - offset); + } + paddr = zfs_kmap_local(page); } aiter->iter_mapaddr = (char *)paddr + offset; @@ -933,8 +940,14 @@ abd_iter_unmap(struct abd_iter *aiter) return; if (!abd_is_linear(aiter->iter_abd)) { + size_t offset = aiter->iter_offset; + + struct page *page = sg_page(aiter->iter_sg); + if (PageHighMem(page)) + offset &= PAGE_SIZE - 1; + /* LINTED E_FUNC_SET_NOT_USED */ - zfs_kunmap_local(aiter->iter_mapaddr - aiter->iter_offset); + zfs_kunmap_local(aiter->iter_mapaddr - offset); } ASSERT3P(aiter->iter_mapaddr, !=, NULL);