HomeFreeBSD

vdev_raidz_asize_to_psize: return psize, not asize

Description

vdev_raidz_asize_to_psize: return psize, not asize

Since 246e588, gang blocks written to raidz vdevs will write past the
end of their allocation, corrupting themselves, other data, or both.

The reason is simple - when allocating the gang children, we call
vdev_psize_to_asize() to find out how much data we should load into the
allocation we just did. vdev_raidz_asize_to_psize() had a bug; it
computed the psize, but returned the original asize. The raidz layer
dutifully writes that much out, into space beyond the end of the
allocation.

If there's existing data there, it gets overwritten, causing checksum
errors when that data is read. Even there's not data there (unlikely,
given that gang blocks are in play at all), that area is not considered
allocated, so can be allocated and overwritten later.

The fix is simple: return the psize we just computed.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17488

Details

Provenance
rob.norris_klarasystems.comAuthored on Jun 26 2025, 2:19 PM
GitHub <noreply@github.com>Committed on Jun 26 2025, 2:19 PM
Parents
rG0a2163d194e3: FreeBSD: Ensure that z_pflags is initialized for new znodes
Branches
Unknown
Tags
Unknown