Skip to content

Commit

Permalink
abd: abd_for_each_chunk macro for the simple case
Browse files Browse the repository at this point in the history
This is where I really wanted to get to. Rather then needing the loop
boilerplate every time, have a macro that hide all that away, having a
use that looks more like a plain old for loop.

This method has two downsides:
- the data and size vars have to be declared outside the loop
- an early exit (break or return) is not possible, as there's no place
  to unmap the chunk.
  • Loading branch information
robn committed Dec 9, 2024
1 parent f5bb75a commit b897f25
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 18 deletions.
22 changes: 22 additions & 0 deletions include/sys/abd_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,28 @@ abd_chunk_unmap(abd_chunk_t *ch) {
abd_iter_unmap(&ch->ch_iter);
}

/*
* Macro to iterate over an ABD in the most common case, where you want to
* do some operation on the actual data.
*
* void *data;
* size_t dsize;
* abd_for_each_chunk(abd, off, size, data, dsize) {
* // do work on data an dsize
* }
*
* XXX Can't be used if we need to break out of the loop early, because it
* would leave the chunk mapped. Also sucks that we have declare data and
* dsize every time, and outside the scope -- robn, 2024-11-21
*/
#define abd_for_each_chunk(abd, off, size, __data, __dsize) \
for (abd_chunk_t __ai = abd_chunk_start(abd, off, size); \
!abd_chunk_done(&__ai) && \
(__data = abd_chunk_map(&__ai)) && \
(__dsize = abd_chunk_size(&__ai)); \
abd_chunk_unmap(&__ai), abd_chunk_advance(&__ai))


#ifdef __cplusplus
}
#endif
Expand Down
35 changes: 17 additions & 18 deletions module/zfs/abd.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,12 +831,12 @@ void
abd_copy_to_buf_off(void *buf, abd_t *abd, size_t off, size_t size)
{
char *c = buf;
for (abd_chunk_t ch = abd_chunk_start(abd, off, size);
!abd_chunk_done(&ch); abd_chunk_advance(&ch)) {
void *addr = abd_chunk_map(&ch);
memcpy(c, addr, abd_chunk_size(&ch));
c += abd_chunk_size(&ch);
abd_chunk_unmap(&ch);
void *data;
size_t dsize;

abd_for_each_chunk(abd, off, size, data, dsize) {
memcpy(c, data, dsize);
c += dsize;
}
}

Expand Down Expand Up @@ -870,12 +870,12 @@ void
abd_copy_from_buf_off(abd_t *abd, const void *buf, size_t off, size_t size)
{
const char *c = buf;
for (abd_chunk_t ch = abd_chunk_start(abd, off, size);
!abd_chunk_done(&ch); abd_chunk_advance(&ch)) {
void *addr = abd_chunk_map(&ch);
memcpy(addr, c, abd_chunk_size(&ch));
c += abd_chunk_size(&ch);
abd_chunk_unmap(&ch);
void *data;
size_t dsize;

abd_for_each_chunk(abd, off, size, data, dsize) {
memcpy(data, c, dsize);
c += dsize;
}
}

Expand All @@ -885,12 +885,11 @@ abd_copy_from_buf_off(abd_t *abd, const void *buf, size_t off, size_t size)
void
abd_zero_off(abd_t *abd, size_t off, size_t size)
{
for (abd_chunk_t ch = abd_chunk_start(abd, off, size);
!abd_chunk_done(&ch); abd_chunk_advance(&ch)) {
void *addr = abd_chunk_map(&ch);
memset(addr, 0, abd_chunk_size(&ch));
abd_chunk_unmap(&ch);
}
void *data;
size_t dsize;

abd_for_each_chunk(abd, off, size, data, dsize)
memset(data, 0, dsize);
}

/*
Expand Down

0 comments on commit b897f25

Please sign in to comment.