Print this page
Matt's code review fixes
*** 4091,4113 ****
}
/*
* Extract properties that cannot be set PRIOR to the receipt of a dataset.
* For example, refquota cannot be set until after the receipt of a dataset,
! * because a prior snapshot may exceed the refquota, and refquotas only apply
! * to the current dataset. The caller (libzfs) will manage these properties
! * somewhat as well to make sure they only come down with the last dataset in
! * a replication stream, but we still need to be safe about it here in
! * kernel-land.
*/
static nvlist_t *
extract_delay_props(nvlist_t *props)
{
nvlist_t *delayprops;
nvpair_t *nvp, *tmp;
static const zfs_prop_t delayable[] = { ZFS_PROP_REFQUOTA, 0 };
- boolean_t dontbother = B_TRUE;
int i;
VERIFY(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL;
--- 4091,4116 ----
}
/*
* Extract properties that cannot be set PRIOR to the receipt of a dataset.
* For example, refquota cannot be set until after the receipt of a dataset,
! * because in replication streams, an older/earlier snapshot may exceed the
! * refquota. We want to receive the older/earlier snapshot, but setting
! * refquota pre-receipt will set the dsl's ACTUAL quota, which will prevent
! * the older/earlier snapshot from being received (with EDQUOT).
! *
! * The ZFS test "zfs_receive_011_pos" demonstrates such a scenario.
! *
! * libzfs will need to be judicious handling errors encountered by props
! * extracted by this function.
*/
static nvlist_t *
extract_delay_props(nvlist_t *props)
{
nvlist_t *delayprops;
nvpair_t *nvp, *tmp;
static const zfs_prop_t delayable[] = { ZFS_PROP_REFQUOTA, 0 };
int i;
VERIFY(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL;
*** 4125,4139 ****
if (delayable[i] != 0) {
tmp = nvlist_prev_nvpair(props, nvp);
VERIFY(nvlist_add_nvpair(delayprops, nvp) == 0);
VERIFY(nvlist_remove_nvpair(props, nvp) == 0);
nvp = tmp;
- dontbother = B_FALSE; /* Actually, do bother! */
}
}
! if (dontbother) {
nvlist_free(delayprops);
delayprops = NULL;
}
return (delayprops);
}
--- 4128,4141 ----
if (delayable[i] != 0) {
tmp = nvlist_prev_nvpair(props, nvp);
VERIFY(nvlist_add_nvpair(delayprops, nvp) == 0);
VERIFY(nvlist_remove_nvpair(props, nvp) == 0);
nvp = tmp;
}
}
! if (nvlist_empty(delayprops)) {
nvlist_free(delayprops);
delayprops = NULL;
}
return (delayprops);
}
*** 4291,4307 ****
(void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
delayprops, errors);
}
}
! /* Merge delayprops back in with regular props, in case of errors. */
if (delayprops != NULL) {
VERIFY(nvlist_merge(props, delayprops, 0) == 0);
nvlist_free(delayprops);
}
! /* Put the props error list into zc AFTER the delayprops. */
if (zc->zc_nvlist_dst_size != 0 &&
(nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
put_nvlist(zc, errors) != 0)) {
/*
* Caller made zc->zc_nvlist_dst less than the minimum expected
--- 4293,4317 ----
(void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
delayprops, errors);
}
}
! /*
! * Merge delayed props back in with initial props, so errors (which is
! * one list) can match up with the order in which props were set.
! * Also, the error cleanup code only deals with the unsplit props
! * list.
! */
if (delayprops != NULL) {
VERIFY(nvlist_merge(props, delayprops, 0) == 0);
nvlist_free(delayprops);
}
! /*
! * Now that all props, initial and delayed, are set, report the prop
! * errors to the caller.
! */
if (zc->zc_nvlist_dst_size != 0 &&
(nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
put_nvlist(zc, errors) != 0)) {
/*
* Caller made zc->zc_nvlist_dst less than the minimum expected