mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
Fix object reclaim when using large dnodes
Currently, when the receive_object() code wants to reclaim an object, it always assumes that the dnode is the legacy 512 bytes, even when the incoming bonus buffer exceeds this length. This causes a buffer overflow if --enable-debug is not provided and triggers an ASSERT if it is. This patch resolves this issue and adds an ASSERT to ensure this can't happen again. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Tom Caputi <tcaputi@datto.com> Closes #7097 Closes #7433
This commit is contained in:
committed by
Brian Behlendorf
parent
0c03d21ac9
commit
e14a32b1c8
@@ -249,7 +249,7 @@ dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot,
|
||||
int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
|
||||
{
|
||||
return (dmu_object_reclaim_dnsize(os, object, ot, blocksize, bonustype,
|
||||
bonuslen, 0, tx));
|
||||
bonuslen, DNODE_MIN_SIZE, tx));
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -2606,9 +2606,10 @@ receive_object(struct receive_writer_arg *rwa, struct drr_object *drro,
|
||||
drro->drr_bonustype != doi.doi_bonus_type ||
|
||||
drro->drr_bonuslen != doi.doi_bonus_size) {
|
||||
/* currently allocated, but with different properties */
|
||||
err = dmu_object_reclaim(rwa->os, drro->drr_object,
|
||||
err = dmu_object_reclaim_dnsize(rwa->os, drro->drr_object,
|
||||
drro->drr_type, drro->drr_blksz,
|
||||
drro->drr_bonustype, drro->drr_bonuslen, tx);
|
||||
drro->drr_bonustype, drro->drr_bonuslen,
|
||||
drro->drr_dn_slots << DNODE_SHIFT, tx);
|
||||
}
|
||||
if (err != 0) {
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
+1
-2
@@ -676,8 +676,7 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
|
||||
ASSERT(DMU_OT_IS_VALID(bonustype));
|
||||
ASSERT3U(bonuslen, <=,
|
||||
DN_BONUS_SIZE(spa_maxdnodesize(dmu_objset_spa(dn->dn_objset))));
|
||||
|
||||
dn_slots = dn_slots > 0 ? dn_slots : DNODE_MIN_SLOTS;
|
||||
ASSERT3U(bonuslen, <=, DN_BONUS_SIZE(dn_slots << DNODE_SHIFT));
|
||||
|
||||
dnode_free_interior_slots(dn);
|
||||
DNODE_STAT_BUMP(dnode_reallocate);
|
||||
|
||||
Reference in New Issue
Block a user