/* ARGSUSED */ static void ready(zio_t *zio, arc_buf_t *abuf, void *arg) { objset_impl_t *os = arg; blkptr_t *bp = os->os_rootbp; dnode_phys_t *dnp = &os->os_phys->os_meta_dnode; int i; ASSERT(bp == zio->io_bp); /* * Update rootbp fill count. */ bp->blk_fill = 1; /* count the meta-dnode */ for (i = 0; i < dnp->dn_nblkptr; i++) bp->blk_fill += dnp->dn_blkptr[i].blk_fill; BP_SET_TYPE(bp, DMU_OT_OBJSET); BP_SET_LEVEL(bp, 0); /* We must do this after we've set the bp's type and level */ if (!DVA_EQUAL(BP_IDENTITY(bp), BP_IDENTITY(&zio->io_bp_orig))) { if (zio->io_bp_orig.blk_birth == os->os_synctx->tx_txg) (void) dsl_dataset_block_kill(os->os_dsl_dataset, &zio->io_bp_orig, NULL, os->os_synctx); dsl_dataset_block_born(os->os_dsl_dataset, bp, os->os_synctx); } }
static void free_blocks(dnode_t *dn, blkptr_t *bp, int num, dmu_tx_t *tx) { dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset; uint64_t bytesfreed = 0; int i; dprintf("ds=%p obj=%llx num=%d\n", ds, dn->dn_object, num); for (i = 0; i < num; i++, bp++) { uint64_t lsize, lvl; dmu_object_type_t type; if (BP_IS_HOLE(bp)) continue; bytesfreed += dsl_dataset_block_kill(ds, bp, tx, B_FALSE); ASSERT3U(bytesfreed, <=, DN_USED_BYTES(dn->dn_phys)); /* * Save some useful information on the holes being * punched, including logical size, type, and indirection * level. Retaining birth time enables detection of when * holes are punched for reducing the number of free * records transmitted during a zfs send. */ lsize = BP_GET_LSIZE(bp); type = BP_GET_TYPE(bp); lvl = BP_GET_LEVEL(bp); bzero(bp, sizeof (blkptr_t)); if (spa_feature_is_active(dn->dn_objset->os_spa, SPA_FEATURE_HOLE_BIRTH)) { BP_SET_LSIZE(bp, lsize); BP_SET_TYPE(bp, type); BP_SET_LEVEL(bp, lvl); BP_SET_BIRTH(bp, dmu_tx_get_txg(tx), 0); } } dnode_diduse_space(dn, -bytesfreed); }