]> granicus.if.org Git - zfs/commitdiff
Fix for #6703
authorTom Caputi <tcaputi@datto.com>
Tue, 3 Oct 2017 01:55:39 +0000 (21:55 -0400)
committerTom Caputi <tcaputi@datto.com>
Wed, 11 Oct 2017 20:57:22 +0000 (16:57 -0400)
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 <tcaputi@datto.com>
module/zfs/dsl_crypt.c

index 3c2babfda877738900a8d21fb0bf6385ea6b9ec3..3dcdde4d07951c2761ad139e71cd173e3fd983a3 100644 (file)
@@ -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));