]> granicus.if.org Git - zfs/commitdiff
Fix error message on promoting encrypted dataset
authorTom Caputi <tcaputi@datto.com>
Mon, 24 Jun 2019 23:42:52 +0000 (19:42 -0400)
committerTony Hutter <hutter2@llnl.gov>
Wed, 25 Sep 2019 18:27:48 +0000 (11:27 -0700)
This patch corrects the error message reported when attempting
to promote a dataset outside of its encryption root.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #8905
Closes #8935

lib/libzfs/libzfs_dataset.c
module/zfs/dsl_crypt.c

index ee5a6412ead5000c575f7eaeaed2278c5e89b29a..0d0194e68453615ff38e7c2b6ca668c989969e9c 100644 (file)
@@ -4117,6 +4117,16 @@ zfs_promote(zfs_handle_t *zhp)
 
        if (ret != 0) {
                switch (ret) {
+               case EACCES:
+                       /*
+                        * Promoting encrypted dataset outside its
+                        * encryption root.
+                        */
+                       zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+                           "cannot promote dataset outside its "
+                           "encryption root"));
+                       return (zfs_error(hdl, EZFS_EXISTS, errbuf));
+
                case EEXIST:
                        /* There is a conflicting snapshot name. */
                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
index 0c0ffaadd8fb2bc1ce361e5e9d20ae29c17fe0c9..568fe7aa32638c29621aa4def2dfd234c7094aec 100644 (file)
@@ -1676,11 +1676,15 @@ dsl_dataset_promote_crypt_check(dsl_dir_t *target, dsl_dir_t *origin)
         * Check that the parent of the target has the same encryption root.
         */
        ret = dsl_dir_get_encryption_root_ddobj(origin->dd_parent, &op_rddobj);
-       if (ret != 0)
+       if (ret == ENOENT)
+               return (SET_ERROR(EACCES));
+       else if (ret != 0)
                return (ret);
 
        ret = dsl_dir_get_encryption_root_ddobj(target->dd_parent, &tp_rddobj);
-       if (ret != 0)
+       if (ret == ENOENT)
+               return (SET_ERROR(EACCES));
+       else if (ret != 0)
                return (ret);
 
        if (op_rddobj != tp_rddobj)