Esempio n. 1
0
static int
dump_dnode(dmu_sendarg_t *dsp, uint64_t object, dnode_phys_t *dnp)
{
	struct drr_object *drro = &(dsp->dsa_drr->drr_u.drr_object);

	if (dnp == NULL || dnp->dn_type == DMU_OT_NONE)
		return (dump_freeobjects(dsp, object, 1));

	if (dsp->dsa_pending_op != PENDING_NONE) {
		if (dump_bytes(dsp, dsp->dsa_drr,
		    sizeof (dmu_replay_record_t)) != 0)
			return (EINTR);
		dsp->dsa_pending_op = PENDING_NONE;
	}

	/* write an OBJECT record */
	bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
	dsp->dsa_drr->drr_type = DRR_OBJECT;
	drro->drr_object = object;
	drro->drr_type = dnp->dn_type;
	drro->drr_bonustype = dnp->dn_bonustype;
	drro->drr_blksz = dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT;
	drro->drr_bonuslen = dnp->dn_bonuslen;
	drro->drr_checksumtype = dnp->dn_checksum;
	drro->drr_compress = dnp->dn_compress;
	drro->drr_toguid = dsp->dsa_toguid;

	if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)) != 0)
		return (EINTR);

	if (dump_bytes(dsp, DN_BONUS(dnp), P2ROUNDUP(dnp->dn_bonuslen, 8)) != 0)
		return (EINTR);

	/* free anything past the end of the file */
	if (dump_free(dsp, object, (dnp->dn_maxblkid + 1) *
	    (dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT), -1ULL))
		return (EINTR);
	if (dsp->dsa_err)
		return (EINTR);
	return (0);
}
Esempio n. 2
0
void
dmu_objset_do_userquota_callbacks(objset_impl_t *os, dmu_tx_t *tx)
{
	dnode_t *dn;
	list_t *list = &os->os_synced_dnodes;
	ASSERTV(static const char zerobuf[DN_MAX_BONUSLEN] = {0});

	ASSERT(list_head(list) == NULL || dmu_objset_userused_enabled(os));

	while ((dn = list_head(list))) {
		dmu_object_type_t bonustype;

		ASSERT(!DMU_OBJECT_IS_SPECIAL(dn->dn_object));
		ASSERT(dn->dn_oldphys);
		ASSERT(dn->dn_phys->dn_type == DMU_OT_NONE ||
		    dn->dn_phys->dn_flags &
		    DNODE_FLAG_USERUSED_ACCOUNTED);

		/* Allocate the user/groupused objects if necessary. */
		if (os->os_userused_dnode->dn_type == DMU_OT_NONE) {
			VERIFY(0 == zap_create_claim(&os->os,
			    DMU_USERUSED_OBJECT,
			    DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx));
			VERIFY(0 == zap_create_claim(&os->os,
			    DMU_GROUPUSED_OBJECT,
			    DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx));
		}

		/*
		 * If the object was not previously
		 * accounted, pretend that it was free.
		 */
		if (!(dn->dn_oldphys->dn_flags &
		    DNODE_FLAG_USERUSED_ACCOUNTED)) {
			bzero(dn->dn_oldphys, sizeof (dnode_phys_t));
		}

		/*
		 * If the object was freed, use the previous bonustype.
		 */
		bonustype = dn->dn_phys->dn_bonustype ?
		    dn->dn_phys->dn_bonustype : dn->dn_oldphys->dn_bonustype;
		ASSERT(dn->dn_phys->dn_type != 0 ||
		    (bcmp(DN_BONUS(dn->dn_phys), zerobuf,
		    DN_MAX_BONUSLEN) == 0 &&
		    DN_USED_BYTES(dn->dn_phys) == 0));
		ASSERT(dn->dn_oldphys->dn_type != 0 ||
		    (bcmp(DN_BONUS(dn->dn_oldphys), zerobuf,
		    DN_MAX_BONUSLEN) == 0 &&
		    DN_USED_BYTES(dn->dn_oldphys) == 0));
		used_cbs[os->os_phys->os_type](&os->os, bonustype,
		    DN_BONUS(dn->dn_oldphys), DN_BONUS(dn->dn_phys),
		    DN_USED_BYTES(dn->dn_oldphys),
		    DN_USED_BYTES(dn->dn_phys), tx);

		/*
		 * The mutex is needed here for interlock with dnode_allocate.
		 */
		mutex_enter(&dn->dn_mtx);
		zio_buf_free(dn->dn_oldphys, sizeof (dnode_phys_t));
		dn->dn_oldphys = NULL;
		mutex_exit(&dn->dn_mtx);

		list_remove(list, dn);
		dnode_rele(dn, list);
	}
}