4076 nvpair_t *match;
4077
4078 next_pair = nvlist_next_nvpair(props, pair);
4079
4080 if ((nvlist_lookup_nvpair(origprops, propname,
4081 &match) != 0) || !propval_equals(pair, match))
4082 goto next; /* need to set received value */
4083
4084 /* don't clear the existing received value */
4085 (void) nvlist_remove_nvpair(origprops, match);
4086 /* don't bother receiving the property */
4087 (void) nvlist_remove_nvpair(props, pair);
4088 next:
4089 pair = next_pair;
4090 }
4091 }
4092
4093 /*
4094 * Extract properties that cannot be set PRIOR to the receipt of a dataset.
4095 * For example, refquota cannot be set until after the receipt of a dataset,
4096 * because a prior snapshot may exceed the refquota, and refquotas only apply
4097 * to the current dataset. The caller (libzfs) will manage these properties
4098 * somewhat as well to make sure they only come down with the last dataset in
4099 * a replication stream, but we still need to be safe about it here in
4100 * kernel-land.
4101 */
4102 static nvlist_t *
4103 extract_delay_props(nvlist_t *props)
4104 {
4105 nvlist_t *delayprops;
4106 nvpair_t *nvp, *tmp;
4107 static const zfs_prop_t delayable[] = { ZFS_PROP_REFQUOTA, 0 };
4108 boolean_t dontbother = B_TRUE;
4109 int i;
4110
4111 VERIFY(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
4112
4113 for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL;
4114 nvp = nvlist_next_nvpair(props, nvp)) {
4115 /*
4116 * strcmp() is safe because zfs_prop_to_name() always returns
4117 * a bounded string.
4118 */
4119 for (i = 0; delayable[i] != 0; i++) {
4120 if (strcmp(zfs_prop_to_name(delayable[i]),
4121 nvpair_name(nvp)) == 0) {
4122 break;
4123 }
4124 }
4125 if (delayable[i] != 0) {
4126 tmp = nvlist_prev_nvpair(props, nvp);
4127 VERIFY(nvlist_add_nvpair(delayprops, nvp) == 0);
4128 VERIFY(nvlist_remove_nvpair(props, nvp) == 0);
4129 nvp = tmp;
4130 dontbother = B_FALSE; /* Actually, do bother! */
4131 }
4132 }
4133
4134 if (dontbother) {
4135 nvlist_free(delayprops);
4136 delayprops = NULL;
4137 }
4138 return (delayprops);
4139 }
4140
4141 #ifdef DEBUG
4142 static boolean_t zfs_ioc_recv_inject_err;
4143 #endif
4144
4145 /*
4146 * inputs:
4147 * zc_name name of containing filesystem
4148 * zc_nvlist_src{_size} nvlist of properties to apply
4149 * zc_value name of snapshot to create
4150 * zc_string name of clone origin (if DRR_FLAG_CLONE)
4151 * zc_cookie file descriptor to recv from
4152 * zc_begin_record the BEGIN record of the stream (not byteswapped)
4153 * zc_guid force flag
4154 * zc_cleanup_fd cleanup-on-exit file descriptor
4276 /*
4277 * If the suspend fails, then the recv_end will
4278 * likely also fail, and clean up after itself.
4279 */
4280 end_err = dmu_recv_end(&drc, zfsvfs);
4281 if (error == 0)
4282 error = zfs_resume_fs(zfsvfs, tofs);
4283 error = error ? error : end_err;
4284 VFS_RELE(zfsvfs->z_vfs);
4285 } else {
4286 error = dmu_recv_end(&drc, NULL);
4287 }
4288
4289 /* Set delayed properties now, after we're done receiving. */
4290 if (delayprops != NULL) {
4291 (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4292 delayprops, errors);
4293 }
4294 }
4295
4296 /* Merge delayprops back in with regular props, in case of errors. */
4297 if (delayprops != NULL) {
4298 VERIFY(nvlist_merge(props, delayprops, 0) == 0);
4299 nvlist_free(delayprops);
4300 }
4301
4302 /* Put the props error list into zc AFTER the delayprops. */
4303 if (zc->zc_nvlist_dst_size != 0 &&
4304 (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
4305 put_nvlist(zc, errors) != 0)) {
4306 /*
4307 * Caller made zc->zc_nvlist_dst less than the minimum expected
4308 * size or supplied an invalid address.
4309 */
4310 props_error = SET_ERROR(EINVAL);
4311 }
4312
4313 zc->zc_cookie = off - fp->f_offset;
4314 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4315 fp->f_offset = off;
4316
4317 #ifdef DEBUG
4318 if (zfs_ioc_recv_inject_err) {
4319 zfs_ioc_recv_inject_err = B_FALSE;
4320 error = 1;
4321 }
4322 #endif
|
4076 nvpair_t *match;
4077
4078 next_pair = nvlist_next_nvpair(props, pair);
4079
4080 if ((nvlist_lookup_nvpair(origprops, propname,
4081 &match) != 0) || !propval_equals(pair, match))
4082 goto next; /* need to set received value */
4083
4084 /* don't clear the existing received value */
4085 (void) nvlist_remove_nvpair(origprops, match);
4086 /* don't bother receiving the property */
4087 (void) nvlist_remove_nvpair(props, pair);
4088 next:
4089 pair = next_pair;
4090 }
4091 }
4092
4093 /*
4094 * Extract properties that cannot be set PRIOR to the receipt of a dataset.
4095 * For example, refquota cannot be set until after the receipt of a dataset,
4096 * because in replication streams, an older/earlier snapshot may exceed the
4097 * refquota. We want to receive the older/earlier snapshot, but setting
4098 * refquota pre-receipt will set the dsl's ACTUAL quota, which will prevent
4099 * the older/earlier snapshot from being received (with EDQUOT).
4100 *
4101 * The ZFS test "zfs_receive_011_pos" demonstrates such a scenario.
4102 *
4103 * libzfs will need to be judicious handling errors encountered by props
4104 * extracted by this function.
4105 */
4106 static nvlist_t *
4107 extract_delay_props(nvlist_t *props)
4108 {
4109 nvlist_t *delayprops;
4110 nvpair_t *nvp, *tmp;
4111 static const zfs_prop_t delayable[] = { ZFS_PROP_REFQUOTA, 0 };
4112 int i;
4113
4114 VERIFY(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
4115
4116 for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL;
4117 nvp = nvlist_next_nvpair(props, nvp)) {
4118 /*
4119 * strcmp() is safe because zfs_prop_to_name() always returns
4120 * a bounded string.
4121 */
4122 for (i = 0; delayable[i] != 0; i++) {
4123 if (strcmp(zfs_prop_to_name(delayable[i]),
4124 nvpair_name(nvp)) == 0) {
4125 break;
4126 }
4127 }
4128 if (delayable[i] != 0) {
4129 tmp = nvlist_prev_nvpair(props, nvp);
4130 VERIFY(nvlist_add_nvpair(delayprops, nvp) == 0);
4131 VERIFY(nvlist_remove_nvpair(props, nvp) == 0);
4132 nvp = tmp;
4133 }
4134 }
4135
4136 if (nvlist_empty(delayprops)) {
4137 nvlist_free(delayprops);
4138 delayprops = NULL;
4139 }
4140 return (delayprops);
4141 }
4142
4143 #ifdef DEBUG
4144 static boolean_t zfs_ioc_recv_inject_err;
4145 #endif
4146
4147 /*
4148 * inputs:
4149 * zc_name name of containing filesystem
4150 * zc_nvlist_src{_size} nvlist of properties to apply
4151 * zc_value name of snapshot to create
4152 * zc_string name of clone origin (if DRR_FLAG_CLONE)
4153 * zc_cookie file descriptor to recv from
4154 * zc_begin_record the BEGIN record of the stream (not byteswapped)
4155 * zc_guid force flag
4156 * zc_cleanup_fd cleanup-on-exit file descriptor
4278 /*
4279 * If the suspend fails, then the recv_end will
4280 * likely also fail, and clean up after itself.
4281 */
4282 end_err = dmu_recv_end(&drc, zfsvfs);
4283 if (error == 0)
4284 error = zfs_resume_fs(zfsvfs, tofs);
4285 error = error ? error : end_err;
4286 VFS_RELE(zfsvfs->z_vfs);
4287 } else {
4288 error = dmu_recv_end(&drc, NULL);
4289 }
4290
4291 /* Set delayed properties now, after we're done receiving. */
4292 if (delayprops != NULL) {
4293 (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4294 delayprops, errors);
4295 }
4296 }
4297
4298 /*
4299 * Merge delayed props back in with initial props, so errors (which is
4300 * one list) can match up with the order in which props were set.
4301 * Also, the error cleanup code only deals with the unsplit props
4302 * list.
4303 */
4304 if (delayprops != NULL) {
4305 VERIFY(nvlist_merge(props, delayprops, 0) == 0);
4306 nvlist_free(delayprops);
4307 }
4308
4309 /*
4310 * Now that all props, initial and delayed, are set, report the prop
4311 * errors to the caller.
4312 */
4313 if (zc->zc_nvlist_dst_size != 0 &&
4314 (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
4315 put_nvlist(zc, errors) != 0)) {
4316 /*
4317 * Caller made zc->zc_nvlist_dst less than the minimum expected
4318 * size or supplied an invalid address.
4319 */
4320 props_error = SET_ERROR(EINVAL);
4321 }
4322
4323 zc->zc_cookie = off - fp->f_offset;
4324 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4325 fp->f_offset = off;
4326
4327 #ifdef DEBUG
4328 if (zfs_ioc_recv_inject_err) {
4329 zfs_ioc_recv_inject_err = B_FALSE;
4330 error = 1;
4331 }
4332 #endif
|