Skip to content

Commit

Permalink
zfs_main.c: cleanup initial implementation
Browse files Browse the repository at this point in the history
- corrected `HELP_MOUNT` to more accurately reflect the options
- changed my usage of `dataset` to `filesystem` in order to align with documentation
- improved the recursive checks in `get_one_dataset()`
  - Skip any dataset with the canmount=off property
  - Skip any dataset whose name doesn't match the target filesystem or
  - Skip any dataset whose name doesn't contain the target filesystem + '/'
- corrected the `usage()` errors in `share_mount()` to accurately reflect the options
- limited the recursive feature to `zfs mount` only
- implemented a validity check of the specified target filesystem using `zfs_open()`

Signed-off-by: QORTEC <[email protected]>
  • Loading branch information
QORTEC committed Sep 14, 2023
1 parent 30a50e7 commit f1155a3
Showing 1 changed file with 47 additions and 15 deletions.
62 changes: 47 additions & 15 deletions cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,8 @@ get_usage(zfs_help_t idx)
"[filesystem|volume|snapshot] ...\n"));
case HELP_MOUNT:
return (gettext("\tmount\n"
"\tmount [-flvO] [-o opts] -r <-a | filesystem>\n"));
"\tmount [-flvO] [-o opts] [-r filesystem] "
"<-a [filesystem] | filesystem>\n"));
case HELP_PROMOTE:
return (gettext("\tpromote <clone-filesystem>\n"));
case HELP_RECEIVE:
Expand Down Expand Up @@ -6731,7 +6732,7 @@ zfs_do_holds(int argc, char **argv)
typedef struct get_all_state {
boolean_t ga_verbose;
get_all_cb_t *ga_cbp;
const char *ga_dataset;
const char *ga_filesystem;
} get_all_state_t;

static int
Expand Down Expand Up @@ -6772,12 +6773,31 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
}

/*
* Skip any dataset whos name doesn't have a prefix matching ga_dataset.
* Check if ga_filesystem is set; used for recursive mounting
*/
if (state->ga_dataset != NULL && strncmp(zfs_get_name(zhp),
state->ga_dataset, strlen(state->ga_dataset)) != 0) {
zfs_close(zhp);
return (0);
if (state->ga_filesystem != NULL) {
/*
* Skip any dataset with the canmount=off property.
*/
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_OFF) {

Check failure on line 6782 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters

Check failure on line 6782 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters
zfs_close(zhp);
return (0);
}

/* Add a trailing / to ga_filesystem */
char filesystem[strlen(state->ga_filesystem) + 2];
strcpy(filesystem, state->ga_filesystem);
strcat(filesystem, "/");

/*
* Skip any dataset whose name doesn't match ga_filesystem exactly

Check failure on line 6793 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters

Check failure on line 6793 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters
* or have a prefix matching filesystem.
*/
if (!strcmp(zfs_get_name(zhp), state->ga_filesystem) == 0 ||

Check failure on line 6796 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

don't use boolean ! with comparison functions

Check failure on line 6796 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

don't use boolean ! with comparison functions
!strncmp(zfs_get_name(zhp), filesystem, strlen(filesystem) == 0)) {

Check failure on line 6797 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters

Check failure on line 6797 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

don't use boolean ! with comparison functions

Check failure on line 6797 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters

Check failure on line 6797 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

don't use boolean ! with comparison functions
zfs_close(zhp);
return (0);
}
}

libzfs_add_handle(state->ga_cbp, zhp);
Expand All @@ -6787,12 +6807,12 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
}

static void
get_all_datasets(get_all_cb_t *cbp, boolean_t verbose, const char *dataset)
get_all_datasets(get_all_cb_t *cbp, boolean_t verbose, const char *filesystem)
{
get_all_state_t state = {
.ga_verbose = verbose,
.ga_cbp = cbp,
.ga_dataset = dataset
.ga_filesystem = filesystem
};

if (verbose)
Expand Down Expand Up @@ -6820,7 +6840,8 @@ typedef struct share_mount_state {
uint_t sm_total; /* number of filesystems to process */
uint_t sm_done; /* number of filesystems processed */
int sm_status; /* -1 if any of the share/mount operations failed */
boolean_t sm_explicit;
boolean_t sm_explicit; /* true if filesystems were explictly requested,

Check failure on line 6843 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters

Check failure on line 6843 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

unterminated single line comment

Check failure on line 6843 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters

Check failure on line 6843 in cmd/zfs/zfs_main.c

View workflow job for this annotation

GitHub Actions / checkstyle

unterminated single line comment
false if they are implied by `-a` */
} share_mount_state_t;

/*
Expand Down Expand Up @@ -7212,23 +7233,34 @@ share_mount(int op, int argc, char **argv)
argv++;
}

if (argc > 1) {
if (!recursive && argc > 1) {
(void) fprintf(stderr, gettext("usage: "
"zfs mount -a <dataset>\n"));
"zfs mount -a [filesystem]\n"));
usage(B_FALSE);
}

if (recursive && argc != 1) {
(void) fprintf(stderr, gettext("usage: "
"zfs mount -r <dataset>\n"));
"zfs mount -r <filesystem>\n"));
usage(B_FALSE);
}

const char *dataset = (argv[0] != NULL) ? argv[0] : NULL;
/*
* Enable recursive -a for mounting only
* Validate filesystem is actually a valid zfs filesystem
*/
const char *filesystem = NULL;
if (op == OP_MOUNT)
filesystem = argv[0];
if (filesystem != NULL &&
zfs_open(g_zfs, filesystem, ZFS_TYPE_FILESYSTEM) == NULL) {
free(options);
return (1);
}

start_progress_timer();
get_all_cb_t cb = { 0 };
get_all_datasets(&cb, verbose, dataset);
get_all_datasets(&cb, verbose, filesystem);

if (cb.cb_used == 0) {
free(options);
Expand Down

0 comments on commit f1155a3

Please sign in to comment.