Skip to content

Commit

Permalink
Mixed raw receives update
Browse files Browse the repository at this point in the history
Squash this commit before merging.

Signed-off-by: Tom Caputi <[email protected]>
  • Loading branch information
Tom Caputi committed Mar 4, 2019
1 parent 6337e5f commit ffb7474
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 26 deletions.
11 changes: 6 additions & 5 deletions module/zfs/dmu_recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2815,11 +2815,12 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
/*
* If this is a raw receive, the crypt_keydata nvlist will include
* a to_ivset_guid for us to set on the new snapshot. This value
* will override the value generated by the snapshot code. Older
* implementations of the raw send code did not include this
* value. By setting the zfs_disable_ivset_guid_check tunable, the
* user can still receive these streams, using the generated value
* if one hasn't been provided.
* will override the value generated by the snapshot code. However,
* this value may not be present, because older implementations of
* the raw send code did not include this value, and we are still
* allowed to receive them if the zfs_disable_ivset_guid_check
* tunable is set, in which case we will leave the newly-generated
* value.
*/
if (drc->drc_raw && drc->drc_ivset_guid != 0) {
dmu_object_zapify(dp->dp_meta_objset, drc->drc_newsnapobj,
Expand Down
27 changes: 11 additions & 16 deletions module/zfs/dsl_crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1986,7 +1986,7 @@ dsl_crypto_recv_raw_objset_check(dsl_dataset_t *ds, dsl_dataset_t *fromds,
uint8_t *buf = NULL;
uint_t len;
uint64_t intval, nlevels, blksz, ibs;
uint64_t nblkptr, maxblkid, from_ivset_guid = 0;
uint64_t nblkptr, maxblkid;

if (ostype != DMU_OST_ZFS && ostype != DMU_OST_ZVOL)
return (SET_ERROR(EINVAL));
Expand Down Expand Up @@ -2061,18 +2061,19 @@ dsl_crypto_recv_raw_objset_check(dsl_dataset_t *ds, dsl_dataset_t *fromds,
* zfs_disable_ivset_guid_check tunable to allow these datasets to
* be received with a generated ivset guid.
*/
if (fromds != NULL) {
if (fromds != NULL && !zfs_disable_ivset_guid_check) {
uint64_t from_ivset_guid = 0;
intval = 0;

(void) nvlist_lookup_uint64(nvl, "from_ivset_guid", &intval);
(void) zap_lookup(tx->tx_pool->dp_meta_objset,
fromds->ds_object, DS_FIELD_IVSET_GUID,
sizeof (from_ivset_guid), 1, &from_ivset_guid);

if (!zfs_disable_ivset_guid_check &&
(intval == 0 || from_ivset_guid == 0))
if (intval == 0 || from_ivset_guid == 0)
return (SET_ERROR(ZFS_ERR_FROM_IVSET_GUID_MISSING));

if (!zfs_disable_ivset_guid_check && intval != from_ivset_guid)
if (intval != from_ivset_guid)
return (SET_ERROR(ZFS_ERR_FROM_IVSET_GUID_MISMATCH));
}

Expand Down Expand Up @@ -2332,19 +2333,19 @@ dsl_crypto_recv_key_check(void *arg, dmu_tx_t *tx)
ret = dsl_dataset_hold_obj(tx->tx_pool, dcrka->dcrka_dsobj,
FTAG, &ds);
if (ret != 0)
goto error;
goto out;

if (dcrka->dcrka_fromobj != 0) {
ret = dsl_dataset_hold_obj(tx->tx_pool, dcrka->dcrka_fromobj,
FTAG, &fromds);
if (ret != 0)
goto error;
goto out;
}

ret = dsl_crypto_recv_raw_objset_check(ds, fromds,
dcrka->dcrka_ostype, dcrka->dcrka_nvl, tx);
if (ret != 0)
goto error;
goto out;

/*
* We run this check even if we won't be doing this part of
Expand All @@ -2353,15 +2354,9 @@ dsl_crypto_recv_key_check(void *arg, dmu_tx_t *tx)
*/
ret = dsl_crypto_recv_raw_key_check(ds, dcrka->dcrka_nvl, tx);
if (ret != 0)
goto error;

dsl_dataset_rele(ds, FTAG);
if (fromds != NULL)
dsl_dataset_rele(fromds, FTAG);

return (0);
goto out;

error:
out:
if (ds != NULL)
dsl_dataset_rele(ds, FTAG);
if (fromds != NULL)
Expand Down
14 changes: 12 additions & 2 deletions module/zfs/dsl_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1711,8 +1711,18 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname,

/*
* Create a ivset guid for this snapshot if the dataset is
* encrypted. This may be overridden by a raw receive. We
* only do this if the bookmark_v2 feature is enabled.
* encrypted. This may be overridden by a raw receive. A
* previous implementation of this code did not have this
* field as part of the on-disk format for ZFS encryption
* (see errata #4). As part of the remediation for this
* issue, we ask the user to enable the bookmark_v2 feature
* which is now a dependency of the encryption feature. We
* use this as a heuristic to determine when the user has
* elected to correct any datasets created with the old code.
* As a result, we only do this step if the bookmark_v2
* feature is enabled, which limits the number of states a
* given pool / dataset can be in with regards to terms of
* correcting the issue.
*/
if (ds->ds_dir->dd_crypto_obj != 0 &&
spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_BOOKMARK_V2)) {
Expand Down
10 changes: 7 additions & 3 deletions module/zfs/zcp_get.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,13 @@ get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname,
numval = dsl_get_inconsistent(ds);
break;
case ZFS_PROP_IVSET_GUID:
error = zap_lookup(ds->ds_dir->dd_pool->dp_meta_objset,
ds->ds_object, DS_FIELD_IVSET_GUID, sizeof (numval),
1, &numval);
if (dsl_dataset_is_zapified(ds)) {
error = zap_lookup(ds->ds_dir->dd_pool->dp_meta_objset,
ds->ds_object, DS_FIELD_IVSET_GUID,
sizeof (numval), 1, &numval);
} else {
error = ENOENT;
}
break;
case ZFS_PROP_RECEIVE_RESUME_TOKEN: {
char *token = get_receive_resume_stats_impl(ds);
Expand Down

0 comments on commit ffb7474

Please sign in to comment.