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
 
 |