mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-24 19:28:53 +03:00
abd: add page iterator
The regular ABD iterators yield data buffers, so they have to map and unmap pages into kernel memory. If the caller only wants to count chunks, or can use page pointers directly, then the map/unmap is just unnecessary overhead. This adds adb_iterate_page_func, which yields unmapped struct page instead. Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Closes #15533 Closes #15588
This commit is contained in:
committed by
Brian Behlendorf
parent
df04efe321
commit
390b448726
@@ -826,6 +826,48 @@ abd_iterate_func(abd_t *abd, size_t off, size_t size,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#if defined(__linux__) && defined(_KERNEL)
|
||||
int
|
||||
abd_iterate_page_func(abd_t *abd, size_t off, size_t size,
|
||||
abd_iter_page_func_t *func, void *private)
|
||||
{
|
||||
struct abd_iter aiter;
|
||||
int ret = 0;
|
||||
|
||||
if (size == 0)
|
||||
return (0);
|
||||
|
||||
abd_verify(abd);
|
||||
ASSERT3U(off + size, <=, abd->abd_size);
|
||||
|
||||
abd_t *c_abd = abd_init_abd_iter(abd, &aiter, off);
|
||||
|
||||
while (size > 0) {
|
||||
IMPLY(abd_is_gang(abd), c_abd != NULL);
|
||||
|
||||
abd_iter_page(&aiter);
|
||||
|
||||
size_t len = MIN(aiter.iter_page_dsize, size);
|
||||
ASSERT3U(len, >, 0);
|
||||
|
||||
ret = func(aiter.iter_page, aiter.iter_page_doff,
|
||||
len, private);
|
||||
|
||||
aiter.iter_page = NULL;
|
||||
aiter.iter_page_doff = 0;
|
||||
aiter.iter_page_dsize = 0;
|
||||
|
||||
if (ret != 0)
|
||||
break;
|
||||
|
||||
size -= len;
|
||||
c_abd = abd_advance_abd_iter(abd, c_abd, &aiter, len);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct buf_arg {
|
||||
void *arg_buf;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user