@@ -307,7 +307,8 @@ get_usage(zfs_help_t idx)
307
307
"[filesystem|volume|snapshot] ...\n" ));
308
308
case HELP_MOUNT :
309
309
return (gettext ("\tmount\n"
310
- "\tmount [-flvO] [-o opts] -r <-a | filesystem>\n" ));
310
+ "\tmount [-flvO] [-o opts] [-r filesystem] "
311
+ "<-a [filesystem] | filesystem>\n" ));
311
312
case HELP_PROMOTE :
312
313
return (gettext ("\tpromote <clone-filesystem>\n" ));
313
314
case HELP_RECEIVE :
@@ -6731,7 +6732,7 @@ zfs_do_holds(int argc, char **argv)
6731
6732
typedef struct get_all_state {
6732
6733
boolean_t ga_verbose ;
6733
6734
get_all_cb_t * ga_cbp ;
6734
- const char * ga_dataset ;
6735
+ const char * ga_filesystem ;
6735
6736
} get_all_state_t ;
6736
6737
6737
6738
static int
@@ -6772,12 +6773,31 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
6772
6773
}
6773
6774
6774
6775
/*
6775
- * Skip any dataset whos name doesn't have a prefix matching ga_dataset.
6776
+ * Check if ga_filesystem is set; used for recursive mounting
6776
6777
*/
6777
- if (state -> ga_dataset != NULL && strncmp (zfs_get_name (zhp ),
6778
- state -> ga_dataset , strlen (state -> ga_dataset )) != 0 ) {
6779
- zfs_close (zhp );
6780
- return (0 );
6778
+ if (state -> ga_filesystem != NULL ) {
6779
+ /*
6780
+ * Skip any dataset with the canmount=off property.
6781
+ */
6782
+ if (zfs_prop_get_int (zhp , ZFS_PROP_CANMOUNT ) == ZFS_CANMOUNT_OFF ) {
6783
+ zfs_close (zhp );
6784
+ return (0 );
6785
+ }
6786
+
6787
+ /* Add a trailing / to ga_filesystem */
6788
+ char filesystem [strlen (state -> ga_filesystem ) + 2 ];
6789
+ strcpy (filesystem , state -> ga_filesystem );
6790
+ strcat (filesystem , "/" );
6791
+
6792
+ /*
6793
+ * Skip any dataset whose name doesn't match ga_filesystem exactly
6794
+ * or have a prefix matching filesystem.
6795
+ */
6796
+ if (!strcmp (zfs_get_name (zhp ), state -> ga_filesystem ) == 0 ||
6797
+ !strncmp (zfs_get_name (zhp ), filesystem , strlen (filesystem ) == 0 )) {
6798
+ zfs_close (zhp );
6799
+ return (0 );
6800
+ }
6781
6801
}
6782
6802
6783
6803
libzfs_add_handle (state -> ga_cbp , zhp );
@@ -6787,12 +6807,12 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
6787
6807
}
6788
6808
6789
6809
static void
6790
- get_all_datasets (get_all_cb_t * cbp , boolean_t verbose , const char * dataset )
6810
+ get_all_datasets (get_all_cb_t * cbp , boolean_t verbose , const char * filesystem )
6791
6811
{
6792
6812
get_all_state_t state = {
6793
6813
.ga_verbose = verbose ,
6794
6814
.ga_cbp = cbp ,
6795
- .ga_dataset = dataset
6815
+ .ga_filesystem = filesystem
6796
6816
};
6797
6817
6798
6818
if (verbose )
@@ -6820,7 +6840,8 @@ typedef struct share_mount_state {
6820
6840
uint_t sm_total ; /* number of filesystems to process */
6821
6841
uint_t sm_done ; /* number of filesystems processed */
6822
6842
int sm_status ; /* -1 if any of the share/mount operations failed */
6823
- boolean_t sm_explicit ;
6843
+ boolean_t sm_explicit ; /* true if filesystems were explictly requested,
6844
+ false if they are implied by `-a` */
6824
6845
} share_mount_state_t ;
6825
6846
6826
6847
/*
@@ -7212,23 +7233,34 @@ share_mount(int op, int argc, char **argv)
7212
7233
argv ++ ;
7213
7234
}
7214
7235
7215
- if (argc > 1 ) {
7236
+ if (! recursive && argc > 1 ) {
7216
7237
(void ) fprintf (stderr , gettext ("usage: "
7217
- "zfs mount -a <dataset> \n" ));
7238
+ "zfs mount -a [filesystem] \n" ));
7218
7239
usage (B_FALSE );
7219
7240
}
7220
7241
7221
7242
if (recursive && argc != 1 ) {
7222
7243
(void ) fprintf (stderr , gettext ("usage: "
7223
- "zfs mount -r <dataset >\n" ));
7244
+ "zfs mount -r <filesystem >\n" ));
7224
7245
usage (B_FALSE );
7225
7246
}
7226
7247
7227
- const char * dataset = (argv [0 ] != NULL ) ? argv [0 ] : NULL ;
7248
+ /*
7249
+ * Enable recursive -a for mounting only
7250
+ * Validate filesystem is actually a valid zfs filesystem
7251
+ */
7252
+ const char * filesystem = NULL ;
7253
+ if (op == OP_MOUNT )
7254
+ filesystem = argv [0 ];
7255
+ if (filesystem != NULL &&
7256
+ zfs_open (g_zfs , filesystem , ZFS_TYPE_FILESYSTEM ) == NULL ) {
7257
+ free (options );
7258
+ return (1 );
7259
+ }
7228
7260
7229
7261
start_progress_timer ();
7230
7262
get_all_cb_t cb = { 0 };
7231
- get_all_datasets (& cb , verbose , dataset );
7263
+ get_all_datasets (& cb , verbose , filesystem );
7232
7264
7233
7265
if (cb .cb_used == 0 ) {
7234
7266
free (options );
0 commit comments