10fa1b3cPaul Dagnelie/*
20fa1b3cPaul Dagnelie * CDDL HEADER START
30fa1b3cPaul Dagnelie *
40fa1b3cPaul Dagnelie * The contents of this file are subject to the terms of the
50fa1b3cPaul Dagnelie * Common Development and Distribution License (the "License").
60fa1b3cPaul Dagnelie * You may not use this file except in compliance with the License.
70fa1b3cPaul Dagnelie *
80fa1b3cPaul Dagnelie * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90fa1b3cPaul Dagnelie * or http://www.opensolaris.org/os/licensing.
100fa1b3cPaul Dagnelie * See the License for the specific language governing permissions
110fa1b3cPaul Dagnelie * and limitations under the License.
120fa1b3cPaul Dagnelie *
130fa1b3cPaul Dagnelie * When distributing Covered Code, include this CDDL HEADER in each
140fa1b3cPaul Dagnelie * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150fa1b3cPaul Dagnelie * If applicable, add the following below this CDDL HEADER, with the
160fa1b3cPaul Dagnelie * fields enclosed by brackets "[]" replaced with your own identifying
170fa1b3cPaul Dagnelie * information: Portions Copyright [yyyy] [name of copyright owner]
180fa1b3cPaul Dagnelie *
190fa1b3cPaul Dagnelie * CDDL HEADER END
200fa1b3cPaul Dagnelie */
210fa1b3cPaul Dagnelie/*
220fa1b3cPaul Dagnelie * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
230fa1b3cPaul Dagnelie * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
240fa1b3cPaul Dagnelie * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
250fa1b3cPaul Dagnelie * Copyright (c) 2014, Joyent, Inc. All rights reserved.
260fa1b3cPaul Dagnelie * Copyright 2014 HybridCluster. All rights reserved.
270fa1b3cPaul Dagnelie * Copyright 2016 RackTop Systems.
280fa1b3cPaul Dagnelie * Copyright (c) 2014 Integros [integros.com]
290fa1b3cPaul Dagnelie */
300fa1b3cPaul Dagnelie
310fa1b3cPaul Dagnelie#include <sys/dmu.h>
320fa1b3cPaul Dagnelie#include <sys/dmu_impl.h>
330fa1b3cPaul Dagnelie#include <sys/dmu_tx.h>
340fa1b3cPaul Dagnelie#include <sys/dbuf.h>
350fa1b3cPaul Dagnelie#include <sys/dnode.h>
360fa1b3cPaul Dagnelie#include <sys/zfs_context.h>
370fa1b3cPaul Dagnelie#include <sys/dmu_objset.h>
380fa1b3cPaul Dagnelie#include <sys/dmu_traverse.h>
390fa1b3cPaul Dagnelie#include <sys/dsl_dataset.h>
400fa1b3cPaul Dagnelie#include <sys/dsl_dir.h>
410fa1b3cPaul Dagnelie#include <sys/dsl_prop.h>
420fa1b3cPaul Dagnelie#include <sys/dsl_pool.h>
430fa1b3cPaul Dagnelie#include <sys/dsl_synctask.h>
440fa1b3cPaul Dagnelie#include <sys/zfs_ioctl.h>
450fa1b3cPaul Dagnelie#include <sys/zap.h>
460fa1b3cPaul Dagnelie#include <sys/zio_checksum.h>
470fa1b3cPaul Dagnelie#include <sys/zfs_znode.h>
480fa1b3cPaul Dagnelie#include <zfs_fletcher.h>
490fa1b3cPaul Dagnelie#include <sys/avl.h>
500fa1b3cPaul Dagnelie#include <sys/ddt.h>
510fa1b3cPaul Dagnelie#include <sys/zfs_onexit.h>
520fa1b3cPaul Dagnelie#include <sys/dmu_recv.h>
530fa1b3cPaul Dagnelie#include <sys/dsl_destroy.h>
540fa1b3cPaul Dagnelie#include <sys/blkptr.h>
550fa1b3cPaul Dagnelie#include <sys/dsl_bookmark.h>
560fa1b3cPaul Dagnelie#include <sys/zfeature.h>
570fa1b3cPaul Dagnelie#include <sys/bqueue.h>
580fa1b3cPaul Dagnelie
590fa1b3cPaul Dagnelieint zfs_recv_queue_length = SPA_MAXBLOCKSIZE;
600fa1b3cPaul Dagnelie
610fa1b3cPaul Dagneliestatic char *dmu_recv_tag = "dmu_recv_tag";
620fa1b3cPaul Dagnelieconst char *recv_clone_name = "%recv";
630fa1b3cPaul Dagnelie
640fa1b3cPaul Dagneliestatic void byteswap_record(dmu_replay_record_t *drr);
650fa1b3cPaul Dagnelie
660fa1b3cPaul Dagnelietypedef struct dmu_recv_begin_arg {
670fa1b3cPaul Dagnelie	const char *drba_origin;
680fa1b3cPaul Dagnelie	dmu_recv_cookie_t *drba_cookie;
690fa1b3cPaul Dagnelie	cred_t *drba_cred;
70eb63303Tom Caputi	dsl_crypto_params_t *drba_dcp;
710fa1b3cPaul Dagnelie} dmu_recv_begin_arg_t;
720fa1b3cPaul Dagnelie
730fa1b3cPaul Dagneliestatic int
740fa1b3cPaul Dagnelierecv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
756ccda74loli    uint64_t fromguid, uint64_t featureflags)
760fa1b3cPaul Dagnelie{
770fa1b3cPaul Dagnelie	uint64_t val;
780fa1b3cPaul Dagnelie	int error;
790fa1b3cPaul Dagnelie	dsl_pool_t *dp = ds->ds_dir->dd_pool;
80eb63303Tom Caputi	boolean_t encrypted = ds->ds_dir->dd_crypto_obj != 0;
81eb63303Tom Caputi	boolean_t raw = (featureflags & DMU_BACKUP_FEATURE_RAW) != 0;
82eb63303Tom Caputi	boolean_t embed = (featureflags & DMU_BACKUP_FEATURE_EMBED_DATA) != 0;
830fa1b3cPaul Dagnelie
840fa1b3cPaul Dagnelie	/* temporary clone name must not exist */
850fa1b3cPaul Dagnelie	error = zap_lookup(dp->dp_meta_objset,
860fa1b3cPaul Dagnelie	    dsl_dir_phys(ds->ds_dir)->dd_child_dir_zapobj, recv_clone_name,
870fa1b3cPaul Dagnelie	    8, 1, &val);
880fa1b3cPaul Dagnelie	if (error != ENOENT)
890fa1b3cPaul Dagnelie		return (error == 0 ? EBUSY : error);
900fa1b3cPaul Dagnelie
910fa1b3cPaul Dagnelie	/* new snapshot name must not exist */
920fa1b3cPaul Dagnelie	error = zap_lookup(dp->dp_meta_objset,
930fa1b3cPaul Dagnelie	    dsl_dataset_phys(ds)->ds_snapnames_zapobj,
940fa1b3cPaul Dagnelie	    drba->drba_cookie->drc_tosnap, 8, 1, &val);
950fa1b3cPaul Dagnelie	if (error != ENOENT)
960fa1b3cPaul Dagnelie		return (error == 0 ? EEXIST : error);
970fa1b3cPaul Dagnelie
980fa1b3cPaul Dagnelie	/*
990fa1b3cPaul Dagnelie	 * Check snapshot limit before receiving. We'll recheck again at the
1000fa1b3cPaul Dagnelie	 * end, but might as well abort before receiving if we're already over
1010fa1b3cPaul Dagnelie	 * the limit.
1020fa1b3cPaul Dagnelie	 *
1030fa1b3cPaul Dagnelie	 * Note that we do not check the file system limit with
1040fa1b3cPaul Dagnelie	 * dsl_dir_fscount_check because the temporary %clones don't count
1050fa1b3cPaul Dagnelie	 * against that limit.
1060fa1b3cPaul Dagnelie	 */
1070fa1b3cPaul Dagnelie	error = dsl_fs_ss_limit_check(ds->ds_dir, 1, ZFS_PROP_SNAPSHOT_LIMIT,
1080fa1b3cPaul Dagnelie	    NULL, drba->drba_cred);
1090fa1b3cPaul Dagnelie	if (error != 0)
1100fa1b3cPaul Dagnelie		return (error);
1110fa1b3cPaul Dagnelie
1120fa1b3cPaul Dagnelie	if (fromguid != 0) {
1130fa1b3cPaul Dagnelie		dsl_dataset_t *snap;
1140fa1b3cPaul Dagnelie		uint64_t obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
1150fa1b3cPaul Dagnelie
116eb63303Tom Caputi		/* Can't raw receive on top of an unencrypted dataset */
117eb63303Tom Caputi		if (!encrypted && raw)
118eb63303Tom Caputi			return (SET_ERROR(EINVAL));
119eb63303Tom Caputi
120eb63303Tom Caputi		/* Encryption is incompatible with embedded data */
121eb63303Tom Caputi		if (encrypted && embed)
122eb63303Tom Caputi			return (SET_ERROR(EINVAL));
123eb63303Tom Caputi
1240fa1b3cPaul Dagnelie		/* Find snapshot in this dir that matches fromguid. */
1250fa1b3cPaul Dagnelie		while (obj != 0) {
1260fa1b3cPaul Dagnelie			error = dsl_dataset_hold_obj(dp, obj, FTAG,
1270fa1b3cPaul Dagnelie			    &snap);
1280fa1b3cPaul Dagnelie			if (error != 0)
1290fa1b3cPaul Dagnelie				return (SET_ERROR(ENODEV));
1300fa1b3cPaul Dagnelie			if (snap->ds_dir != ds->ds_dir) {
1310fa1b3cPaul Dagnelie				dsl_dataset_rele(snap, FTAG);
1320fa1b3cPaul Dagnelie				return (SET_ERROR(ENODEV));
1330fa1b3cPaul Dagnelie			}
1340fa1b3cPaul Dagnelie			if (dsl_dataset_phys(snap)->ds_guid == fromguid)
1350fa1b3cPaul Dagnelie				break;
1360fa1b3cPaul Dagnelie			obj = dsl_dataset_phys(snap)->ds_prev_snap_obj;
1370fa1b3cPaul Dagnelie			dsl_dataset_rele(snap, FTAG);
1380fa1b3cPaul Dagnelie		}
1390fa1b3cPaul Dagnelie		if (obj == 0)
1400fa1b3cPaul Dagnelie			return (SET_ERROR(ENODEV));
1410fa1b3cPaul Dagnelie
1420fa1b3cPaul Dagnelie		if (drba->drba_cookie->drc_force) {
143eb63303Tom Caputi			drba->drba_cookie->drc_fromsnapobj = obj;
1440fa1b3cPaul Dagnelie		} else {
1450fa1b3cPaul Dagnelie			/*
1460fa1b3cPaul Dagnelie			 * If we are not forcing, there must be no
1470fa1b3cPaul Dagnelie			 * changes since fromsnap.
1480fa1b3cPaul Dagnelie			 */
1490fa1b3cPaul Dagnelie			if (dsl_dataset_modified_since_snap(ds, snap)) {
1500fa1b3cPaul Dagnelie				dsl_dataset_rele(snap, FTAG);
1510fa1b3cPaul Dagnelie				return (SET_ERROR(ETXTBSY));
1520fa1b3cPaul Dagnelie			}
153eb63303Tom Caputi			drba->drba_cookie->drc_fromsnapobj =
154eb63303Tom Caputi			    ds->ds_prev->ds_object;
1550fa1b3cPaul Dagnelie		}
1560fa1b3cPaul Dagnelie
1570fa1b3cPaul Dagnelie		dsl_dataset_rele(snap, FTAG);
1580fa1b3cPaul Dagnelie	} else {
1590fa1b3cPaul Dagnelie		/* if full, then must be forced */
1600fa1b3cPaul Dagnelie		if (!drba->drba_cookie->drc_force)
1610fa1b3cPaul Dagnelie			return (SET_ERROR(EEXIST));
162eb63303Tom Caputi
163eb63303Tom Caputi		/*
164eb63303Tom Caputi		 * We don't support using zfs recv -F to blow away
165eb63303Tom Caputi		 * encrypted filesystems. This would require the
166eb63303Tom Caputi		 * dsl dir to point to the old encryption key and
167eb63303Tom Caputi		 * the new one at the same time during the receive.
168eb63303Tom Caputi		 */
169eb63303Tom Caputi		if ((!encrypted && raw) || encrypted)
170eb63303Tom Caputi			return (SET_ERROR(EINVAL));
171eb63303Tom Caputi
172eb63303Tom Caputi		/*
173eb63303Tom Caputi		 * Perform the same encryption checks we would if
174eb63303Tom Caputi		 * we were creating a new dataset from scratch.
175eb63303Tom Caputi		 */
176eb63303Tom Caputi		if (!raw) {
177eb63303Tom Caputi			boolean_t will_encrypt;
178eb63303Tom Caputi
179eb63303Tom Caputi			error = dmu_objset_create_crypt_check(
180eb63303Tom Caputi			    ds->ds_dir->dd_parent, drba->drba_dcp,
181eb63303Tom Caputi			    &will_encrypt);
182eb63303Tom Caputi			if (error != 0)
183eb63303Tom Caputi				return (error);
184eb63303Tom Caputi
185eb63303Tom Caputi			if (will_encrypt && embed)
186eb63303Tom Caputi				return (SET_ERROR(EINVAL));
187eb63303Tom Caputi		}
188eb63303Tom Caputi
189eb63303Tom Caputi		drba->drba_cookie->drc_fromsnapobj = 0;
1900fa1b3cPaul Dagnelie	}
1910fa1b3cPaul Dagnelie
1920fa1b3cPaul Dagnelie	return (0);
1930fa1b3cPaul Dagnelie
1940fa1b3cPaul Dagnelie}
1950fa1b3cPaul Dagnelie
1960fa1b3cPaul Dagneliestatic int
1970fa1b3cPaul Dagneliedmu_recv_begin_check(void *arg, dmu_tx_t *tx)
1980fa1b3cPaul Dagnelie{
1990fa1b3cPaul Dagnelie	dmu_recv_begin_arg_t *drba = arg;
2000fa1b3cPaul Dagnelie	dsl_pool_t *dp = dmu_tx_pool(tx);
2010fa1b3cPaul Dagnelie	struct drr_begin *drrb = drba->drba_cookie->drc_drrb;
2020fa1b3cPaul Dagnelie	uint64_t fromguid = drrb->drr_fromguid;
2030fa1b3cPaul Dagnelie	int flags = drrb->drr_flags;
204eb63303Tom Caputi	ds_hold_flags_t dsflags = 0;
2050fa1b3cPaul Dagnelie	int error;
2060fa1b3cPaul Dagnelie	uint64_t featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
2070fa1b3cPaul Dagnelie	dsl_dataset_t *ds;
2080fa1b3cPaul Dagnelie	const char *tofs = drba->drba_cookie->drc_tofs;
2090fa1b3cPaul Dagnelie
2100fa1b3cPaul Dagnelie	/* already checked */
2110fa1b3cPaul Dagnelie	ASSERT3U(drrb->drr_magic, ==, DMU_BACKUP_MAGIC);
2120fa1b3cPaul Dagnelie	ASSERT(!(featureflags & DMU_BACKUP_FEATURE_RESUMING));
2130fa1b3cPaul Dagnelie
2140fa1b3cPaul Dagnelie	if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
2150fa1b3cPaul Dagnelie	    DMU_COMPOUNDSTREAM ||
2160fa1b3cPaul Dagnelie	    drrb->drr_type >= DMU_OST_NUMTYPES ||
2170fa1b3cPaul Dagnelie	    ((flags & DRR_FLAG_CLONE) && drba->drba_origin == NULL))
2180fa1b3cPaul Dagnelie		return (SET_ERROR(EINVAL));
2190fa1b3cPaul Dagnelie
2200fa1b3cPaul Dagnelie	/* Verify pool version supports SA if SA_SPILL feature set */
2210fa1b3cPaul Dagnelie	if ((featureflags & DMU_BACKUP_FEATURE_SA_SPILL) &&
2220fa1b3cPaul Dagnelie	    spa_version(dp->dp_spa) < SPA_VERSION_SA)
2230fa1b3cPaul Dagnelie		return (SET_ERROR(ENOTSUP));
2240fa1b3cPaul Dagnelie
2250fa1b3cPaul Dagnelie	if (drba->drba_cookie->drc_resumable &&
2260fa1b3cPaul Dagnelie	    !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_EXTENSIBLE_DATASET))
2270fa1b3cPaul Dagnelie		return (SET_ERROR(ENOTSUP));
2280fa1b3cPaul Dagnelie
2290fa1b3cPaul Dagnelie	/*
2300fa1b3cPaul Dagnelie	 * The receiving code doesn't know how to translate a WRITE_EMBEDDED
2310fa1b3cPaul Dagnelie	 * record to a plain WRITE record, so the pool must have the
2320fa1b3cPaul Dagnelie	 * EMBEDDED_DATA feature enabled if the stream has WRITE_EMBEDDED
2330fa1b3cPaul Dagnelie	 * records.  Same with WRITE_EMBEDDED records that use LZ4 compression.
2340fa1b3cPaul Dagnelie	 */
2350fa1b3cPaul Dagnelie	if ((featureflags & DMU_BACKUP_FEATURE_EMBED_DATA) &&
2360fa1b3cPaul Dagnelie	    !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_EMBEDDED_DATA))
2370fa1b3cPaul Dagnelie		return (SET_ERROR(ENOTSUP));
2380fa1b3cPaul Dagnelie	if ((featureflags & DMU_BACKUP_FEATURE_LZ4) &&
2390fa1b3cPaul Dagnelie	    !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LZ4_COMPRESS))
2400fa1b3cPaul Dagnelie		return (SET_ERROR(ENOTSUP));
2410fa1b3cPaul Dagnelie
2420fa1b3cPaul Dagnelie	/*
2430fa1b3cPaul Dagnelie	 * The receiving code doesn't know how to translate large blocks
2440fa1b3cPaul Dagnelie	 * to smaller ones, so the pool must have the LARGE_BLOCKS
2450fa1b3cPaul Dagnelie	 * feature enabled if the stream has LARGE_BLOCKS. Same with
2460fa1b3cPaul Dagnelie	 * large dnodes.
2470fa1b3cPaul Dagnelie	 */
2480fa1b3cPaul Dagnelie	if ((featureflags & DMU_BACKUP_FEATURE_LARGE_BLOCKS) &&
2490fa1b3cPaul Dagnelie	    !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS))
2500fa1b3cPaul Dagnelie		return (SET_ERROR(ENOTSUP));
2510fa1b3cPaul Dagnelie	if ((featureflags & DMU_BACKUP_FEATURE_LARGE_DNODE) &&
2520fa1b3cPaul Dagnelie	    !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LARGE_DNODE))
2530fa1b3cPaul Dagnelie		return (SET_ERROR(ENOTSUP));
2540fa1b3cPaul Dagnelie
2556ccda74loli	if (featureflags & DMU_BACKUP_FEATURE_RAW) {
256eb63303Tom Caputi		/* raw receives require the encryption feature */
257eb63303Tom Caputi		if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_ENCRYPTION))
258eb63303Tom Caputi			return (SET_ERROR(ENOTSUP));
259eb63303Tom Caputi
260eb63303Tom Caputi		/* embedded data is incompatible with encryption and raw recv */
261eb63303Tom Caputi		if (featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)
262eb63303Tom Caputi			return (SET_ERROR(EINVAL));
263eb63303Tom Caputi
264eb63303Tom Caputi		/* raw receives require spill block allocation flag */
265eb63303Tom Caputi		if (!(flags & DRR_FLAG_SPILL_BLOCK))
266eb63303Tom Caputi			return (SET_ERROR(ZFS_ERR_SPILL_BLOCK_FLAG_MISSING));
267eb63303Tom Caputi	} else {
268eb63303Tom Caputi		dsflags |= DS_HOLD_FLAG_DECRYPT;
269eb63303Tom Caputi	}
270eb63303Tom Caputi
271eb63303Tom Caputi	error = dsl_dataset_hold_flags(dp, tofs, dsflags, FTAG, &ds);
2720fa1b3cPaul Dagnelie	if (error == 0) {
2730fa1b3cPaul Dagnelie		/* target fs already exists; recv into temp clone */
2740fa1b3cPaul Dagnelie
2750fa1b3cPaul Dagnelie		/* Can't recv a clone into an existing fs */
2760fa1b3cPaul Dagnelie		if (flags & DRR_FLAG_CLONE || drba->drba_origin) {
277eb63303Tom Caputi			dsl_dataset_rele_flags(ds, dsflags, FTAG);
2780fa1b3cPaul Dagnelie			return (SET_ERROR(EINVAL));
2790fa1b3cPaul Dagnelie		}
2800fa1b3cPaul Dagnelie
2816ccda74loli		error = recv_begin_check_existing_impl(drba, ds, fromguid,
2826ccda74loli		    featureflags);
283eb63303Tom Caputi		dsl_dataset_rele_flags(ds, dsflags, FTAG);
2840fa1b3cPaul Dagnelie	} else if (error == ENOENT) {
2850fa1b3cPaul Dagnelie		/* target fs does not exist; must be a full backup or clone */
2860fa1b3cPaul Dagnelie		char buf[ZFS_MAX_DATASET_NAME_LEN];
2870fa1b3cPaul Dagnelie
2880fa1b3cPaul Dagnelie		/*
2890fa1b3cPaul Dagnelie		 * If it's a non-clone incremental, we are missing the
2900fa1b3cPaul Dagnelie		 * target fs, so fail the recv.
2910fa1b3cPaul Dagnelie		 */
2920fa1b3cPaul Dagnelie		if (fromguid != 0 && !(flags & DRR_FLAG_CLONE ||
2930fa1b3cPaul Dagnelie		    drba->drba_origin))
2940fa1b3cPaul Dagnelie			return (SET_ERROR(ENOENT));
2950fa1b3cPaul Dagnelie
2960fa1b3cPaul Dagnelie		/*
2970fa1b3cPaul Dagnelie		 * If we're receiving a full send as a clone, and it doesn't
2980fa1b3cPaul Dagnelie		 * contain all the necessary free records and freeobject
2990fa1b3cPaul Dagnelie		 * records, reject it.
3000fa1b3cPaul Dagnelie		 */
3010fa1b3cPaul Dagnelie		if (fromguid == 0 && drba->drba_origin &&
3020fa1b3cPaul Dagnelie		    !(flags & DRR_FLAG_FREERECORDS))
3030fa1b3cPaul Dagnelie			return (SET_ERROR(EINVAL));
3040fa1b3cPaul Dagnelie
3050fa1b3cPaul Dagnelie		/* Open the parent of tofs */
3060fa1b3cPaul Dagnelie		ASSERT3U(strlen(tofs), <, sizeof (buf));
3070fa1b3cPaul Dagnelie		(void) strlcpy(buf, tofs, strrchr(tofs, '/') - tofs + 1);
308a60ca23Tom Caputi		error = dsl_dataset_hold(dp, buf, FTAG, &ds);
3090fa1b3cPaul Dagnelie		if (error != 0)
3100fa1b3cPaul Dagnelie			return (error);
3110fa1b3cPaul Dagnelie
312eb63303Tom Caputi		if ((featureflags & DMU_BACKUP_FEATURE_RAW) == 0 &&
313eb63303Tom Caputi		    drba->drba_origin == NULL) {
314eb63303Tom Caputi			boolean_t will_encrypt;
315eb63303Tom Caputi
316eb63303Tom Caputi			/*
317eb63303Tom Caputi			 * Check that we aren't breaking any encryption rules
318eb63303Tom Caputi			 * and that we have all the parameters we need to
319eb63303Tom Caputi			 * create an encrypted dataset if necessary. If we are
320eb63303Tom Caputi			 * making an encrypted dataset the stream can't have
321eb63303Tom Caputi			 * embedded data.
322eb63303Tom Caputi			 */
323eb63303Tom Caputi			error = dmu_objset_create_crypt_check(ds->ds_dir,
324eb63303Tom Caputi			    drba->drba_dcp, &will_encrypt);
325eb63303Tom Caputi			if (error != 0) {
326a60ca23Tom Caputi				dsl_dataset_rele(ds, FTAG);
327eb63303Tom Caputi				return (error);
328eb63303Tom Caputi			}
329eb63303Tom Caputi
330eb63303Tom Caputi			if (will_encrypt &&
331eb63303Tom Caputi			    (featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)) {
332a60ca23Tom Caputi				dsl_dataset_rele(ds, FTAG);
333eb63303Tom Caputi				return (SET_ERROR(EINVAL));
334eb63303Tom Caputi			}
335eb63303Tom Caputi		}
336eb63303Tom Caputi
3370fa1b3cPaul Dagnelie		/*
3380fa1b3cPaul Dagnelie		 * Check filesystem and snapshot limits before receiving. We'll
3390fa1b3cPaul Dagnelie		 * recheck snapshot limits again at the end (we create the
3400fa1b3cPaul Dagnelie		 * filesystems and increment those counts during begin_sync).
3410fa1b3cPaul Dagnelie		 */
3420fa1b3cPaul Dagnelie		error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
3430fa1b3cPaul Dagnelie		    ZFS_PROP_FILESYSTEM_LIMIT, NULL, drba->drba_cred);
3440fa1b3cPaul Dagnelie		if (error != 0) {
345a60ca23Tom Caputi			dsl_dataset_rele(ds, FTAG);
3460fa1b3cPaul Dagnelie			return (error);
3470fa1b3cPaul Dagnelie		}
3480fa1b3cPaul Dagnelie
3490fa1b3cPaul Dagnelie		error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
3500fa1b3cPaul Dagnelie		    ZFS_PROP_SNAPSHOT_LIMIT, NULL, drba->drba_cred);
3510fa1b3cPaul Dagnelie		if (error != 0) {
352a60ca23Tom Caputi			dsl_dataset_rele(ds, FTAG);
3530fa1b3cPaul Dagnelie			return (error);
3540fa1b3cPaul Dagnelie		}
3550fa1b3cPaul Dagnelie
3560fa1b3cPaul Dagnelie		if (drba->drba_origin != NULL) {
3570fa1b3cPaul Dagnelie			dsl_dataset_t *origin;
358eb63303Tom Caputi
359a60ca23Tom Caputi			error = dsl_dataset_hold(dp, drba->drba_origin,
360a60ca23Tom Caputi			    FTAG, &origin);
3610fa1b3cPaul Dagnelie			if (error != 0) {
362a60ca23Tom Caputi				dsl_dataset_rele(ds, FTAG);
3630fa1b3cPaul Dagnelie				return (error);
3640fa1b3cPaul Dagnelie			}
3650fa1b3cPaul Dagnelie			if (!origin->ds_is_snapshot) {
366a60ca23Tom Caputi				dsl_dataset_rele(origin, FTAG);
367a60ca23Tom Caputi				dsl_dataset_rele(ds, FTAG);
3680fa1b3cPaul Dagnelie				return (SET_ERROR(EINVAL));
3690fa1b3cPaul Dagnelie			}
3700fa1b3cPaul Dagnelie			if (dsl_dataset_phys(origin)->ds_guid != fromguid &&
3710fa1b3cPaul Dagnelie			    fromguid != 0) {
372a60ca23Tom Caputi				dsl_dataset_rele(origin, FTAG);
373a60ca23Tom Caputi				dsl_dataset_rele(ds, FTAG);
3740fa1b3cPaul Dagnelie				return (SET_ERROR(ENODEV));
3750fa1b3cPaul Dagnelie			}
376eb63303Tom Caputi			if (origin->ds_dir->dd_crypto_obj != 0 &&
377eb63303Tom Caputi			    (featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)) {
378a60ca23Tom Caputi				dsl_dataset_rele(origin, FTAG);
379a60ca23Tom Caputi				dsl_dataset_rele(ds, FTAG);
380eb63303Tom Caputi				return (SET_ERROR(EINVAL));
381eb63303Tom Caputi			}
382a60ca23Tom Caputi			dsl_dataset_rele(origin, FTAG);
3830fa1b3cPaul Dagnelie		}
384a60ca23Tom Caputi		dsl_dataset_rele(ds, FTAG);
3850fa1b3cPaul Dagnelie		error = 0;
3860fa1b3cPaul Dagnelie	}
3870fa1b3cPaul Dagnelie	return (error);
3880fa1b3cPaul Dagnelie}
3890fa1b3cPaul Dagnelie
3900fa1b3cPaul Dagneliestatic void
3910fa1b3cPaul Dagneliedmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
3920fa1b3cPaul Dagnelie{
3930fa1b3cPaul Dagnelie	dmu_recv_begin_arg_t *drba = arg;
3940fa1b3cPaul Dagnelie	dsl_pool_t *dp = dmu_tx_pool(tx);
3950fa1b3cPaul Dagnelie	objset_t *mos = dp->dp_meta_objset;
3960fa1b3cPaul Dagnelie	struct drr_begin *drrb = drba->drba_cookie->drc_drrb;
3970fa1b3cPaul Dagnelie	const char *tofs = drba->drba_cookie->drc_tofs;
398eb63303Tom Caputi	uint64_t featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
3990fa1b3cPaul Dagnelie	dsl_dataset_t *ds, *newds;
400eb63303Tom Caputi	objset_t *os;
4010fa1b3cPaul Dagnelie	uint64_t dsobj;
402eb63303Tom Caputi	ds_hold_flags_t dsflags = 0;
4030fa1b3cPaul Dagnelie	int error;
4040fa1b3cPaul Dagnelie	uint64_t crflags = 0;
405eb63303Tom Caputi	dsl_crypto_params_t dummy_dcp = { 0 };
406eb63303Tom Caputi	dsl_crypto_params_t *dcp = drba->drba_dcp;
4070fa1b3cPaul Dagnelie
4080fa1b3cPaul Dagnelie	if (drrb->drr_flags & DRR_FLAG_CI_DATA)
4090fa1b3cPaul Dagnelie		crflags |= DS_FLAG_CI_DATASET;
4106ccda74loli
411eb63303Tom Caputi	if ((featureflags & DMU_BACKUP_FEATURE_RAW) == 0)
412eb63303Tom Caputi		dsflags |= DS_HOLD_FLAG_DECRYPT;
413eb63303Tom Caputi
414eb63303Tom Caputi	/*
415eb63303Tom Caputi	 * Raw, non-incremental recvs always use a dummy dcp with
416eb63303Tom Caputi	 * the raw cmd set. Raw incremental recvs do not use a dcp
417eb63303Tom Caputi	 * since the encryption parameters are already set in stone.
418eb63303Tom Caputi	 */
419eb63303Tom Caputi	if (dcp == NULL && drba->drba_cookie->drc_fromsnapobj == 0 &&
420eb63303Tom Caputi	    drba->drba_origin == NULL) {
421eb63303Tom Caputi		ASSERT3P(dcp, ==, NULL);
422eb63303Tom Caputi		dcp = &dummy_dcp;
4230fa1b3cPaul Dagnelie
424eb63303Tom Caputi		if (featureflags & DMU_BACKUP_FEATURE_RAW)
425eb63303Tom Caputi			dcp->cp_cmd = DCP_CMD_RAW_RECV;
426eb63303Tom Caputi	}
427eb63303Tom Caputi
428eb63303Tom Caputi	error = dsl_dataset_hold_flags(dp, tofs, dsflags, FTAG, &ds);
4290fa1b3cPaul Dagnelie	if (error == 0) {
4300fa1b3cPaul Dagnelie		/* create temporary clone */
4310fa1b3cPaul Dagnelie		dsl_dataset_t *snap = NULL;
432eb63303Tom Caputi
433eb63303Tom Caputi		if (drba->drba_cookie->drc_fromsnapobj != 0) {
4340fa1b3cPaul Dagnelie			VERIFY0(dsl_dataset_hold_obj(dp,
435eb63303Tom Caputi			    drba->drba_cookie->drc_fromsnapobj, FTAG, &snap));
436eb63303Tom Caputi			ASSERT3P(dcp, ==, NULL);
4370fa1b3cPaul Dagnelie		}
438eb63303Tom Caputi
4390fa1b3cPaul Dagnelie		dsobj = dsl_dataset_create_sync(ds->ds_dir, recv_clone_name,
440eb63303Tom Caputi		    snap, crflags, drba->drba_cred, dcp, tx);
441eb63303Tom Caputi		if (drba->drba_cookie->drc_fromsnapobj != 0)
4420fa1b3cPaul Dagnelie			dsl_dataset_rele(snap, FTAG);
443eb63303Tom Caputi		dsl_dataset_rele_flags(ds, dsflags, FTAG);
4440fa1b3cPaul Dagnelie	} else {
4450fa1b3cPaul Dagnelie		dsl_dir_t *dd;
4460fa1b3cPaul Dagnelie		const char *tail;
4470fa1b3cPaul Dagnelie		dsl_dataset_t *origin = NULL;
4480fa1b3cPaul Dagnelie
4490fa1b3cPaul Dagnelie		VERIFY0(dsl_dir_hold(dp, tofs, FTAG, &dd, &tail));
4500fa1b3cPaul Dagnelie
4510fa1b3cPaul Dagnelie		if (drba->drba_origin != NULL) {
4520fa1b3cPaul Dagnelie			VERIFY0(dsl_dataset_hold(dp, drba->drba_origin,
4530fa1b3cPaul Dagnelie			    FTAG, &origin));
454eb63303Tom Caputi			ASSERT3P(dcp, ==, NULL);
4550fa1b3cPaul Dagnelie		}
4560fa1b3cPaul Dagnelie
4570fa1b3cPaul Dagnelie		/* Create new dataset. */
458eb63303Tom Caputi		dsobj = dsl_dataset_create_sync(dd, strrchr(tofs, '/') + 1,
459eb63303Tom Caputi		    origin, crflags, drba->drba_cred, dcp, tx);
4600fa1b3cPaul Dagnelie		if (origin != NULL)
4610fa1b3cPaul Dagnelie			dsl_dataset_rele(origin, FTAG);
4620fa1b3cPaul Dagnelie		dsl_dir_rele(dd, FTAG);
4630fa1b3cPaul Dagnelie		drba->drba_cookie->drc_newfs = B_TRUE;
4640fa1b3cPaul Dagnelie	}
465eb63303Tom Caputi
466eb63303Tom Caputi	VERIFY0(dsl_dataset_own_obj(dp, dsobj, dsflags, dmu_recv_tag, &newds));
467eb63303Tom Caputi	VERIFY0(dmu_objset_from_ds(newds, &os));
4680fa1b3cPaul Dagnelie
4690fa1b3cPaul Dagnelie	if (drba->drba_cookie->drc_resumable) {
4700fa1b3cPaul Dagnelie		dsl_dataset_zapify(newds, tx);
4710fa1b3cPaul Dagnelie		if (drrb->drr_fromguid != 0) {
4720fa1b3cPaul Dagnelie			VERIFY0(zap_add(mos, dsobj, DS_FIELD_RESUME_FROMGUID,
4730fa1b3cPaul Dagnelie			    8, 1, &drrb->drr_fromguid, tx));
4740fa1b3cPaul Dagnelie		}
4750fa1b3cPaul Dagnelie		VERIFY0(zap_add(mos, dsobj, DS_FIELD_RESUME_TOGUID,
4760fa1b3cPaul Dagnelie		    8, 1, &drrb->drr_toguid, tx));
4770fa1b3cPaul Dagnelie		VERIFY0(zap_add(mos, dsobj, DS_FIELD_RESUME_TONAME,
4780fa1b3cPaul Dagnelie		    1, strlen(drrb->drr_toname) + 1, drrb->drr_toname, tx));
4790fa1b3cPaul Dagnelie		uint64_t one = 1;
4800fa1b3cPaul Dagnelie		uint64_t zero = 0;
4810fa1b3cPaul Dagnelie		VERIFY0(zap_add(mos, dsobj, DS_FIELD_RESUME_OBJECT,
4820fa1b3cPaul Dagnelie		    8, 1, &one, tx));
4830fa1b3cPaul Dagnelie		VERIFY0(zap_add(mos, dsobj, DS_FIELD_RESUME_OFFSET,
4840fa1b3cPaul Dagnelie		    8, 1, &zero, tx));
4850fa1b3cPaul Dagnelie		VERIFY0(zap_add(mos, dsobj, DS_FIELD_RESUME_BYTES,
4860fa1b3cPaul Dagnelie		    8, 1, &zero, tx));
487eb63303Tom Caputi		if (featureflags & DMU_BACKUP_FEATURE_LARGE_BLOCKS) {
4880fa1b3cPaul Dagnelie			VERIFY0(zap_add(mos, dsobj, DS_FIELD_RESUME_LARGEBLOCK,
4890fa1b3cPaul Dagnelie			    8, 1, &one, tx));
4900fa1b3cPaul Dagnelie		}
491eb63303Tom Caputi		if (featureflags & DMU_BACKUP_FEATURE_EMBED_DATA) {
4920fa1b3cPaul Dagnelie			VERIFY0(zap_add(mos, dsobj, DS_FIELD_RESUME_EMBEDOK,
4930fa1b3cPaul Dagnelie			    8, 1, &one, tx));
4940fa1b3cPaul Dagnelie		}
495eb63303Tom Caputi		if (featureflags & DMU_BACKUP_FEATURE_COMPRESSED) {
4960fa1b3cPaul Dagnelie			VERIFY0(zap_add(mos, dsobj, DS_FIELD_RESUME_COMPRESSOK,
4970fa1b3cPaul Dagnelie			    8, 1, &one, tx));
498