Skip to content

Commit

Permalink
dbuf: Set dr_data when unoverriding after clone
Browse files Browse the repository at this point in the history
Block cloning normally creates dirty record without dr_data.  But if
the block is read after cloning, it is moved into DB_CACHED state and
receives the data buffer.  If after that we call dbuf_unoverride()
to convert the dirty record into normal write, we should give it the
data buffer from dbuf and release one.

Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
  • Loading branch information
amotin committed Dec 9, 2023
1 parent 8ad73bf commit 8c3151d
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions module/zfs/dbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1919,7 +1919,6 @@ dbuf_unoverride(dbuf_dirty_record_t *dr)
dmu_buf_impl_t *db = dr->dr_dbuf;
blkptr_t *bp = &dr->dt.dl.dr_overridden_by;
uint64_t txg = dr->dr_txg;
boolean_t release;

ASSERT(MUTEX_HELD(&db->db_mtx));
/*
Expand All @@ -1940,7 +1939,8 @@ dbuf_unoverride(dbuf_dirty_record_t *dr)
if (!BP_IS_HOLE(bp) && !dr->dt.dl.dr_nopwrite)
zio_free(db->db_objset->os_spa, txg, bp);

release = !dr->dt.dl.dr_brtwrite;
if (dr->dt.dl.dr_brtwrite)
dr->dt.dl.dr_data = db->db_buf;
dr->dt.dl.dr_override_state = DR_NOT_OVERRIDDEN;
dr->dt.dl.dr_nopwrite = B_FALSE;
dr->dt.dl.dr_brtwrite = B_FALSE;
Expand All @@ -1954,7 +1954,7 @@ dbuf_unoverride(dbuf_dirty_record_t *dr)
* the buf thawed to save the effort of freezing &
* immediately re-thawing it.
*/
if (release)
if (dr->dt.dl.dr_data)
arc_release(dr->dt.dl.dr_data, db);
}

Expand Down

0 comments on commit 8c3151d

Please sign in to comment.