aboutsummaryrefslogtreecommitdiffstats
path: root/lib/libzfs/libzfs_sendrecv.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libzfs/libzfs_sendrecv.c')
-rw-r--r--lib/libzfs/libzfs_sendrecv.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c
index 9ac2a9026..c850c8ba6 100644
--- a/lib/libzfs/libzfs_sendrecv.c
+++ b/lib/libzfs/libzfs_sendrecv.c
@@ -3832,6 +3832,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
if (zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
zfs_cmd_t zc = {"\0"};
zfs_handle_t *zhp;
+ boolean_t encrypted;
(void) strcpy(zc.zc_name, name);
@@ -3879,24 +3880,36 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
}
/*
- * zfs recv -F cant be used to blow away an existing
- * encrypted filesystem. This is because it would require
- * the dsl dir to point to the the new key (or lack of a
- * key) and the old key at the same time. The -F flag may
- * still be used for deleting intermediate snapshots that
- * would otherwise prevent the receive from working.
+ * Raw sends can not be performed as an incremental on top
+ * of existing unencryppted datasets. zfs recv -F cant be
+ * used to blow away an existing encrypted filesystem. This
+ * is because it would require the dsl dir to point to the
+ * new key (or lack of a key) and the old key at the same
+ * time. The -F flag may still be used for deleting
+ * intermediate snapshots that would otherwise prevent the
+ * receive from working.
*/
- if (stream_wantsnewfs && flags->force &&
- zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) !=
- ZIO_CRYPT_OFF) {
+ encrypted = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) !=
+ ZIO_CRYPT_OFF;
+ if (!stream_wantsnewfs && !encrypted && raw) {
zfs_close(zhp);
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "zfs receive -F cannot be used to "
- "destroy an encrypted filesystem"));
+ "cannot perform raw receive on top of "
+ "existing unencrypted dataset"));
err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
goto out;
}
+ if (stream_wantsnewfs && flags->force &&
+ ((raw && !encrypted) || encrypted)) {
+ zfs_close(zhp);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "zfs receive -F cannot be used to destroy an "
+ "encrypted filesystem or overwrite an "
+ "unencrypted one with an encrypted one"));
+ err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
+ goto out;
+ }
if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
stream_wantsnewfs) {