Print this page
3973 zfs_ioc_rename alters passed in zc->zc_name
Reviewed by: Matthew Ahrens <mahrens@delphix.com>

@@ -3550,22 +3550,29 @@
                 return (SET_ERROR(EINVAL));
 
         at = strchr(zc->zc_name, '@');
         if (at != NULL) {
                 /* snaps must be in same fs */
+                int error;
+
                 if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
                         return (SET_ERROR(EXDEV));
                 *at = '\0';
                 if (zc->zc_objset_type == DMU_OST_ZFS) {
-                        int error = dmu_objset_find(zc->zc_name,
+                        error = dmu_objset_find(zc->zc_name,
                             recursive_unmount, at + 1,
                             recursive ? DS_FIND_CHILDREN : 0);
-                        if (error != 0)
+                        if (error != 0) {
+                                *at = '@';
                                 return (error);
                 }
-                return (dsl_dataset_rename_snapshot(zc->zc_name,
-                    at + 1, strchr(zc->zc_value, '@') + 1, recursive));
+                }
+                error = dsl_dataset_rename_snapshot(zc->zc_name,
+                    at + 1, strchr(zc->zc_value, '@') + 1, recursive);
+                *at = '@';
+
+                return (error);
         } else {
                 if (zc->zc_objset_type == DMU_OST_ZVOL)
                         (void) zvol_remove_minor(zc->zc_name);
                 return (dsl_dir_rename(zc->zc_name, zc->zc_value));
         }