diff --git a/include/sys/dbuf.h b/include/sys/dbuf.h index 0b379ee79caa..f6c72abf04e9 100644 --- a/include/sys/dbuf.h +++ b/include/sys/dbuf.h @@ -347,7 +347,8 @@ uint64_t dbuf_whichblock(const struct dnode *di, const int64_t level, const uint64_t offset); void dbuf_create_bonus(struct dnode *dn); -int dbuf_spill_set_blksz(dmu_buf_t *db, uint64_t blksz, dmu_tx_t *tx); +int dbuf_spill_set_blksz(dmu_buf_t *db, uint64_t blksz, boolean_t copy, + dmu_tx_t *tx); void dbuf_rm_spill(struct dnode *dn, dmu_tx_t *tx); @@ -414,7 +415,7 @@ void dbuf_free_range(struct dnode *dn, uint64_t start, uint64_t end, void dbuf_evict_range(struct dnode *dn, uint64_t start_blkid, uint64_t end_blkid); -void dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx); +void dbuf_new_size(dmu_buf_impl_t *db, int size, boolean_t copy, dmu_tx_t *tx); void dbuf_stats_init(dbuf_hash_table_t *hash); void dbuf_stats_destroy(void); diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 9e899e3ea334..59df70696bf4 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -2149,7 +2149,7 @@ dbuf_evict_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid) } void -dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx) +dbuf_new_size(dmu_buf_impl_t *db, int size, boolean_t copy, dmu_tx_t *tx) { arc_buf_t *buf, *old_buf; dbuf_dirty_record_t *dr; @@ -2173,12 +2173,15 @@ dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx) /* create the data buffer for the new block */ buf = arc_alloc_buf(dn->dn_objset->os_spa, db, type, size); - /* copy old block data to the new block */ old_buf = db->db_buf; - memcpy(buf->b_data, old_buf->b_data, MIN(osize, size)); - /* zero the remainder */ - if (size > osize) - memset((uint8_t *)buf->b_data + osize, 0, size - osize); + if (copy) { + ASSERT(arc_get_compression(old_buf) == ZIO_COMPRESS_OFF); + /* copy old block data to the new block */ + memcpy(buf->b_data, old_buf->b_data, MIN(osize, size)); + /* zero the remainder */ + if (size > osize) + memset((uint8_t *)buf->b_data + osize, 0, size - osize); + } mutex_enter(&db->db_mtx); dbuf_set_data(db, buf); @@ -4129,7 +4132,8 @@ dbuf_create_bonus(dnode_t *dn) } int -dbuf_spill_set_blksz(dmu_buf_t *db_fake, uint64_t blksz, dmu_tx_t *tx) +dbuf_spill_set_blksz(dmu_buf_t *db_fake, uint64_t blksz, boolean_t copy, + dmu_tx_t *tx) { dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake; @@ -4140,7 +4144,7 @@ dbuf_spill_set_blksz(dmu_buf_t *db_fake, uint64_t blksz, dmu_tx_t *tx) ASSERT3U(blksz, <=, spa_maxblocksize(dmu_objset_spa(db->db_objset))); blksz = P2ROUNDUP(blksz, SPA_MINBLOCKSIZE); - dbuf_new_size(db, blksz, tx); + dbuf_new_size(db, blksz, copy, tx); return (0); } diff --git a/module/zfs/dmu_recv.c b/module/zfs/dmu_recv.c index d7231665085d..dda6f5229942 100644 --- a/module/zfs/dmu_recv.c +++ b/module/zfs/dmu_recv.c @@ -3521,7 +3521,7 @@ receive_spill(struct receive_writer_arg *rwa, struct drr_spill *drrs, if (db_spill->db_size != drrs->drr_length) { dmu_buf_will_fill(db_spill, tx, B_FALSE); VERIFY0(dbuf_spill_set_blksz(db_spill, - drrs->drr_length, tx)); + drrs->drr_length, B_FALSE, tx)); } arc_buf_t *abuf; diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c index 5c0d93bd17b0..cc148a88df48 100644 --- a/module/zfs/dnode.c +++ b/module/zfs/dnode.c @@ -1978,7 +1978,7 @@ dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx) /* resize the old block */ err = dbuf_hold_impl(dn, 0, 0, TRUE, FALSE, FTAG, &db); if (err == 0) { - dbuf_new_size(db, size, tx); + dbuf_new_size(db, size, B_TRUE, tx); } else if (err != ENOENT) { goto fail; } diff --git a/module/zfs/dsl_bookmark.c b/module/zfs/dsl_bookmark.c index b0354203d425..704552424c89 100644 --- a/module/zfs/dsl_bookmark.c +++ b/module/zfs/dsl_bookmark.c @@ -493,7 +493,7 @@ dsl_bookmark_create_sync_impl_snap(const char *bookmark, const char *snapshot, DB_RF_MUST_SUCCEED, tag, &db)); dmu_buf_will_fill(db, tx, B_FALSE); VERIFY0(dbuf_spill_set_blksz(db, P2ROUNDUP(bonuslen, - SPA_MINBLOCKSIZE), tx)); + SPA_MINBLOCKSIZE), B_TRUE, tx)); local_rl->rl_phys = db->db_data; local_rl->rl_dbuf = db; } diff --git a/module/zfs/sa.c b/module/zfs/sa.c index c6b36474b9fa..a616309caa71 100644 --- a/module/zfs/sa.c +++ b/module/zfs/sa.c @@ -504,7 +504,7 @@ sa_resize_spill(sa_handle_t *hdl, uint32_t size, dmu_tx_t *tx) blocksize = P2ROUNDUP_TYPED(size, SPA_MINBLOCKSIZE, uint32_t); } - error = dbuf_spill_set_blksz(hdl->sa_spill, blocksize, tx); + error = dbuf_spill_set_blksz(hdl->sa_spill, blocksize, B_TRUE, tx); ASSERT0(error); return (error); }