/*
 * Return (in *dsizep) the amount of space on the deadlist which is:
 * mintxg < blk_birth <= maxtxg
 */
int
bplist_space_birthrange(bplist_t *bpl, uint64_t mintxg, uint64_t maxtxg,
    uint64_t *dsizep)
{
	uint64_t size = 0;
	uint64_t itor = 0;
	blkptr_t bp;
	int err;

	/*
	 * As an optimization, if they want the whole txg range, just
	 * get bpl_bytes rather than iterating over the bps.
	 */
	if (mintxg < TXG_INITIAL && maxtxg == UINT64_MAX) {
		mutex_enter(&bpl->bpl_lock);
		err = bplist_hold(bpl);
		if (err == 0)
			*dsizep = bpl->bpl_phys->bpl_bytes;
		mutex_exit(&bpl->bpl_lock);
		return (err);
	}

	while ((err = bplist_iterate(bpl, &itor, &bp)) == 0) {
		if (bp.blk_birth > mintxg && bp.blk_birth <= maxtxg) {
			size += bp_get_dsize(dmu_objset_spa(bpl->bpl_mos), &bp);
		}
	}
	if (err == ENOENT)
		err = 0;
	*dsizep = size;
	return (err);
}
Beispiel #2
0
static void
dmu_tx_count_twig(dmu_tx_hold_t *txh, dnode_t *dn, dmu_buf_impl_t *db,
    int level, uint64_t blkid, boolean_t freeable, uint64_t *history)
{
	objset_t *os = dn->dn_objset;
	dsl_dataset_t *ds = os->os_dsl_dataset;
	int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
	dmu_buf_impl_t *parent = NULL;
	blkptr_t *bp = NULL;
	uint64_t space;

	if (level >= dn->dn_nlevels || history[level] == blkid)
		return;

	history[level] = blkid;

	space = (level == 0) ? dn->dn_datablksz : (1ULL << dn->dn_indblkshift);

	if (db == NULL || db == dn->dn_dbuf) {
		ASSERT(level != 0);
		db = NULL;
	} else {
		ASSERT(DB_DNODE(db) == dn);
		ASSERT(db->db_level == level);
		ASSERT(db->db.db_size == space);
		ASSERT(db->db_blkid == blkid);
		bp = db->db_blkptr;
		parent = db->db_parent;
	}

	freeable = (bp && (freeable ||
	    dsl_dataset_block_freeable(ds, bp, bp->blk_birth)));

	if (freeable) {
		(void) refcount_add_many(&txh->txh_space_tooverwrite,
		    space, FTAG);
	} else {
		(void) refcount_add_many(&txh->txh_space_towrite,
		    space, FTAG);
	}

	if (bp) {
		(void) refcount_add_many(&txh->txh_space_tounref,
		    bp_get_dsize(os->os_spa, bp), FTAG);
	}

	dmu_tx_count_twig(txh, dn, parent, level + 1,
	    blkid >> epbs, freeable, history);
}