From b135b9f11ad15823d92f8ca3f40fcdd91690677d Mon Sep 17 00:00:00 2001 From: Tom Caputi Date: Mon, 2 Oct 2017 21:55:39 -0400 Subject: [PATCH] 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 --- module/zfs/dsl_crypt.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c index 3c2babfda8..3dcdde4d07 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));