diff options
Diffstat (limited to 'module')
-rw-r--r-- | module/zfs/dmu_send.c | 2 | ||||
-rw-r--r-- | module/zfs/dnode_sync.c | 2 | ||||
-rw-r--r-- | module/zfs/dsl_scan.c | 13 |
3 files changed, 17 insertions, 0 deletions
diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index 2f2fd4c3d..58a72a68a 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -763,6 +763,8 @@ dump_dnode(dmu_send_cookie_t *dscp, const blkptr_t *bp, uint64_t object, * to send it. */ if (bonuslen != 0) { + if (drro->drr_bonuslen > DN_MAX_BONUS_LEN(dnp)) + return (SET_ERROR(EINVAL)); drro->drr_raw_bonuslen = DN_MAX_BONUS_LEN(dnp); bonuslen = drro->drr_raw_bonuslen; } diff --git a/module/zfs/dnode_sync.c b/module/zfs/dnode_sync.c index f574130e5..12ab4bea1 100644 --- a/module/zfs/dnode_sync.c +++ b/module/zfs/dnode_sync.c @@ -854,6 +854,8 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx) dnode_rele(dn, (void *)(uintptr_t)tx->tx_txg); } + ASSERT3U(dnp->dn_bonuslen, <=, DN_MAX_BONUS_LEN(dnp)); + /* * Although we have dropped our reference to the dnode, it * can't be evicted until its written, and we haven't yet diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c index 62ee9bb9a..765998417 100644 --- a/module/zfs/dsl_scan.c +++ b/module/zfs/dsl_scan.c @@ -1821,6 +1821,19 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype, ASSERT(!BP_IS_REDACTED(bp)); + /* + * There is an unlikely case of encountering dnodes with contradicting + * dn_bonuslen and DNODE_FLAG_SPILL_BLKPTR flag before in files created + * or modified before commit 4254acb was merged. As it is not possible + * to know which of the two is correct, report an error. + */ + if (dnp != NULL && + dnp->dn_bonuslen > DN_MAX_BONUS_LEN(dnp)) { + scn->scn_phys.scn_errors++; + spa_log_error(dp->dp_spa, zb); + return (SET_ERROR(EINVAL)); + } + if (BP_GET_LEVEL(bp) > 0) { arc_flags_t flags = ARC_FLAG_WAIT; int i; |