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