mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-01-14 17:22:05 +03:00
Fix dynamic gang block headers on raidz and mirror devices
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com> Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com> Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Closes #17587
This commit is contained in:
parent
8ecf044d62
commit
31c4fa93bb
@ -139,6 +139,7 @@ extern uint64_t vdev_asize_to_psize_txg(vdev_t *vd, uint64_t asize,
|
||||
extern uint64_t vdev_psize_to_asize_txg(vdev_t *vd, uint64_t psize,
|
||||
uint64_t txg);
|
||||
extern uint64_t vdev_psize_to_asize(vdev_t *vd, uint64_t psize);
|
||||
extern uint64_t vdev_get_min_alloc(vdev_t *vd);
|
||||
|
||||
/*
|
||||
* Return the amount of space allocated for a gang block header. Note that
|
||||
@ -151,6 +152,19 @@ vdev_gang_header_asize(vdev_t *vd)
|
||||
return (vdev_psize_to_asize_txg(vd, SPA_OLD_GANGBLOCKSIZE, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the amount of data that can be stored in a gang header. Because we
|
||||
* need to ensure gang headers can always be allocated (as long as there is
|
||||
* space available), this is the minimum allocatable size on the vdev. Note that
|
||||
* since the physical birth txg is not provided, this must be constant for
|
||||
* a given vdev. (e.g. raidz expansion can't change this)
|
||||
*/
|
||||
static inline uint64_t
|
||||
vdev_gang_header_psize(vdev_t *vd)
|
||||
{
|
||||
return (vdev_get_min_alloc(vd));
|
||||
}
|
||||
|
||||
extern int vdev_fault(spa_t *spa, uint64_t guid, vdev_aux_t aux);
|
||||
extern int vdev_degrade(spa_t *spa, uint64_t guid, vdev_aux_t aux);
|
||||
extern int vdev_online(spa_t *spa, uint64_t guid, uint64_t flags,
|
||||
|
||||
@ -621,7 +621,6 @@ extern uint64_t vdev_default_asize(vdev_t *vd, uint64_t psize, uint64_t txg);
|
||||
extern uint64_t vdev_default_min_asize(vdev_t *vd);
|
||||
extern uint64_t vdev_get_min_asize(vdev_t *vd);
|
||||
extern void vdev_set_min_asize(vdev_t *vd);
|
||||
extern uint64_t vdev_get_min_alloc(vdev_t *vd);
|
||||
extern uint64_t vdev_get_nparity(vdev_t *vd);
|
||||
extern uint64_t vdev_get_ndisks(vdev_t *vd);
|
||||
|
||||
|
||||
@ -2956,8 +2956,8 @@ zio_gang_tree_assemble(zio_t *gio, blkptr_t *bp, zio_gang_node_t **gnpp)
|
||||
for (int dva = 0; dva < BP_GET_NDVAS(bp); dva++) {
|
||||
vdev_t *vd = vdev_lookup_top(gio->io_spa,
|
||||
DVA_GET_VDEV(&bp->blk_dva[dva]));
|
||||
uint64_t asize = vdev_gang_header_asize(vd);
|
||||
gangblocksize = MIN(gangblocksize, asize);
|
||||
uint64_t psize = vdev_gang_header_psize(vd);
|
||||
gangblocksize = MIN(gangblocksize, psize);
|
||||
}
|
||||
spa_config_exit(gio->io_spa, SCL_VDEV, FTAG);
|
||||
} else {
|
||||
|
||||
@ -569,7 +569,11 @@ zio_checksum_error(zio_t *zio, zio_bad_cksum_t *info)
|
||||
SPA_OLD_GANGBLOCKSIZE, offset, info);
|
||||
if (error == 0) {
|
||||
ASSERT3U(zio->io_child_type, ==, ZIO_CHILD_VDEV);
|
||||
zio_t *pio = zio_unique_parent(zio);
|
||||
zio_t *pio;
|
||||
for (pio = zio_unique_parent(zio);
|
||||
pio->io_child_type != ZIO_CHILD_GANG;
|
||||
pio = zio_unique_parent(pio))
|
||||
;
|
||||
zio_gang_node_t *gn = pio->io_private;
|
||||
gn->gn_gangblocksize = SPA_OLD_GANGBLOCKSIZE;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user