mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-27 02:14:28 +03:00
Fix double mutex_init bug in send code
It was possible to cause a kernel panic in the send code by initializing an already-initialized mutex, if a record was created with type DATA, destroyed with a different type (bypassing the mutex_destroy call) and then re-allocated as a DATA record again. We tweak the logic to not change the type of a record once it has been created, avoiding the issue. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Jorgen Lundman <lundman@lundman.net> Signed-off-by: Paul Dagnelie <pcd@delphix.com> Closes #10374
This commit is contained in:
parent
52998c7f36
commit
99b281f1ae
@ -1153,23 +1153,30 @@ send_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
||||
if (zb->zb_blkid == DMU_SPILL_BLKID)
|
||||
ASSERT3U(BP_GET_TYPE(bp), ==, DMU_OT_SA);
|
||||
|
||||
record = range_alloc(DATA, zb->zb_object, start, (start + span < start ?
|
||||
0 : start + span), B_FALSE);
|
||||
enum type record_type = DATA;
|
||||
if (BP_IS_HOLE(bp))
|
||||
record_type = HOLE;
|
||||
else if (BP_IS_REDACTED(bp))
|
||||
record_type = REDACT;
|
||||
else
|
||||
record_type = DATA;
|
||||
|
||||
record = range_alloc(record_type, zb->zb_object, start,
|
||||
(start + span < start ? 0 : start + span), B_FALSE);
|
||||
|
||||
uint64_t datablksz = (zb->zb_blkid == DMU_SPILL_BLKID ?
|
||||
BP_GET_LSIZE(bp) : dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
|
||||
|
||||
if (BP_IS_HOLE(bp)) {
|
||||
record->type = HOLE;
|
||||
record->sru.hole.datablksz = datablksz;
|
||||
} else if (BP_IS_REDACTED(bp)) {
|
||||
record->type = REDACT;
|
||||
record->sru.redact.datablksz = datablksz;
|
||||
} else {
|
||||
record->type = DATA;
|
||||
record->sru.data.datablksz = datablksz;
|
||||
record->sru.data.obj_type = dnp->dn_type;
|
||||
record->sru.data.bp = *bp;
|
||||
}
|
||||
|
||||
bqueue_enqueue(&sta->q, record, sizeof (*record));
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user