コード例 #1
0
ファイル: dsl_prop.c プロジェクト: Alyseo/zfs
/* ARGSUSED */
static int
dsl_prop_notify_all_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
{
	dsl_dir_t *dd = ds->ds_dir;
	dsl_prop_record_t *pr;
	dsl_prop_cb_record_t *cbr;

	mutex_enter(&dd->dd_lock);
	for (pr = list_head(&dd->dd_props);
	    pr; pr = list_next(&dd->dd_props, pr)) {
		for (cbr = list_head(&pr->pr_cbs); cbr;
		    cbr = list_next(&pr->pr_cbs, cbr)) {
			uint64_t value;

			/*
			 * Callback entries do not have holds on their
			 * datasets so that datasets with registered
			 * callbacks are still eligible for eviction.
			 * Unlike operations to update properties on a
			 * single dataset, we are performing a recursive
			 * descent of related head datasets.  The caller
			 * of this function only has a dataset hold on
			 * the passed in head dataset, not the snapshots
			 * associated with this dataset.  Without a hold,
			 * the dataset pointer within callback records
			 * for snapshots can be invalidated by eviction
			 * at any time.
			 *
			 * Use dsl_dataset_try_add_ref() to verify
			 * that the dataset for a snapshot has not
			 * begun eviction processing and to prevent
			 * eviction from occurring for the duration of
			 * the callback.  If the hold attempt fails,
			 * this object is already being evicted and the
			 * callback can be safely ignored.
			 */
			if (ds != cbr->cbr_ds &&
			    !dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
				continue;

			if (dsl_prop_get_ds(cbr->cbr_ds,
			    cbr->cbr_pr->pr_propname, sizeof (value), 1,
			    &value, NULL) == 0)
				cbr->cbr_func(cbr->cbr_arg, value);

			if (ds != cbr->cbr_ds)
				dsl_dataset_rele(cbr->cbr_ds, FTAG);
		}
	}
	mutex_exit(&dd->dd_lock);

	return (0);
}
コード例 #2
0
ファイル: dsl_prop.c プロジェクト: mikess/illumos-gate
/* ARGSUSED */
static int
dsl_prop_notify_all_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
{
	dsl_dir_t *dd = ds->ds_dir;
	dsl_prop_cb_record_t *cbr;

	mutex_enter(&dd->dd_lock);
	for (cbr = list_head(&dd->dd_prop_cbs); cbr;
	    cbr = list_next(&dd->dd_prop_cbs, cbr)) {
		uint64_t value;

		/*
		 * Callback entries do not have holds on their datasets
		 * so that datasets with registered callbacks are still
		 * eligible for eviction.  Unlike operations on callbacks
		 * for a single dataset, we are performing a recursive
		 * descent of related datasets and the calling context
		 * for this iteration only has a dataset hold on the root.
		 * Without a hold, the callback's pointer to the dataset
		 * could be invalidated by eviction at any time.
		 *
		 * Use dsl_dataset_try_add_ref() to verify that the
		 * dataset has not begun eviction processing and to
		 * prevent eviction from occurring for the duration
		 * of the callback.  If the hold attempt fails, this
		 * object is already being evicted and the callback can
		 * be safely ignored.
		 */
		if (!dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
			continue;

		if (dsl_prop_get_ds(cbr->cbr_ds, cbr->cbr_propname,
		    sizeof (value), 1, &value, NULL) == 0)
			cbr->cbr_func(cbr->cbr_arg, value);

		dsl_dataset_rele(cbr->cbr_ds, FTAG);
	}
	mutex_exit(&dd->dd_lock);

	return (0);
}