summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Wilson <alex.wilson@joyent.com>2019-03-18 21:45:34 +0000
committerJason King <jason.king@joyent.com>2019-03-19 21:33:54 +0000
commit322170ab72e48b661407bc3c8028db0ad05f7d1a (patch)
tree9b8dec9023bc322111799032855bfc9fdb9769cc
parentadd9387c83ff72819a22b0601dc8ab93925640e0 (diff)
downloadillumos-joyent-zfs-crypto-demo.tar.gz
Allow child datasets to be created w/o encryptionzfs-crypto-demo
-rw-r--r--usr/src/lib/libzfs/common/libzfs.h4
-rw-r--r--usr/src/lib/libzfs/common/libzfs_crypto.c8
-rw-r--r--usr/src/lib/libzfs/common/libzfs_dataset.c2
-rw-r--r--usr/src/lib/libzfs/common/libzfs_pool.c4
-rw-r--r--usr/src/uts/common/fs/zfs/dmu_objset.c3
-rw-r--r--usr/src/uts/common/fs/zfs/dmu_send.c4
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_crypt.c9
-rw-r--r--usr/src/uts/common/fs/zfs/spa.c2
-rw-r--r--usr/src/uts/common/fs/zfs/sys/dsl_crypt.h2
-rw-r--r--usr/src/uts/common/fs/zfs/zio_crypt.c4
10 files changed, 27 insertions, 15 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h
index b72bc6029a..b44e876ac0 100644
--- a/usr/src/lib/libzfs/common/libzfs.h
+++ b/usr/src/lib/libzfs/common/libzfs.h
@@ -496,8 +496,8 @@ extern nvlist_t *zfs_get_clones_nvl(zfs_handle_t *);
* zfs encryption management
*/
extern int zfs_crypto_get_encryption_root(zfs_handle_t *, boolean_t *, char *);
-extern int zfs_crypto_create(libzfs_handle_t *, char *, nvlist_t *, nvlist_t *,
- uint8_t **, uint_t *);
+extern int zfs_crypto_create(libzfs_handle_t *, char *, zfs_type_t, nvlist_t *,
+ nvlist_t *, uint8_t **, uint_t *);
extern int zfs_crypto_clone_check(libzfs_handle_t *, zfs_handle_t *, char *,
nvlist_t *);
extern int zfs_crypto_attempt_load_keys(libzfs_handle_t *, char *);
diff --git a/usr/src/lib/libzfs/common/libzfs_crypto.c b/usr/src/lib/libzfs/common/libzfs_crypto.c
index 0c87346b37..f2f9dba216 100644
--- a/usr/src/lib/libzfs/common/libzfs_crypto.c
+++ b/usr/src/lib/libzfs/common/libzfs_crypto.c
@@ -718,8 +718,9 @@ zfs_crypto_get_encryption_root(zfs_handle_t *zhp, boolean_t *is_encroot,
}
int
-zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, nvlist_t *props,
- nvlist_t *pool_props, uint8_t **wkeydata_out, uint_t *wkeylen_out)
+zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, zfs_type_t type,
+ nvlist_t *props, nvlist_t *pool_props, uint8_t **wkeydata_out,
+ uint_t *wkeylen_out)
{
int ret;
char errbuf[1024];
@@ -792,7 +793,8 @@ zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, nvlist_t *props,
}
/* Check for encryption being explicitly truned off */
- if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF) {
+ if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF &&
+ type != ZFS_TYPE_VOLUME) {
ret = EINVAL;
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"Invalid encryption value. Dataset must be encrypted."));
diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c
index d7b5f5fe54..d1c19f748d 100644
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c
@@ -3664,7 +3664,7 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
}
(void) parent_name(path, parent, sizeof (parent));
- if (zfs_crypto_create(hdl, parent, props, NULL, &wkeydata,
+ if (zfs_crypto_create(hdl, parent, type, props, NULL, &wkeydata,
&wkeylen) != 0) {
nvlist_free(props);
return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c
index 5dae959248..0bf7497c10 100644
--- a/usr/src/lib/libzfs/common/libzfs_pool.c
+++ b/usr/src/lib/libzfs/common/libzfs_pool.c
@@ -1169,8 +1169,8 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
(nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
goto create_failed;
}
- if (zfs_crypto_create(hdl, NULL, zc_fsprops, props,
- &wkeydata, &wkeylen) != 0) {
+ if (zfs_crypto_create(hdl, NULL, ZFS_TYPE_FILESYSTEM,
+ zc_fsprops, props, &wkeydata, &wkeylen) != 0) {
(void) zfs_error(hdl, EZFS_CRYPTOFAILED, msg);
goto create_failed;
}
diff --git a/usr/src/uts/common/fs/zfs/dmu_objset.c b/usr/src/uts/common/fs/zfs/dmu_objset.c
index ff1bc972a4..06641a3e5b 100644
--- a/usr/src/uts/common/fs/zfs/dmu_objset.c
+++ b/usr/src/uts/common/fs/zfs/dmu_objset.c
@@ -1056,7 +1056,8 @@ dmu_objset_create_check(void *arg, dmu_tx_t *tx)
return (SET_ERROR(EEXIST));
}
- error = dmu_objset_create_crypt_check(pdd, doca->doca_dcp, NULL);
+ error = dmu_objset_create_crypt_check(pdd, doca->doca_dcp,
+ doca->doca_type, NULL);
if (error != 0) {
dsl_dir_rele(pdd, FTAG);
return (error);
diff --git a/usr/src/uts/common/fs/zfs/dmu_send.c b/usr/src/uts/common/fs/zfs/dmu_send.c
index b2ba3ac597..54e0526e5d 100644
--- a/usr/src/uts/common/fs/zfs/dmu_send.c
+++ b/usr/src/uts/common/fs/zfs/dmu_send.c
@@ -1612,6 +1612,7 @@ recv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
error = dmu_objset_create_crypt_check(
ds->ds_dir->dd_parent, drba->drba_dcp,
+ ds->ds_objset->os_phys->os_type,
&will_encrypt);
if (error != 0)
return (error);
@@ -1750,7 +1751,8 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
* embedded data.
*/
error = dmu_objset_create_crypt_check(ds->ds_dir,
- drba->drba_dcp, &will_encrypt);
+ drba->drba_dcp, ds->ds_objset->os_phys->os_type,
+ &will_encrypt);
if (error != 0) {
dsl_dataset_rele_flags(ds, dsflags, FTAG);
return (error);
diff --git a/usr/src/uts/common/fs/zfs/dsl_crypt.c b/usr/src/uts/common/fs/zfs/dsl_crypt.c
index 5e0b09cc3b..d11e3ff741 100644
--- a/usr/src/uts/common/fs/zfs/dsl_crypt.c
+++ b/usr/src/uts/common/fs/zfs/dsl_crypt.c
@@ -1755,7 +1755,7 @@ dmu_objset_clone_crypt_check(dsl_dir_t *parentdd, dsl_dir_t *origindd)
int
dmu_objset_create_crypt_check(dsl_dir_t *parentdd, dsl_crypto_params_t *dcp,
- boolean_t *will_encrypt)
+ dmu_objset_type_t type, boolean_t *will_encrypt)
{
int ret;
uint64_t pcrypt, crypt;
@@ -1785,9 +1785,12 @@ dmu_objset_create_crypt_check(dsl_dir_t *parentdd, dsl_crypto_params_t *dcp,
/*
* We can't create an unencrypted child of an encrypted parent
- * under any circumstances.
+ * except when it's a zvol. We allow this to support dump zvols
+ * on pools with encryption set at the top, until there is proper
+ * support for encrypted dump zvols.
*/
- if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF)
+ if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF &&
+ type != DMU_OST_ZVOL)
return (SET_ERROR(EINVAL));
/* check for valid dcp with no encryption (inherited or local) */
diff --git a/usr/src/uts/common/fs/zfs/spa.c b/usr/src/uts/common/fs/zfs/spa.c
index 89afe2511d..5ad58ba294 100644
--- a/usr/src/uts/common/fs/zfs/spa.c
+++ b/usr/src/uts/common/fs/zfs/spa.c
@@ -4622,7 +4622,7 @@ spa_create_check_encryption_params(dsl_crypto_params_t *dcp,
!has_encryption)
return (SET_ERROR(ENOTSUP));
- return (dmu_objset_create_crypt_check(NULL, dcp, NULL));
+ return (dmu_objset_create_crypt_check(NULL, dcp, DMU_OST_META, NULL));
}
/*
diff --git a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h
index 360a69b329..7502b6ce66 100644
--- a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h
+++ b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h
@@ -204,7 +204,7 @@ int dsl_dataset_promote_crypt_check(dsl_dir_t *target, dsl_dir_t *origin);
void dsl_dataset_promote_crypt_sync(dsl_dir_t *target, dsl_dir_t *origin,
dmu_tx_t *tx);
int dmu_objset_create_crypt_check(dsl_dir_t *parentdd,
- dsl_crypto_params_t *dcp, boolean_t *will_encrypt);
+ dsl_crypto_params_t *dcp, dmu_objset_type_t type, boolean_t *will_encrypt);
void dsl_dataset_create_crypt_sync(uint64_t dsobj, dsl_dir_t *dd,
struct dsl_dataset *origin, dsl_crypto_params_t *dcp, dmu_tx_t *tx);
uint64_t dsl_crypto_key_create_sync(uint64_t crypt, dsl_wrapping_key_t *wkey,
diff --git a/usr/src/uts/common/fs/zfs/zio_crypt.c b/usr/src/uts/common/fs/zfs/zio_crypt.c
index 55d2f682cc..be718d4ae0 100644
--- a/usr/src/uts/common/fs/zfs/zio_crypt.c
+++ b/usr/src/uts/common/fs/zfs/zio_crypt.c
@@ -1531,6 +1531,7 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
}
*no_crypt = (nr_iovecs == 0);
+ VERIFY(*no_crypt || total_len > 0);
*enc_len = total_len;
*authbuf = aadbuf;
*auth_len = aad_len;
@@ -1564,6 +1565,7 @@ error:
puio->uio_iovcnt = 0;
cuio->uio_iov = NULL;
cuio->uio_iovcnt = 0;
+ VERIFY3S(ret, !=, 0);
return (ret);
}
@@ -1924,6 +1926,8 @@ zio_do_crypt_data(boolean_t encrypt, zio_crypt_key_t *key,
/* perform the encryption / decryption */
ret = zio_do_crypt_uio(encrypt, key->zk_crypt, ckey, tmpl, iv, enc_len,
&puio, &cuio, authbuf, auth_len);
+ if (ret != 0 && no_crypt)
+ ret = 0;
if (ret != 0)
goto error;