diff options
author | Serapheim Dimitropoulos <[email protected]> | 2019-08-15 07:44:57 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-08-15 08:44:57 -0600 |
commit | 0e37a0f4f3bc4feb62a966a7c0dd64544172395f (patch) | |
tree | 3a451478c51f6d9d5ca03f853a331e06c7be9a14 /module/zfs/dnode.c | |
parent | e2b31b58e8777faa51561342d72a5a30127fa4b6 (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.c | 8 |
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; |