Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/sys/abd.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@ __attribute__((malloc))
abd_t *abd_alloc(size_t, boolean_t);
__attribute__((malloc))
abd_t *abd_alloc_linear(size_t, boolean_t);
abd_t *abd_alloc_linear_struct(abd_t *, size_t, boolean_t);
__attribute__((malloc))
abd_t *abd_alloc_gang(void);
abd_t *abd_alloc_gang_struct(abd_t *);
__attribute__((malloc))
abd_t *abd_alloc_for_io(size_t, boolean_t);
__attribute__((malloc))
Expand All @@ -94,6 +96,7 @@ abd_t *abd_get_offset(abd_t *, size_t);
abd_t *abd_get_offset_size(abd_t *, size_t, size_t);
abd_t *abd_get_offset_struct(abd_t *, abd_t *, size_t, size_t);
abd_t *abd_get_zeros(size_t);
abd_t *abd_get_zeros_struct(abd_t *, size_t);
abd_t *abd_get_from_buf(void *, size_t);
abd_t *abd_get_from_buf_struct(abd_t *, void *, size_t);
void abd_cache_reap_now(void);
Expand Down
45 changes: 38 additions & 7 deletions module/zfs/abd.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,9 @@ abd_alloc(size_t size, boolean_t is_metadata)
* buffer. Only use this when it would be very annoying to write your ABD
* consumer with a scattered ABD.
*/
abd_t *
abd_alloc_linear(size_t size, boolean_t is_metadata)
static abd_t *
abd_alloc_linear_impl(abd_t *abd, size_t size, boolean_t is_metadata)
{
abd_t *abd = abd_alloc_struct(0);

VERIFY3U(size, <=, SPA_MAXBLOCKSIZE);

abd->abd_flags |= ABD_FLAG_LINEAR | ABD_FLAG_OWNER;
Expand All @@ -236,6 +234,19 @@ abd_alloc_linear(size_t size, boolean_t is_metadata)
return (abd);
}

abd_t *
abd_alloc_linear(size_t size, boolean_t is_metadata)
{
return (abd_alloc_linear_impl(abd_alloc_struct(0), size, is_metadata));
}

abd_t *
abd_alloc_linear_struct(abd_t *abd, size_t size, boolean_t is_metadata)
{
abd_init_struct(abd);
return (abd_alloc_linear_impl(abd, size, is_metadata));
}

static void
abd_free_linear(abd_t *abd)
{
Expand Down Expand Up @@ -349,16 +360,28 @@ abd_alloc_sametype(abd_t *sabd, size_t size)
* to "chain" scatter/gather lists together when constructing aggregated
* IO's. To free this abd, abd_free() must be called.
*/
abd_t *
abd_alloc_gang(void)
static abd_t *
abd_alloc_gang_impl(abd_t *abd)
{
abd_t *abd = abd_alloc_struct(0);
abd->abd_flags |= ABD_FLAG_GANG | ABD_FLAG_OWNER;
list_create(&ABD_GANG(abd).abd_gang_chain,
sizeof (abd_t), offsetof(abd_t, abd_gang_link));
return (abd);
}

abd_t *
abd_alloc_gang(void)
{
return (abd_alloc_gang_impl(abd_alloc_struct(0)));
}

abd_t *
abd_alloc_gang_struct(abd_t *abd)
{
abd_init_struct(abd);
return (abd_alloc_gang_impl(abd));
}

/*
* Add a child gang ABD to a parent gang ABDs chained list.
*/
Expand Down Expand Up @@ -624,6 +647,14 @@ abd_get_zeros(size_t size)
return (abd_get_offset_size(abd_zero_scatter, 0, size));
}

abd_t *
abd_get_zeros_struct(abd_t *abd, size_t size)
{
ASSERT3P(abd_zero_scatter, !=, NULL);
ASSERT3U(size, <=, SPA_MAXBLOCKSIZE);
return (abd_get_offset_struct(abd, abd_zero_scatter, 0, size));
}

