summaryrefslogtreecommitdiffstats
path: root/module/zfs/dnode.c
diff options
context:
space:
mode:
authorSerapheim Dimitropoulos <[email protected]>2019-08-15 07:44:57 -0700
committerBrian Behlendorf <[email protected]>2019-08-15 08:44:57 -0600
commit0e37a0f4f3bc4feb62a966a7c0dd64544172395f (patch)
tree3a451478c51f6d9d5ca03f853a331e06c7be9a14 /module/zfs/dnode.c
parente2b31b58e8777faa51561342d72a5a30127fa4b6 (diff)
Assert that a dnode's bonuslen never exceeds its recorded size
This patch introduces an assertion that can catch pitfalls in development where there is a mismatch between the size of reads and writes between a *_phys structure and its respective in-core structure when bonus buffers are used. This debugging-aid should be complementary to the verification done by ztest in ztest_verify_dnode_bt(). A side to this patch is that we now clear out any extra bytes past a bonus buffer's new size when the buffer is shrinking. Reviewed-by: Matt Ahrens <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Tom Caputi <[email protected]> Signed-off-by: Serapheim Dimitropoulos <[email protected]> Closes #8348
Diffstat (limited to 'module/zfs/dnode.c')
-rw-r--r--module/zfs/dnode.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c
index c9ff43fa6..ef62d394a 100644
--- a/module/zfs/dnode.c
+++ b/module/zfs/dnode.c
@@ -390,6 +390,14 @@ dnode_setbonuslen(dnode_t *dn, int newsize, dmu_tx_t *tx)
rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
ASSERT3U(newsize, <=, DN_SLOTS_TO_BONUSLEN(dn->dn_num_slots) -
(dn->dn_nblkptr-1) * sizeof (blkptr_t));
+
+ if (newsize < dn->dn_bonuslen) {
+ /* clear any data after the end of the new size */
+ size_t diff = dn->dn_bonuslen - newsize;
+ char *data_end = ((char *)dn->dn_bonus->db.db_data) + newsize;
+ bzero(data_end, diff);
+ }
+
dn->dn_bonuslen = newsize;
if (newsize == 0)
dn->dn_next_bonuslen[tx->tx_txg & TXG_MASK] = DN_ZERO_BONUSLEN;