diff options
author | Tom Caputi <[email protected]> | 2017-10-02 21:55:39 -0400 |
---|---|---|
committer | Tom Caputi <[email protected]> | 2017-10-11 16:57:22 -0400 |
commit | b135b9f11ad15823d92f8ca3f40fcdd91690677d (patch) | |
tree | 69a115e1bef06aaaec9da5f3824f94efcb773d8d /module/zfs/dsl_crypt.c | |
parent | 440a3eb939441a42ab5029e5e64498d802fa276b (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.c | 24 |
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)); |