594 embedok = B_FALSE;
595 }
596
597 DMU_SET_FEATUREFLAGS(drr->drr_u.drr_begin.drr_versioninfo,
598 featureflags);
599
600 drr->drr_u.drr_begin.drr_creation_time =
601 dsl_dataset_phys(ds)->ds_creation_time;
602 drr->drr_u.drr_begin.drr_type = dmu_objset_type(os);
603 if (is_clone)
604 drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CLONE;
605 drr->drr_u.drr_begin.drr_toguid = dsl_dataset_phys(ds)->ds_guid;
606 if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
607 drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CI_DATA;
608
609 if (fromzb != NULL) {
610 drr->drr_u.drr_begin.drr_fromguid = fromzb->zbm_guid;
611 fromtxg = fromzb->zbm_creation_txg;
612 }
613 dsl_dataset_name(ds, drr->drr_u.drr_begin.drr_toname);
614 if (!dsl_dataset_is_snapshot(ds)) {
615 (void) strlcat(drr->drr_u.drr_begin.drr_toname, "@--head--",
616 sizeof (drr->drr_u.drr_begin.drr_toname));
617 }
618
619 dsp = kmem_zalloc(sizeof (dmu_sendarg_t), KM_SLEEP);
620
621 dsp->dsa_drr = drr;
622 dsp->dsa_vp = vp;
623 dsp->dsa_outfd = outfd;
624 dsp->dsa_proc = curproc;
625 dsp->dsa_os = os;
626 dsp->dsa_off = off;
627 dsp->dsa_toguid = dsl_dataset_phys(ds)->ds_guid;
628 ZIO_SET_CHECKSUM(&dsp->dsa_zc, 0, 0, 0, 0);
629 dsp->dsa_pending_op = PENDING_NONE;
630 dsp->dsa_incremental = (fromzb != NULL);
631 dsp->dsa_featureflags = featureflags;
632
633 mutex_enter(&ds->ds_sendstream_lock);
634 list_insert_head(&ds->ds_sendstreams, dsp);
801 err = dmu_send_impl(FTAG, dp, ds, NULL, B_FALSE,
802 embedok, large_block_ok, outfd, vp, off);
803 }
804 if (owned)
805 dsl_dataset_disown(ds, FTAG);
806 else
807 dsl_dataset_rele(ds, FTAG);
808 return (err);
809 }
810
811 int
812 dmu_send_estimate(dsl_dataset_t *ds, dsl_dataset_t *fromds, uint64_t *sizep)
813 {
814 dsl_pool_t *dp = ds->ds_dir->dd_pool;
815 int err;
816 uint64_t size;
817
818 ASSERT(dsl_pool_config_held(dp));
819
820 /* tosnap must be a snapshot */
821 if (!dsl_dataset_is_snapshot(ds))
822 return (SET_ERROR(EINVAL));
823
824 /*
825 * fromsnap must be an earlier snapshot from the same fs as tosnap,
826 * or the origin's fs.
827 */
828 if (fromds != NULL && !dsl_dataset_is_before(ds, fromds, 0))
829 return (SET_ERROR(EXDEV));
830
831 /* Get uncompressed size estimate of changed data. */
832 if (fromds == NULL) {
833 size = dsl_dataset_phys(ds)->ds_uncompressed_bytes;
834 } else {
835 uint64_t used, comp;
836 err = dsl_dataset_space_written(fromds, ds,
837 &used, &comp, &size);
838 if (err != 0)
839 return (err);
840 }
841
1048 if (error != 0) {
1049 dsl_dataset_rele(ds, FTAG);
1050 return (error);
1051 }
1052
1053 error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
1054 ZFS_PROP_SNAPSHOT_LIMIT, NULL, drba->drba_cred);
1055 if (error != 0) {
1056 dsl_dataset_rele(ds, FTAG);
1057 return (error);
1058 }
1059
1060 if (drba->drba_origin != NULL) {
1061 dsl_dataset_t *origin;
1062 error = dsl_dataset_hold(dp, drba->drba_origin,
1063 FTAG, &origin);
1064 if (error != 0) {
1065 dsl_dataset_rele(ds, FTAG);
1066 return (error);
1067 }
1068 if (!dsl_dataset_is_snapshot(origin)) {
1069 dsl_dataset_rele(origin, FTAG);
1070 dsl_dataset_rele(ds, FTAG);
1071 return (SET_ERROR(EINVAL));
1072 }
1073 if (dsl_dataset_phys(origin)->ds_guid != fromguid) {
1074 dsl_dataset_rele(origin, FTAG);
1075 dsl_dataset_rele(ds, FTAG);
1076 return (SET_ERROR(ENODEV));
1077 }
1078 dsl_dataset_rele(origin, FTAG);
1079 }
1080 dsl_dataset_rele(ds, FTAG);
1081 error = 0;
1082 }
1083 return (error);
1084 }
1085
1086 static void
1087 dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
1088 {
|
594 embedok = B_FALSE;
595 }
596
597 DMU_SET_FEATUREFLAGS(drr->drr_u.drr_begin.drr_versioninfo,
598 featureflags);
599
600 drr->drr_u.drr_begin.drr_creation_time =
601 dsl_dataset_phys(ds)->ds_creation_time;
602 drr->drr_u.drr_begin.drr_type = dmu_objset_type(os);
603 if (is_clone)
604 drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CLONE;
605 drr->drr_u.drr_begin.drr_toguid = dsl_dataset_phys(ds)->ds_guid;
606 if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
607 drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CI_DATA;
608
609 if (fromzb != NULL) {
610 drr->drr_u.drr_begin.drr_fromguid = fromzb->zbm_guid;
611 fromtxg = fromzb->zbm_creation_txg;
612 }
613 dsl_dataset_name(ds, drr->drr_u.drr_begin.drr_toname);
614 if (!ds->ds_is_snapshot) {
615 (void) strlcat(drr->drr_u.drr_begin.drr_toname, "@--head--",
616 sizeof (drr->drr_u.drr_begin.drr_toname));
617 }
618
619 dsp = kmem_zalloc(sizeof (dmu_sendarg_t), KM_SLEEP);
620
621 dsp->dsa_drr = drr;
622 dsp->dsa_vp = vp;
623 dsp->dsa_outfd = outfd;
624 dsp->dsa_proc = curproc;
625 dsp->dsa_os = os;
626 dsp->dsa_off = off;
627 dsp->dsa_toguid = dsl_dataset_phys(ds)->ds_guid;
628 ZIO_SET_CHECKSUM(&dsp->dsa_zc, 0, 0, 0, 0);
629 dsp->dsa_pending_op = PENDING_NONE;
630 dsp->dsa_incremental = (fromzb != NULL);
631 dsp->dsa_featureflags = featureflags;
632
633 mutex_enter(&ds->ds_sendstream_lock);
634 list_insert_head(&ds->ds_sendstreams, dsp);
801 err = dmu_send_impl(FTAG, dp, ds, NULL, B_FALSE,
802 embedok, large_block_ok, outfd, vp, off);
803 }
804 if (owned)
805 dsl_dataset_disown(ds, FTAG);
806 else
807 dsl_dataset_rele(ds, FTAG);
808 return (err);
809 }
810
811 int
812 dmu_send_estimate(dsl_dataset_t *ds, dsl_dataset_t *fromds, uint64_t *sizep)
813 {
814 dsl_pool_t *dp = ds->ds_dir->dd_pool;
815 int err;
816 uint64_t size;
817
818 ASSERT(dsl_pool_config_held(dp));
819
820 /* tosnap must be a snapshot */
821 if (!ds->ds_is_snapshot)
822 return (SET_ERROR(EINVAL));
823
824 /*
825 * fromsnap must be an earlier snapshot from the same fs as tosnap,
826 * or the origin's fs.
827 */
828 if (fromds != NULL && !dsl_dataset_is_before(ds, fromds, 0))
829 return (SET_ERROR(EXDEV));
830
831 /* Get uncompressed size estimate of changed data. */
832 if (fromds == NULL) {
833 size = dsl_dataset_phys(ds)->ds_uncompressed_bytes;
834 } else {
835 uint64_t used, comp;
836 err = dsl_dataset_space_written(fromds, ds,
837 &used, &comp, &size);
838 if (err != 0)
839 return (err);
840 }
841
1048 if (error != 0) {
1049 dsl_dataset_rele(ds, FTAG);
1050 return (error);
1051 }
1052
1053 error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
1054 ZFS_PROP_SNAPSHOT_LIMIT, NULL, drba->drba_cred);
1055 if (error != 0) {
1056 dsl_dataset_rele(ds, FTAG);
1057 return (error);
1058 }
1059
1060 if (drba->drba_origin != NULL) {
1061 dsl_dataset_t *origin;
1062 error = dsl_dataset_hold(dp, drba->drba_origin,
1063 FTAG, &origin);
1064 if (error != 0) {
1065 dsl_dataset_rele(ds, FTAG);
1066 return (error);
1067 }
1068 if (!origin->ds_is_snapshot) {
1069 dsl_dataset_rele(origin, FTAG);
1070 dsl_dataset_rele(ds, FTAG);
1071 return (SET_ERROR(EINVAL));
1072 }
1073 if (dsl_dataset_phys(origin)->ds_guid != fromguid) {
1074 dsl_dataset_rele(origin, FTAG);
1075 dsl_dataset_rele(ds, FTAG);
1076 return (SET_ERROR(ENODEV));
1077 }
1078 dsl_dataset_rele(origin, FTAG);
1079 }
1080 dsl_dataset_rele(ds, FTAG);
1081 error = 0;
1082 }
1083 return (error);
1084 }
1085
1086 static void
1087 dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
1088 {
|