summaryrefslogtreecommitdiffstats
path: root/module/zfs/dsl_crypt.c
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2017-10-02 21:55:39 -0400
committerTom Caputi <[email protected]>2017-10-11 16:57:22 -0400
commitb135b9f11ad15823d92f8ca3f40fcdd91690677d (patch)
tree69a115e1bef06aaaec9da5f3824f94efcb773d8d /module/zfs/dsl_crypt.c
parent440a3eb939441a42ab5029e5e64498d802fa276b (diff)
Fix for #6703
This patch resolves an issue where spa_keystore_change_key_sync_impl() incorrectly recursed into clone DSL Directories while recursively rewrapping encryption keys. Clones share keys with their origins, so this logic was incorrect. Signed-off-by: Tom Caputi <[email protected]>
Diffstat (limited to 'module/zfs/dsl_crypt.c')
-rw-r--r--module/zfs/dsl_crypt.c24
1 files changed, 6 insertions, 18 deletions
diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c
index 3c2babfda..3dcdde4d0 100644
--- a/module/zfs/dsl_crypt.c
+++ b/module/zfs/dsl_crypt.c
@@ -1321,10 +1321,12 @@ spa_keystore_change_key_sync_impl(uint64_t rddobj, uint64_t ddobj,
return;
}
- /* stop recursing if this dsl dir didn't inherit from the root */
+ /*
+ * Stop recursing if this dsl dir didn't inherit from the root
+ * or if this dd is a clone.
+ */
VERIFY0(dsl_dir_get_encryption_root_ddobj(dd, &curr_rddobj));
-
- if (curr_rddobj != rddobj) {
+ if (curr_rddobj != rddobj || dsl_dir_is_clone(dd)) {
dsl_dir_rele(dd, FTAG);
return;
}
@@ -1350,7 +1352,7 @@ spa_keystore_change_key_sync_impl(uint64_t rddobj, uint64_t ddobj,
zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
- /* Recurse into all child and clone dsl dirs. */
+ /* Recurse into all child dsl dirs. */
for (zap_cursor_init(zc, dp->dp_meta_objset,
dsl_dir_phys(dd)->dd_child_dir_zapobj);
zap_cursor_retrieve(zc, za) == 0;
@@ -1360,20 +1362,6 @@ spa_keystore_change_key_sync_impl(uint64_t rddobj, uint64_t ddobj,
}
zap_cursor_fini(zc);
- for (zap_cursor_init(zc, dp->dp_meta_objset,
- dsl_dir_phys(dd)->dd_clones);
- zap_cursor_retrieve(zc, za) == 0;
- zap_cursor_advance(zc)) {
- dsl_dataset_t *clone;
-
- VERIFY0(dsl_dataset_hold_obj(dp,
- za->za_first_integer, FTAG, &clone));
- spa_keystore_change_key_sync_impl(rddobj,
- clone->ds_dir->dd_object, new_rddobj, wkey, tx);
- dsl_dataset_rele(clone, FTAG);
- }
- zap_cursor_fini(zc);
-
kmem_free(za, sizeof (zap_attribute_t));
kmem_free(zc, sizeof (zap_cursor_t));