mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Implement allocation size ranges and use for gang leaves (#17111)
When forced to resort to ganging, ZFS currently allocates three child blocks, each one third of the size of the original. This is true regardless of whether larger allocations could be made, which would allow us to have fewer gang leaves. This improves performance when fragmentation is high enough to require ganging, but not so high that all the free ranges are only just big enough to hold a third of the recordsize. This is also useful for improving the behavior of a future change to allow larger gang headers. We add the ability for the allocation codepath to allocate a range of sizes instead of a single fixed size. We then use this to pre-allocate the DVAs for the gang children. If those allocations fail, we fall back to the normal write path, which will likely re-gang. Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com> Co-authored-by: Paul Dagnelie <paul.dagnelie@klarasystems.com> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Tony Hutter <hutter2@llnl.gov>
This commit is contained in:
@@ -726,7 +726,8 @@ tests = ['large_dnode_001_pos', 'large_dnode_003_pos', 'large_dnode_004_neg',
|
||||
tags = ['functional', 'features', 'large_dnode']
|
||||
|
||||
[tests/functional/gang_blocks]
|
||||
tests = ['gang_blocks_redundant', 'gang_blocks_ddt_copies']
|
||||
tests = ['gang_blocks_001_pos', 'gang_blocks_redundant',
|
||||
'gang_blocks_ddt_copies']
|
||||
tags = ['functional', 'gang_blocks']
|
||||
|
||||
[tests/functional/grow]
|
||||
|
||||
@@ -428,6 +428,10 @@ tests = ['large_dnode_003_pos', 'large_dnode_004_neg',
|
||||
'large_dnode_005_pos', 'large_dnode_007_neg']
|
||||
tags = ['functional', 'features', 'large_dnode']
|
||||
|
||||
[tests/functional/gang_blocks]
|
||||
tests = ['gang_blocks_001_pos']
|
||||
tags = ['functional', 'gang_blocks']
|
||||
|
||||
[tests/functional/grow]
|
||||
pre =
|
||||
post =
|
||||
|
||||
@@ -1562,6 +1562,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||
functional/features/large_dnode/large_dnode_009_pos.ksh \
|
||||
functional/features/large_dnode/setup.ksh \
|
||||
functional/gang_blocks/cleanup.ksh \
|
||||
functional/gang_blocks/gang_blocks_001_pos.ksh \
|
||||
functional/gang_blocks/gang_blocks_ddt_copies.ksh \
|
||||
functional/gang_blocks/gang_blocks_redundant.ksh \
|
||||
functional/gang_blocks/setup.ksh \
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/bin/ksh
|
||||
# SPDX-License-Identifier: CDDL-1.0
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# 1.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy of the CDDL is also available via the Internet at
|
||||
# http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2025 by Klara Inc.
|
||||
#
|
||||
|
||||
#
|
||||
# Description:
|
||||
# Verify that gang block functionality behaves correctly.
|
||||
#
|
||||
# Strategy:
|
||||
# 1. Create a pool without dynamic gang headers.
|
||||
# 2. Set metaslab_force_ganging to force gang blocks to be created.
|
||||
# 3. Verify that gang blocks can be read, written, and freed.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/gang_blocks/gang_blocks.kshlib
|
||||
|
||||
log_assert "Gang blocks behave correctly."
|
||||
|
||||
preamble
|
||||
log_onexit cleanup
|
||||
|
||||
log_must zpool create -f $TESTPOOL $DISKS
|
||||
log_must zfs create -o recordsize=128k $TESTPOOL/$TESTFS
|
||||
mountpoint=$(get_prop mountpoint $TESTPOOL/$TESTFS)
|
||||
set_tunable64 METASLAB_FORCE_GANGING 100000
|
||||
set_tunable32 METASLAB_FORCE_GANGING_PCT 100
|
||||
|
||||
path="${mountpoint}/file"
|
||||
log_must dd if=/dev/urandom of=$path bs=128k count=1
|
||||
log_must zpool sync $TESTPOOL
|
||||
first_block=$(get_first_block_dva $TESTPOOL/$TESTFS file)
|
||||
leaves=$(read_gang_header $TESTPOOL $first_block 200 | grep -v hole | wc -l)
|
||||
[[ "$leaves" -gt 1 ]] || log_fail "Only one leaf in gang block, should not be possible"
|
||||
|
||||
orig_checksum="$(cat $path | xxh128digest)"
|
||||
|
||||
log_must verify_pool $TESTPOOL
|
||||
log_must zinject -a
|
||||
new_checksum="$(cat $path | xxh128digest)"
|
||||
[[ "$orig_checksum" == "$new_checksum" ]] || log_fail "Checksum mismatch"
|
||||
|
||||
log_must rm $path
|
||||
log_must verify_pool $TESTPOOL
|
||||
|
||||
log_pass "Gang blocks behave correctly."
|
||||
Reference in New Issue
Block a user