From 2b56a634579e4cdab8d84ccba138e701a6d3bc64 Mon Sep 17 00:00:00 2001 From: Matthew Ahrens Date: Fri, 26 Mar 2021 11:19:35 -0700 Subject: [PATCH] Use a helper function to clarify gang block size For gang blocks, `DVA_GET_ASIZE()` is the total space allocated for the gang DVA including its children BP's. The space allocated at each DVA's vdev/offset is `vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE)`. This commit makes this relationship more clear by using a helper function, `vdev_gang_header_asize()`, for the space allocated at the gang block's vdev/offset. Reviewed-by: Brian Behlendorf Signed-off-by: Matthew Ahrens Closes #11744 --- include/sys/spa.h | 6 ++++++ include/sys/vdev.h | 9 +++++++++ module/zfs/metaslab.c | 8 ++++---- module/zfs/zio.c | 18 +++++++++++------- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/include/sys/spa.h b/include/sys/spa.h index 8391be8328..c960478efe 100644 --- a/include/sys/spa.h +++ b/include/sys/spa.h @@ -405,6 +405,12 @@ typedef struct blkptr { /* * Macros to get and set fields in a bp or DVA. */ + +/* + * Note, for gang blocks, DVA_GET_ASIZE() is the total space allocated for + * this gang DVA including its children BP's. The space allocated at this + * DVA's vdev/offset is vdev_gang_header_asize(vdev). + */ #define DVA_GET_ASIZE(dva) \ BF64_GET_SB((dva)->dva_word[0], 0, SPA_ASIZEBITS, SPA_MINBLOCKSHIFT, 0) #define DVA_SET_ASIZE(dva, x) \ diff --git a/include/sys/vdev.h b/include/sys/vdev.h index d1ef6b5b59..f235bfc8cc 100644 --- a/include/sys/vdev.h +++ b/include/sys/vdev.h @@ -133,6 +133,15 @@ extern int64_t vdev_deflated_space(vdev_t *vd, int64_t space); extern uint64_t vdev_psize_to_asize(vdev_t *vd, uint64_t psize); +/* + * Return the amount of space allocated for a gang block header. + */ +static inline uint64_t +vdev_gang_header_asize(vdev_t *vd) +{ + return (vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE)); +} + 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, diff --git a/module/zfs/metaslab.c b/module/zfs/metaslab.c index 463806c607..3b2b79b2f4 100644 --- a/module/zfs/metaslab.c +++ b/module/zfs/metaslab.c @@ -5544,7 +5544,7 @@ metaslab_unalloc_dva(spa_t *spa, const dva_t *dva, uint64_t txg) ASSERT3P(vd->vdev_indirect_mapping, ==, NULL); if (DVA_GET_GANG(dva)) - size = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE); + size = vdev_gang_header_asize(vd); msp = vd->vdev_ms[offset >> vd->vdev_ms_shift]; @@ -5579,7 +5579,7 @@ metaslab_free_dva(spa_t *spa, const dva_t *dva, boolean_t checkpoint) ASSERT3U(spa_config_held(spa, SCL_ALL, RW_READER), !=, 0); if (DVA_GET_GANG(dva)) { - size = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE); + size = vdev_gang_header_asize(vd); } metaslab_free_impl(vd, offset, size, checkpoint); @@ -5768,7 +5768,7 @@ metaslab_claim_dva(spa_t *spa, const dva_t *dva, uint64_t txg) ASSERT(DVA_IS_VALID(dva)); if (DVA_GET_GANG(dva)) - size = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE); + size = vdev_gang_header_asize(vd); return (metaslab_claim_impl(vd, offset, size, txg)); } @@ -6034,7 +6034,7 @@ metaslab_check_free(spa_t *spa, const blkptr_t *bp) uint64_t size = DVA_GET_ASIZE(&bp->blk_dva[i]); if (DVA_GET_GANG(&bp->blk_dva[i])) - size = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE); + size = vdev_gang_header_asize(vd); ASSERT3P(vd, !=, NULL); diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 23d45ded62..d97c8ddc95 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -995,7 +995,8 @@ zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp, boolean_t config_held, * that are in the log) to be arbitrarily large. */ for (int i = 0; i < BP_GET_NDVAS(bp); i++) { - uint64_t vdevid = DVA_GET_VDEV(&bp->blk_dva[i]); + const dva_t *dva = &bp->blk_dva[i]; + uint64_t vdevid = DVA_GET_VDEV(dva); if (vdevid >= spa->spa_root_vdev->vdev_children) { errors += zfs_blkptr_verify_log(spa, bp, blk_verify, @@ -1024,10 +1025,10 @@ zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp, boolean_t config_held, */ continue; } - uint64_t offset = DVA_GET_OFFSET(&bp->blk_dva[i]); - uint64_t asize = DVA_GET_ASIZE(&bp->blk_dva[i]); - if (BP_IS_GANG(bp)) - asize = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE); + uint64_t offset = DVA_GET_OFFSET(dva); + uint64_t asize = DVA_GET_ASIZE(dva); + if (DVA_GET_GANG(dva)) + asize = vdev_gang_header_asize(vd); if (offset + asize > vd->vdev_asize) { errors += zfs_blkptr_verify_log(spa, bp, blk_verify, "blkptr at %p DVA %u has invalid OFFSET %llu", @@ -1064,8 +1065,8 @@ zfs_dva_valid(spa_t *spa, const dva_t *dva, const blkptr_t *bp) uint64_t offset = DVA_GET_OFFSET(dva); uint64_t asize = DVA_GET_ASIZE(dva); - if (BP_IS_GANG(bp)) - asize = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE); + if (DVA_GET_GANG(dva)) + asize = vdev_gang_header_asize(vd); if (offset + asize > vd->vdev_asize) return (B_FALSE); @@ -3984,6 +3985,9 @@ zio_vdev_io_assess(zio_t *zio) */ if (zio->io_error == ENXIO && zio->io_type == ZIO_TYPE_WRITE && vd != NULL && !vd->vdev_ops->vdev_op_leaf) { + vdev_dbgmsg(vd, "zio_vdev_io_assess(zio=%px) setting " + "cant_write=TRUE due to write failure with ENXIO", + zio); vd->vdev_cant_write = B_TRUE; }