Print this page
5610 zfs clone from different source and target pools produces coredump


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  24  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
  25  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  26  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.

  27  */
  28 
  29 /* Portions Copyright 2010 Robert Milkowski */
  30 
  31 #include <sys/cred.h>
  32 #include <sys/zfs_context.h>
  33 #include <sys/dmu_objset.h>
  34 #include <sys/dsl_dir.h>
  35 #include <sys/dsl_dataset.h>
  36 #include <sys/dsl_prop.h>
  37 #include <sys/dsl_pool.h>
  38 #include <sys/dsl_synctask.h>
  39 #include <sys/dsl_deleg.h>
  40 #include <sys/dnode.h>
  41 #include <sys/dbuf.h>
  42 #include <sys/zvol.h>
  43 #include <sys/dmu_tx.h>
  44 #include <sys/zap.h>
  45 #include <sys/zil.h>
  46 #include <sys/dmu_impl.h>


 888 static int
 889 dmu_objset_clone_check(void *arg, dmu_tx_t *tx)
 890 {
 891         dmu_objset_clone_arg_t *doca = arg;
 892         dsl_dir_t *pdd;
 893         const char *tail;
 894         int error;
 895         dsl_dataset_t *origin;
 896         dsl_pool_t *dp = dmu_tx_pool(tx);
 897 
 898         if (strchr(doca->doca_clone, '@') != NULL)
 899                 return (SET_ERROR(EINVAL));
 900 
 901         error = dsl_dir_hold(dp, doca->doca_clone, FTAG, &pdd, &tail);
 902         if (error != 0)
 903                 return (error);
 904         if (tail == NULL) {
 905                 dsl_dir_rele(pdd, FTAG);
 906                 return (SET_ERROR(EEXIST));
 907         }
 908         /* You can't clone across pools. */
 909         if (pdd->dd_pool != dp) {
 910                 dsl_dir_rele(pdd, FTAG);
 911                 return (SET_ERROR(EXDEV));
 912         }
 913         error = dsl_fs_ss_limit_check(pdd, 1, ZFS_PROP_FILESYSTEM_LIMIT, NULL,
 914             doca->doca_cred);
 915         if (error != 0) {
 916                 dsl_dir_rele(pdd, FTAG);
 917                 return (SET_ERROR(EDQUOT));
 918         }
 919         dsl_dir_rele(pdd, FTAG);
 920 
 921         error = dsl_dataset_hold(dp, doca->doca_origin, FTAG, &origin);
 922         if (error != 0)
 923                 return (error);
 924 
 925         /* You can't clone across pools. */
 926         if (origin->ds_dir->dd_pool != dp) {
 927                 dsl_dataset_rele(origin, FTAG);
 928                 return (SET_ERROR(EXDEV));
 929         }
 930 
 931         /* You can only clone snapshots, not the head datasets. */
 932         if (!origin->ds_is_snapshot) {
 933                 dsl_dataset_rele(origin, FTAG);
 934                 return (SET_ERROR(EINVAL));
 935         }
 936         dsl_dataset_rele(origin, FTAG);
 937 
 938         return (0);
 939 }
 940 
 941 static void
 942 dmu_objset_clone_sync(void *arg, dmu_tx_t *tx)
 943 {
 944         dmu_objset_clone_arg_t *doca = arg;
 945         dsl_pool_t *dp = dmu_tx_pool(tx);
 946         dsl_dir_t *pdd;
 947         const char *tail;
 948         dsl_dataset_t *origin, *ds;
 949         uint64_t obj;
 950         char namebuf[MAXNAMELEN];




   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  24  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
  25  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  26  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  27  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
  28  */
  29 
  30 /* Portions Copyright 2010 Robert Milkowski */
  31 
  32 #include <sys/cred.h>
  33 #include <sys/zfs_context.h>
  34 #include <sys/dmu_objset.h>
  35 #include <sys/dsl_dir.h>
  36 #include <sys/dsl_dataset.h>
  37 #include <sys/dsl_prop.h>
  38 #include <sys/dsl_pool.h>
  39 #include <sys/dsl_synctask.h>
  40 #include <sys/dsl_deleg.h>
  41 #include <sys/dnode.h>
  42 #include <sys/dbuf.h>
  43 #include <sys/zvol.h>
  44 #include <sys/dmu_tx.h>
  45 #include <sys/zap.h>
  46 #include <sys/zil.h>
  47 #include <sys/dmu_impl.h>


 889 static int
 890 dmu_objset_clone_check(void *arg, dmu_tx_t *tx)
 891 {
 892         dmu_objset_clone_arg_t *doca = arg;
 893         dsl_dir_t *pdd;
 894         const char *tail;
 895         int error;
 896         dsl_dataset_t *origin;
 897         dsl_pool_t *dp = dmu_tx_pool(tx);
 898 
 899         if (strchr(doca->doca_clone, '@') != NULL)
 900                 return (SET_ERROR(EINVAL));
 901 
 902         error = dsl_dir_hold(dp, doca->doca_clone, FTAG, &pdd, &tail);
 903         if (error != 0)
 904                 return (error);
 905         if (tail == NULL) {
 906                 dsl_dir_rele(pdd, FTAG);
 907                 return (SET_ERROR(EEXIST));
 908         }
 909 




 910         error = dsl_fs_ss_limit_check(pdd, 1, ZFS_PROP_FILESYSTEM_LIMIT, NULL,
 911             doca->doca_cred);
 912         if (error != 0) {
 913                 dsl_dir_rele(pdd, FTAG);
 914                 return (SET_ERROR(EDQUOT));
 915         }
 916         dsl_dir_rele(pdd, FTAG);
 917 
 918         error = dsl_dataset_hold(dp, doca->doca_origin, FTAG, &origin);
 919         if (error != 0)
 920                 return (error);
 921 






 922         /* You can only clone snapshots, not the head datasets. */
 923         if (!origin->ds_is_snapshot) {
 924                 dsl_dataset_rele(origin, FTAG);
 925                 return (SET_ERROR(EINVAL));
 926         }
 927         dsl_dataset_rele(origin, FTAG);
 928 
 929         return (0);
 930 }
 931 
 932 static void
 933 dmu_objset_clone_sync(void *arg, dmu_tx_t *tx)
 934 {
 935         dmu_objset_clone_arg_t *doca = arg;
 936         dsl_pool_t *dp = dmu_tx_pool(tx);
 937         dsl_dir_t *pdd;
 938         const char *tail;
 939         dsl_dataset_t *origin, *ds;
 940         uint64_t obj;
 941         char namebuf[MAXNAMELEN];