diff options
| author | Martin Matuska <mm@FreeBSD.org> | 2026-06-27 06:15:42 +0000 |
|---|---|---|
| committer | Martin Matuska <mm@FreeBSD.org> | 2026-06-27 08:51:33 +0000 |
| commit | d0b3ecdc274930e190ea233b6b69ff03782eaf8d (patch) | |
| tree | 8f7bc49621e339a1a9baa14a3221e2d90c7a0c5d /sys/contrib/openzfs/module/zfs/vdev_raidz.c | |
| parent | 8e61d8707f8a10acc143210089fea2502a3f2922 (diff) | |
| parent | 37af899488652c55c456d3f160fb8b295db2ec70 (diff) | |
zfs: merge openzfs/zfs@37af89948
Notable upstream pull request merges:
#18509 f16b3744d zstream: refactor common functions
#18573 -multiple Persist z_seq across znode eviction
s18611 eb0c674c2 zfs_ioctl: fix EBUSY race between quota queries and mount
#18637 77e64d86e Fix self-deadlock when setting the "allocating"/"path"
vdev property
#18645 e3082b923 freebsd: set mnt_time on the rootfs at mountroot time
#18652 50d012b2a zbookmark_compare: handle "marker" bookmarks with negative
levels
#18664 520eeeaa6 Improve performance of "zpool offline" for log devices
#18668 6b8f79877 Avoid more abd_t allocations in RAIDZ/dRAID
#18669 99ab859c3 Optimize metaslab_set_selected_txg()
#18673 97b9ba7a9 delegate: add 'send:encrypted' permission
#18687 2ea519c2a Avoid lookup overhead for nonexistent xattr directories
#18688 87593ea2b Fix handling of _PC_HAS_HIDDENSYSTEM for FreeBSD
#18693 0483a8e0c Clean up embedded slog metaslab across txgs
#18695 41311c665 RAIDZ: Optimize single data column writes
#18706 37af89948 ddt_log: Fix refcount tagging for begin/commit
Obtained from: OpenZFS
OpenZFS commit: 37af899488652c55c456d3f160fb8b295db2ec70
Diffstat (limited to 'sys/contrib/openzfs/module/zfs/vdev_raidz.c')
| -rw-r--r-- | sys/contrib/openzfs/module/zfs/vdev_raidz.c | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/sys/contrib/openzfs/module/zfs/vdev_raidz.c b/sys/contrib/openzfs/module/zfs/vdev_raidz.c index 2db7422e772e..ab9f62c3c2d0 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_raidz.c +++ b/sys/contrib/openzfs/module/zfs/vdev_raidz.c @@ -419,7 +419,16 @@ static int zfs_scrub_partial_writes = 1; static void vdev_raidz_row_free(raidz_row_t *rr) { - for (int c = 0; c < rr->rr_cols; c++) { + abd_t *dabd = rr->rr_col[rr->rr_firstdatacol].rc_abd; + for (int c = 0; c < rr->rr_firstdatacol; c++) { + raidz_col_t *rc = &rr->rr_col[c]; + + if (rc->rc_size != 0 && rc->rc_abd != dabd) + abd_free(rc->rc_abd); + if (rc->rc_orig_data != NULL) + abd_free(rc->rc_orig_data); + } + for (int c = rr->rr_firstdatacol; c < rr->rr_cols; c++) { raidz_col_t *rc = &rr->rr_col[c]; if (rc->rc_size != 0) @@ -532,6 +541,22 @@ vdev_raidz_map_alloc_write(zio_t *zio, raidz_map_t *rm, uint64_t ashift) */ int skipped = rr->rr_scols - rr->rr_cols; + /* + * When there is only a single data column the parity is a copy of + * it, so point all parity columns at the data ABD directly to avoid + * allocating buffers and computing parity. + */ + if (rr->rr_cols == rr->rr_firstdatacol + 1) { + ASSERT0(nwrapped); + ASSERT0(rm->rm_nskip); + raidz_col_t *dc = &rr->rr_col[rr->rr_firstdatacol]; + dc->rc_abd = abd_get_offset_struct(&dc->rc_abdstruct, + zio->io_abd, 0, dc->rc_size); + for (c = 0; c < rr->rr_firstdatacol; c++) + rr->rr_col[c].rc_abd = dc->rc_abd; + return; + } + /* Allocate buffers for the parity columns */ for (c = 0; c < rr->rr_firstdatacol; c++) { raidz_col_t *rc = &rr->rr_col[c]; @@ -546,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); } } @@ -599,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]; @@ -1046,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); } /* @@ -1075,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); } } } @@ -1272,6 +1300,13 @@ vdev_raidz_generate_parity_row(raidz_map_t *rm, raidz_row_t *rr) return; } + /* + * Single data column: parity is the data itself. + */ + if (rr->rr_col[VDEV_RAIDZ_P].rc_abd == + rr->rr_col[rr->rr_firstdatacol].rc_abd) + return; + /* Generate using the new math implementation */ if (vdev_raidz_math_generate(rm, rr) != RAIDZ_ORIGINAL_IMPL) return; |
