@@ -766,6 +766,26 @@ finish_progress(const char *done)
766766 pt_header = NULL ;
767767}
768768
769+ static void
770+ makeprops_parents (nvlist_t * * ptr , boolean_t parents_nomount )
771+ {
772+ nvlist_t * props = NULL ;
773+
774+ if (parents_nomount ) {
775+ if (nvlist_alloc (& props , NV_UNIQUE_NAME , 0 ) != 0 )
776+ nomem ();
777+
778+ if (nvlist_add_string (props ,
779+ zfs_prop_to_name (ZFS_PROP_CANMOUNT ),
780+ "off" ) != 0 ) {
781+ nvlist_free (props );
782+ nomem ();
783+ }
784+ }
785+
786+ * ptr = props ;
787+ }
788+
769789static int
770790zfs_mount_and_share (libzfs_handle_t * hdl , const char * dataset , zfs_type_t type )
771791{
@@ -826,13 +846,16 @@ zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type)
826846 * the clone exists.
827847 *
828848 * The '-p' flag creates all the non-existing ancestors of the target first.
849+ * If repeated twice, the ancestors are created with `canmount=off`.
829850 */
830851static int
831852zfs_do_clone (int argc , char * * argv )
832853{
833854 zfs_handle_t * zhp = NULL ;
834855 boolean_t parents = B_FALSE ;
856+ boolean_t parents_nomount = B_FALSE ;
835857 nvlist_t * props ;
858+ nvlist_t * props_parents = NULL ;
836859 int ret = 1 ;
837860 int c ;
838861
@@ -849,7 +872,10 @@ zfs_do_clone(int argc, char **argv)
849872 }
850873 break ;
851874 case 'p' :
852- parents = B_TRUE ;
875+ if (!parents )
876+ parents = B_TRUE ;
877+ else
878+ parents_nomount = B_TRUE ;
853879 break ;
854880 case '?' :
855881 (void ) fprintf (stderr , gettext ("invalid option '%c'\n" ),
@@ -894,9 +920,11 @@ zfs_do_clone(int argc, char **argv)
894920 ret = 0 ;
895921 goto error ;
896922 }
897- if (zfs_create_ancestors (g_zfs , argv [1 ]) != 0 ) {
923+
924+ makeprops_parents (& props_parents , parents_nomount );
925+ if (zfs_create_ancestors (g_zfs , argv [1 ],
926+ props_parents ) != 0 )
898927 goto error ;
899- }
900928 }
901929
902930 /* pass to libzfs */
@@ -921,11 +949,13 @@ zfs_do_clone(int argc, char **argv)
921949 zfs_close (zhp );
922950error_open :
923951 nvlist_free (props );
952+ nvlist_free (props_parents );
924953 return (!!ret );
925954
926955usage :
927956 ASSERT0P (zhp );
928957 nvlist_free (props );
958+ nvlist_free (props_parents );
929959 usage (B_FALSE );
930960 return (-1 );
931961}
@@ -1059,6 +1089,7 @@ default_volblocksize(zpool_handle_t *zhp, nvlist_t *props)
10591089 * SPA_VERSION_REFRESERVATION, we set a refreservation instead.
10601090 *
10611091 * The '-p' flag creates all the non-existing ancestors of the target first.
1092+ * If repeated twice, the ancestors are created with `canmount=off`.
10621093 *
10631094 * The '-n' flag is no-op (dry run) mode. This will perform a user-space sanity
10641095 * check of arguments and properties, but does not check for permissions,
@@ -1081,12 +1112,14 @@ zfs_do_create(int argc, char **argv)
10811112 boolean_t noreserve = B_FALSE ;
10821113 boolean_t bflag = B_FALSE ;
10831114 boolean_t parents = B_FALSE ;
1115+ boolean_t parents_nomount = B_FALSE ;
10841116 boolean_t dryrun = B_FALSE ;
10851117 boolean_t nomount = B_FALSE ;
10861118 boolean_t verbose = B_FALSE ;
10871119 boolean_t parseable = B_FALSE ;
10881120 int ret = 1 ;
10891121 nvlist_t * props ;
1122+ nvlist_t * props_parents = NULL ;
10901123 uint64_t intval ;
10911124 const char * strval ;
10921125
@@ -1115,7 +1148,10 @@ zfs_do_create(int argc, char **argv)
11151148 parseable = B_TRUE ;
11161149 break ;
11171150 case 'p' :
1118- parents = B_TRUE ;
1151+ if (!parents )
1152+ parents = B_TRUE ;
1153+ else
1154+ parents_nomount = B_TRUE ;
11191155 break ;
11201156 case 'b' :
11211157 bflag = B_TRUE ;
@@ -1265,6 +1301,8 @@ zfs_do_create(int argc, char **argv)
12651301 }
12661302
12671303 if (parents && zfs_name_valid (argv [0 ], type )) {
1304+ makeprops_parents (& props_parents , parents_nomount );
1305+
12681306 /*
12691307 * Now create the ancestors of target dataset. If the target
12701308 * already exists and '-p' option was used we should not
@@ -1280,7 +1318,8 @@ zfs_do_create(int argc, char **argv)
12801318 "create ancestors of %s\n" , argv [0 ]);
12811319 }
12821320 if (!dryrun ) {
1283- if (zfs_create_ancestors (g_zfs , argv [0 ]) != 0 ) {
1321+ if (zfs_create_ancestors (g_zfs , argv [0 ],
1322+ props_parents ) != 0 ) {
12841323 goto error ;
12851324 }
12861325 }
@@ -1339,9 +1378,11 @@ zfs_do_create(int argc, char **argv)
13391378 (void ) zfs_mount_and_share (g_zfs , argv [0 ], ZFS_TYPE_DATASET );
13401379error :
13411380 nvlist_free (props );
1381+ nvlist_free (props_parents );
13421382 return (ret );
13431383badusage :
13441384 nvlist_free (props );
1385+ nvlist_free (props_parents );
13451386 usage (B_FALSE );
13461387 return (2 );
13471388}
@@ -4036,6 +4077,8 @@ found3:;
40364077 * Renames the given dataset to another of the same type.
40374078 *
40384079 * The '-p' flag creates all the non-existing ancestors of the target first.
4080+ * If repeated twice, the ancestors are created with `canmount=off`.
4081+ *
40394082 * The '-u' flag prevents file systems from being remounted during rename.
40404083 */
40414084static int
@@ -4047,12 +4090,17 @@ zfs_do_rename(int argc, char **argv)
40474090 int ret = 1 ;
40484091 int types ;
40494092 boolean_t parents = B_FALSE ;
4093+ boolean_t parents_nomount = B_FALSE ;
4094+ nvlist_t * props_parents = NULL ;
40504095
40514096 /* check options */
40524097 while ((c = getopt (argc , argv , "pruf" )) != -1 ) {
40534098 switch (c ) {
40544099 case 'p' :
4055- parents = B_TRUE ;
4100+ if (parents )
4101+ parents_nomount = B_TRUE ;
4102+ else
4103+ parents = B_TRUE ;
40564104 break ;
40574105 case 'r' :
40584106 flags .recursive = B_TRUE ;
@@ -4119,16 +4167,21 @@ zfs_do_rename(int argc, char **argv)
41194167 goto error_open ;
41204168
41214169 /* If we were asked and the name looks good, try to create ancestors. */
4122- if (parents && zfs_name_valid (argv [1 ], zfs_get_type (zhp )) &&
4123- zfs_create_ancestors (g_zfs , argv [1 ]) != 0 ) {
4124- goto error ;
4170+ if (parents && zfs_name_valid (argv [1 ], zfs_get_type (zhp ))) {
4171+
4172+ makeprops_parents (& props_parents , parents_nomount );
4173+ if (zfs_create_ancestors (g_zfs , argv [1 ],
4174+ props_parents ) != 0 ) {
4175+ goto error ;
4176+ }
41254177 }
41264178
41274179 ret = (zfs_rename (zhp , argv [1 ], flags ) != 0 );
41284180
41294181error :
41304182 zfs_close (zhp );
41314183error_open :
4184+ nvlist_free (props_parents );
41324185 return (ret );
41334186}
41344187
0 commit comments