/*
* Create a linear ABD for an existing buf.
*/
Expand Down
10 changes: 6 additions & 4 deletions module/zfs/vdev_draid.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,15 +798,16 @@ vdev_draid_map_alloc_write(zio_t *zio, uint64_t abd_offset, raidz_row_t *rr)
if (rc->rc_size == 0) {
/* empty data column (small write), add a skip sector */
ASSERT3U(skip_size, ==, parity_size);
rc->rc_abd = abd_get_zeros(skip_size);
rc->rc_abd = abd_get_zeros_struct(&rc->rc_abdstruct,
skip_size);
} else if (rc->rc_size == parity_size) {
/* this is a "big column" */
rc->rc_abd = abd_get_offset_struct(&rc->rc_abdstruct,
zio->io_abd, abd_off, rc->rc_size);
} else {
/* short data column, add a skip sector */
ASSERT3U(rc->rc_size + skip_size, ==, parity_size);
rc->rc_abd = abd_alloc_gang();
rc->rc_abd = abd_alloc_gang_struct(&rc->rc_abdstruct);
abd_gang_add(rc->rc_abd, abd_get_offset_size(
zio->io_abd, abd_off, rc->rc_size), B_TRUE);
abd_gang_add(rc->rc_abd, abd_get_zeros(skip_size),
Expand Down Expand Up @@ -863,7 +864,7 @@ vdev_draid_map_alloc_scrub(zio_t *zio, uint64_t abd_offset, raidz_row_t *rr)
/* short data column, add a skip sector */
ASSERT3U(rc->rc_size + skip_size, ==, parity_size);
ASSERT3U(rr->rr_nempty, !=, 0);
rc->rc_abd = abd_alloc_gang();
rc->rc_abd = abd_alloc_gang_struct(&rc->rc_abdstruct);
abd_gang_add(rc->rc_abd, abd_get_offset_size(
zio->io_abd, abd_off, rc->rc_size), B_TRUE);
abd_gang_add(rc->rc_abd, abd_get_offset_size(
Expand Down Expand Up @@ -1240,7 +1241,8 @@ vdev_draid_map_alloc_row(zio_t *zio, raidz_row_t **rrp, uint64_t io_offset,
/* Allocate buffers for the parity columns */
for (uint64_t c = 0; c < rr->rr_firstdatacol; c++) {
raidz_col_t *rc = &rr->rr_col[c];
rc->rc_abd = abd_alloc_linear(rc->rc_size, B_FALSE);
rc->rc_abd = abd_alloc_linear_struct(&rc->rc_abdstruct,
rc->rc_size, B_FALSE);
}

/*
Expand Down
21 changes: 12 additions & 9 deletions module/zfs/vdev_raidz.c
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,13 @@ vdev_raidz_map_alloc_write(zio_t *zio, raidz_map_t *rm, uint64_t ashift)
* VDEV queue locks (vq_lock).
*/
if (c < nwrapped) {
rc->rc_abd = abd_alloc_linear(
rc->rc_abd = abd_alloc_linear_struct(&rc->rc_abdstruct,
rc->rc_size + (1ULL << ashift), B_FALSE);
abd_zero_off(rc->rc_abd, rc->rc_size, 1ULL << ashift);
skipped++;
} else {
rc->rc_abd = abd_alloc_linear(rc->rc_size, B_FALSE);
rc->rc_abd = abd_alloc_linear_struct(&rc->rc_abdstruct,
rc->rc_size, B_FALSE);
}
}

Expand Down Expand Up @@ -624,9 +625,11 @@ vdev_raidz_map_alloc_read(zio_t *zio, raidz_map_t *rm)
ASSERT3U(rm->rm_nrows, ==, 1);

/* Allocate buffers for the parity columns */
for (c = 0; c < rr->rr_firstdatacol; c++)
rr->rr_col[c].rc_abd =
abd_alloc_linear(rr->rr_col[c].rc_size, B_FALSE);
for (c = 0; c < rr->rr_firstdatacol; c++) {
raidz_col_t *rc = &rr->rr_col[c];
rc->rc_abd = abd_alloc_linear_struct(&rc->rc_abdstruct,
rc->rc_size, B_FALSE);
}

for (uint64_t off = 0; c < rr->rr_cols; c++) {
raidz_col_t *rc = &rr->rr_col[c];
Expand Down Expand Up @@ -1071,8 +1074,8 @@ vdev_raidz_map_alloc_expanded(zio_t *zio,
continue;

prc->rc_abd =
abd_alloc_linear(rm->rm_phys_col[i].rc_size,
B_FALSE);
abd_alloc_linear_struct(&prc->rc_abdstruct,
prc->rc_size, B_FALSE);
}

/*
Expand Down Expand Up @@ -1100,8 +1103,8 @@ vdev_raidz_map_alloc_expanded(zio_t *zio,
for (int c = 0; c < rr->rr_firstdatacol; c++) {
raidz_col_t *rc = &rr->rr_col[c];
rc->rc_abd =
abd_alloc_linear(rc->rc_size,
B_TRUE);
abd_alloc_linear_struct(&rc->rc_abdstruct,
rc->rc_size, B_TRUE);
}
}
}
Expand Down
Loading