diff --git a/lib/libshare/libshare.c b/lib/libshare/libshare.c index 4a8e32d773..09529e5b41 100644 --- a/lib/libshare/libshare.c +++ b/lib/libshare/libshare.c @@ -45,77 +45,63 @@ .sa_mountpoint = path, \ .sa_shareopts = shareopts, \ } -#define find_proto(pcol) \ - /* CSTYLED */ \ - ({ \ - sa_fstype_t prot = { \ - .protocol = pcol, \ - }; \ - avl_find(&fstypes, &prot, NULL); \ - }) -static avl_tree_t fstypes; +#define VALIDATE_PROTOCOL(proto, ...) \ + if ((proto) < 0 || (proto) >= SA_PROTOCOL_COUNT) \ + return __VA_ARGS__ -static int -fstypes_compar(const void *lhs, const void *rhs) -{ - const sa_fstype_t *l = lhs, *r = rhs; - int cmp = strcmp(l->protocol, r->protocol); - return ((0 < cmp) - (cmp < 0)); -} +const char *const sa_protocol_names[SA_PROTOCOL_COUNT] = { + [SA_PROTOCOL_NFS] = "nfs", + [SA_PROTOCOL_SMB] = "smb", +}; -__attribute__((constructor)) static void -libshare_init(void) -{ - avl_create(&fstypes, fstypes_compar, - sizeof (sa_fstype_t), offsetof(sa_fstype_t, node)); - avl_add(&fstypes, &libshare_nfs_type); - avl_add(&fstypes, &libshare_smb_type); -} +static const sa_fstype_t *fstypes[SA_PROTOCOL_COUNT] = + {&libshare_nfs_type, &libshare_smb_type}; int sa_enable_share(const char *zfsname, const char *mountpoint, - const char *shareopts, const char *protocol) + const char *shareopts, enum sa_protocol protocol) { - sa_fstype_t *fstype = find_proto(protocol); - if (!fstype) - return (SA_INVALID_PROTOCOL); + VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL); const struct sa_share_impl args = init_share(zfsname, mountpoint, shareopts); - return (fstype->enable_share(&args)); + return (fstypes[protocol]->enable_share(&args)); } int -sa_disable_share(const char *mountpoint, const char *protocol) +sa_disable_share(const char *mountpoint, enum sa_protocol protocol) { - sa_fstype_t *fstype = find_proto(protocol); - if (!fstype) - return (SA_INVALID_PROTOCOL); + VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL); const struct sa_share_impl args = init_share(NULL, mountpoint, NULL); - return (fstype->disable_share(&args)); + return (fstypes[protocol]->disable_share(&args)); } boolean_t -sa_is_shared(const char *mountpoint, const char *protocol) +sa_is_shared(const char *mountpoint, enum sa_protocol protocol) { - sa_fstype_t *fstype = find_proto(protocol); - if (!fstype) - return (B_FALSE); + VALIDATE_PROTOCOL(protocol, B_FALSE); const struct sa_share_impl args = init_share(NULL, mountpoint, NULL); - return (fstype->is_shared(&args)); + return (fstypes[protocol]->is_shared(&args)); } void -sa_commit_shares(const char *protocol) +sa_commit_shares(enum sa_protocol protocol) { - sa_fstype_t *fstype = find_proto(protocol); - if (!fstype) - return; + /* CSTYLED */ + VALIDATE_PROTOCOL(protocol, ); - fstype->commit_shares(); + fstypes[protocol]->commit_shares(); +} + +int +sa_validate_shareopts(const char *options, enum sa_protocol protocol) +{ + VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL); + + return (fstypes[protocol]->validate_shareopts(options)); } /* @@ -205,13 +191,3 @@ sa_errorstr(int err) return (errstr); } } - -int -sa_validate_shareopts(const char *options, const char *protocol) -{ - sa_fstype_t *fstype = find_proto(protocol); - if (!fstype) - return (SA_INVALID_PROTOCOL); - - return (fstype->validate_shareopts(options)); -} diff --git a/lib/libshare/libshare_impl.h b/lib/libshare/libshare_impl.h index c79b4f532a..110fe93d25 100644 --- a/lib/libshare/libshare_impl.h +++ b/lib/libshare/libshare_impl.h @@ -27,8 +27,6 @@ #ifndef _LIBSPL_LIBSHARE_IMPL_H #define _LIBSPL_LIBSHARE_IMPL_H -#include - typedef const struct sa_share_impl { const char *sa_zfsname; const char *sa_mountpoint; @@ -36,17 +34,13 @@ typedef const struct sa_share_impl { } *sa_share_impl_t; typedef struct { - const char *protocol; - int (*const enable_share)(sa_share_impl_t share); int (*const disable_share)(sa_share_impl_t share); boolean_t (*const is_shared)(sa_share_impl_t share); int (*const validate_shareopts)(const char *shareopts); int (*const commit_shares)(void); - - avl_node_t node; } sa_fstype_t; -extern sa_fstype_t libshare_nfs_type, libshare_smb_type; +extern const sa_fstype_t libshare_nfs_type, libshare_smb_type; #endif /* _LIBSPL_LIBSHARE_IMPL_H */ diff --git a/lib/libshare/os/freebsd/nfs.c b/lib/libshare/os/freebsd/nfs.c index 388bafc283..338d25fcd0 100644 --- a/lib/libshare/os/freebsd/nfs.c +++ b/lib/libshare/os/freebsd/nfs.c @@ -186,9 +186,7 @@ start: return (SA_OK); } -sa_fstype_t libshare_nfs_type = { - .protocol = "nfs", - +const sa_fstype_t libshare_nfs_type = { .enable_share = nfs_enable_share, .disable_share = nfs_disable_share, .is_shared = nfs_is_shared, diff --git a/lib/libshare/os/freebsd/smb.c b/lib/libshare/os/freebsd/smb.c index fd61d473d5..0f546dc554 100644 --- a/lib/libshare/os/freebsd/smb.c +++ b/lib/libshare/os/freebsd/smb.c @@ -76,9 +76,7 @@ smb_update_shares(void) return (0); } -sa_fstype_t libshare_smb_type = { - .protocol = "smb", - +const sa_fstype_t libshare_smb_type = { .enable_share = smb_enable_share, .disable_share = smb_disable_share, .is_shared = smb_is_share_active, diff --git a/lib/libshare/os/linux/nfs.c b/lib/libshare/os/linux/nfs.c index f8a34924c1..09c7395c66 100644 --- a/lib/libshare/os/linux/nfs.c +++ b/lib/libshare/os/linux/nfs.c @@ -481,9 +481,7 @@ nfs_commit_shares(void) return (libzfs_run_process(argv[0], argv, 0)); } -sa_fstype_t libshare_nfs_type = { - .protocol = "nfs", - +const sa_fstype_t libshare_nfs_type = { .enable_share = nfs_enable_share, .disable_share = nfs_disable_share, .is_shared = nfs_is_shared, diff --git a/lib/libshare/os/linux/smb.c b/lib/libshare/os/linux/smb.c index 91dffc9bb8..1f32d0e109 100644 --- a/lib/libshare/os/linux/smb.c +++ b/lib/libshare/os/linux/smb.c @@ -363,9 +363,7 @@ smb_update_shares(void) return (0); } -sa_fstype_t libshare_smb_type = { - .protocol = "smb", - +const sa_fstype_t libshare_smb_type = { .enable_share = smb_enable_share, .disable_share = smb_disable_share, .is_shared = smb_is_share_active, diff --git a/lib/libspl/include/libshare.h b/lib/libspl/include/libshare.h index b8aa02095c..ae0e2c39dc 100644 --- a/lib/libspl/include/libshare.h +++ b/lib/libspl/include/libshare.h @@ -72,14 +72,24 @@ /* initialization */ _LIBSPL_LIBSHARE_H const char *sa_errorstr(int); +/* available protocols */ +enum sa_protocol { + SA_PROTOCOL_NFS, + SA_PROTOCOL_SMB, /* ABI: add before _COUNT */ + SA_PROTOCOL_COUNT, +}; + +/* lower-case */ +_LIBSPL_LIBSHARE_H const char *const sa_protocol_names[SA_PROTOCOL_COUNT]; + /* share control */ _LIBSPL_LIBSHARE_H int sa_enable_share(const char *, const char *, const char *, - const char *); -_LIBSPL_LIBSHARE_H int sa_disable_share(const char *, const char *); -_LIBSPL_LIBSHARE_H boolean_t sa_is_shared(const char *, const char *); -_LIBSPL_LIBSHARE_H void sa_commit_shares(const char *); + enum sa_protocol); +_LIBSPL_LIBSHARE_H int sa_disable_share(const char *, enum sa_protocol); +_LIBSPL_LIBSHARE_H boolean_t sa_is_shared(const char *, enum sa_protocol); +_LIBSPL_LIBSHARE_H void sa_commit_shares(enum sa_protocol); /* protocol specific interfaces */ -_LIBSPL_LIBSHARE_H int sa_validate_shareopts(const char *, const char *); +_LIBSPL_LIBSHARE_H int sa_validate_shareopts(const char *, enum sa_protocol); #endif /* _LIBSPL_LIBSHARE_H */ diff --git a/lib/libzfs/libzfs_changelist.c b/lib/libzfs/libzfs_changelist.c index 5441864c5c..a70c7424b9 100644 --- a/lib/libzfs/libzfs_changelist.c +++ b/lib/libzfs/libzfs_changelist.c @@ -345,7 +345,7 @@ changelist_rename(prop_changelist_t *clp, const char *src, const char *dst) * unshare all the datasets in the list. */ int -changelist_unshare(prop_changelist_t *clp, const zfs_share_proto_t *proto) +changelist_unshare(prop_changelist_t *clp, const enum sa_protocol *proto) { prop_changenode_t *cn; uu_avl_walk_t *walk; @@ -363,7 +363,8 @@ changelist_unshare(prop_changelist_t *clp, const zfs_share_proto_t *proto) ret = -1; } - zfs_commit_proto(proto); + for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p) + sa_commit_shares(*p); uu_avl_walk_end(walk); return (ret); diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 3469d38065..e5c1bd62d5 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -1418,14 +1418,15 @@ badlabel: prop == ZFS_PROP_SHARESMB) && strcmp(strval, "on") != 0 && strcmp(strval, "off") != 0) { - zfs_share_proto_t proto; + enum sa_protocol proto; if (prop == ZFS_PROP_SHARESMB) - proto = PROTO_SMB; + proto = SA_PROTOCOL_SMB; else - proto = PROTO_NFS; + proto = SA_PROTOCOL_NFS; - if (zfs_parse_options(strval, proto) != SA_OK) { + if (sa_validate_shareopts(strval, proto) != + SA_OK) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' cannot be set to invalid " "options"), propname); diff --git a/lib/libzfs/libzfs_impl.h b/lib/libzfs/libzfs_impl.h index 4b18ad6685..bf1a8359ce 100644 --- a/lib/libzfs/libzfs_impl.h +++ b/lib/libzfs/libzfs_impl.h @@ -105,21 +105,14 @@ struct zpool_handle { diskaddr_t zpool_start_block; }; -typedef enum { - PROTO_NFS = 0, - PROTO_SMB = 1, - PROTO_END = 2 -} zfs_share_proto_t; - /* - * The following can be used as a bitmask and any new values - * added must preserve that capability. + * Bitmask of shared types: + * 0 means none, otherwise | (1 << (enum sa_protocol + 1)). */ -typedef enum { - SHARED_NOT_SHARED = 0x0, - SHARED_NFS = 0x2, - SHARED_SMB = 0x4 -} zfs_share_type_t; +typedef unsigned zfs_share_type_t; +#define SHARED_NOT_SHARED 0 + +#define SA_NO_PROTOCOL -1 typedef int (*zfs_uri_handler_fn_t)(struct libzfs_handle *, const char *, const char *, zfs_keyformat_t, boolean_t, uint8_t **, size_t *); @@ -189,7 +182,7 @@ extern void changelist_remove(prop_changelist_t *, const char *); extern void changelist_free(prop_changelist_t *); extern prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int, int); -extern int changelist_unshare(prop_changelist_t *, const zfs_share_proto_t *); +extern int changelist_unshare(prop_changelist_t *, const enum sa_protocol *); extern int changelist_haszonedchild(prop_changelist_t *); extern void remove_mountpoint(zfs_handle_t *); @@ -209,11 +202,8 @@ extern int zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type, extern void namespace_clear(libzfs_handle_t *); -extern int zfs_parse_options(char *, zfs_share_proto_t); - typedef struct { zfs_prop_t p_prop; - char *p_name; int p_share_err; int p_unshare_err; } proto_table_t; @@ -244,20 +234,19 @@ extern int do_mount(zfs_handle_t *zhp, const char *mntpt, char *opts, int flags); extern int do_unmount(zfs_handle_t *zhp, const char *mntpt, int flags); extern int zfs_mount_delegation_check(void); -extern int zfs_share_proto(zfs_handle_t *zhp, const zfs_share_proto_t *proto); +extern int zfs_share_proto(zfs_handle_t *zhp, const enum sa_protocol *proto); extern int zfs_unshare_proto(zfs_handle_t *, const char *, - const zfs_share_proto_t *); + const enum sa_protocol *); extern int unshare_one(libzfs_handle_t *hdl, const char *name, - const char *mountpoint, zfs_share_proto_t proto); + const char *mountpoint, enum sa_protocol proto); extern boolean_t zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen, zprop_source_t *source, int flags); extern zfs_share_type_t is_shared(const char *mountpoint, - zfs_share_proto_t proto); + enum sa_protocol proto); extern int libzfs_load_module(void); extern int zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg); extern int find_shares_object(differ_info_t *di); -extern void zfs_commit_proto(const zfs_share_proto_t *); #ifdef __cplusplus } diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 59cfa22d34..ea7e97c293 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -96,30 +96,19 @@ static int mount_tp_nthr = 512; /* tpool threads for multi-threaded mounting */ static void zfs_mount_task(void *); static zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **, - zfs_share_proto_t); + enum sa_protocol); -/* - * The share protocols table must be in the same order as the zfs_share_proto_t - * enum in libzfs_impl.h - */ -static const proto_table_t proto_table[PROTO_END] = { - {ZFS_PROP_SHARENFS, "nfs", EZFS_SHARENFSFAILED, EZFS_UNSHARENFSFAILED}, - {ZFS_PROP_SHARESMB, "smb", EZFS_SHARESMBFAILED, EZFS_UNSHARESMBFAILED}, +static const proto_table_t proto_table[SA_PROTOCOL_COUNT] = { + [SA_PROTOCOL_NFS] = + {ZFS_PROP_SHARENFS, EZFS_SHARENFSFAILED, EZFS_UNSHARENFSFAILED}, + [SA_PROTOCOL_SMB] = + {ZFS_PROP_SHARESMB, EZFS_SHARESMBFAILED, EZFS_UNSHARESMBFAILED}, }; -static const zfs_share_proto_t nfs_only[] = { - PROTO_NFS, - PROTO_END -}; - -static const zfs_share_proto_t smb_only[] = { - PROTO_SMB, - PROTO_END -}; -static const zfs_share_proto_t share_all_proto[] = { - PROTO_NFS, - PROTO_SMB, - PROTO_END +static const enum sa_protocol share_all_proto[SA_PROTOCOL_COUNT + 1] = { + SA_PROTOCOL_NFS, + SA_PROTOCOL_SMB, + SA_NO_PROTOCOL }; @@ -705,17 +694,14 @@ zfs_unmountall(zfs_handle_t *zhp, int flags) boolean_t zfs_is_shared(zfs_handle_t *zhp) { - zfs_share_type_t rc = 0; - const zfs_share_proto_t *curr_proto; - if (ZFS_IS_VOLUME(zhp)) return (B_FALSE); - for (curr_proto = share_all_proto; *curr_proto != PROTO_END; - curr_proto++) - rc |= zfs_is_shared_proto(zhp, NULL, *curr_proto); + for (enum sa_protocol i = 0; i < SA_PROTOCOL_COUNT; ++i) + if (zfs_is_shared_proto(zhp, NULL, i)) + return (B_TRUE); - return (rc ? B_TRUE : B_FALSE); + return (B_FALSE); } /* @@ -723,16 +709,14 @@ zfs_is_shared(zfs_handle_t *zhp) */ int unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint, - zfs_share_proto_t proto) + enum sa_protocol proto) { - int err; - - err = sa_disable_share(mountpoint, proto_table[proto].p_name); - if (err != SA_OK) { + int err = sa_disable_share(mountpoint, proto); + if (err != SA_OK) return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err, dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"), name, sa_errorstr(err))); - } + return (0); } @@ -741,19 +725,12 @@ unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint, * a zfs_share_type_t value. */ zfs_share_type_t -is_shared(const char *mountpoint, zfs_share_proto_t proto) +is_shared(const char *mountpoint, enum sa_protocol proto) { - if (sa_is_shared(mountpoint, proto_table[proto].p_name)) { - switch (proto) { - case PROTO_NFS: - return (SHARED_NFS); - case PROTO_SMB: - return (SHARED_SMB); - default: - return (SHARED_NOT_SHARED); - } - } - return (SHARED_NOT_SHARED); + if (sa_is_shared(mountpoint, proto)) + return (1 << (proto + 1)); + else + return (SHARED_NOT_SHARED); } /* @@ -762,19 +739,19 @@ is_shared(const char *mountpoint, zfs_share_proto_t proto) * on "libshare" to do the dirty work for us. */ int -zfs_share_proto(zfs_handle_t *zhp, const zfs_share_proto_t *proto) +zfs_share_proto(zfs_handle_t *zhp, const enum sa_protocol *proto) { char mountpoint[ZFS_MAXPROPLEN]; char shareopts[ZFS_MAXPROPLEN]; char sourcestr[ZFS_MAXPROPLEN]; - const zfs_share_proto_t *curr_proto; + const enum sa_protocol *curr_proto; zprop_source_t sourcetype; int err = 0; if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL, 0)) return (0); - for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) { + for (curr_proto = proto; *curr_proto != SA_NO_PROTOCOL; curr_proto++) { /* * Return success if there are no share options. */ @@ -794,7 +771,7 @@ zfs_share_proto(zfs_handle_t *zhp, const zfs_share_proto_t *proto) continue; err = sa_enable_share(zfs_get_name(zhp), mountpoint, shareopts, - proto_table[*curr_proto].p_name); + *curr_proto); if (err != SA_OK) { return (zfs_error_fmt(zhp->zfs_hdl, proto_table[*curr_proto].p_share_err, @@ -824,7 +801,7 @@ zfs_unshare(zfs_handle_t *zhp) * Check to see if the filesystem is currently shared. */ static zfs_share_type_t -zfs_is_shared_proto(zfs_handle_t *zhp, char **where, zfs_share_proto_t proto) +zfs_is_shared_proto(zfs_handle_t *zhp, char **where, enum sa_protocol proto) { char *mountpoint; zfs_share_type_t rc; @@ -849,74 +826,60 @@ boolean_t zfs_is_shared_nfs(zfs_handle_t *zhp, char **where) { return (zfs_is_shared_proto(zhp, where, - PROTO_NFS) != SHARED_NOT_SHARED); + SA_PROTOCOL_NFS) != SHARED_NOT_SHARED); } boolean_t zfs_is_shared_smb(zfs_handle_t *zhp, char **where) { return (zfs_is_shared_proto(zhp, where, - PROTO_SMB) != SHARED_NOT_SHARED); -} - -/* - * zfs_parse_options(options, proto) - * - * Call the legacy parse interface to get the protocol specific - * options using the NULL arg to indicate that this is a "parse" only. - */ -int -zfs_parse_options(char *options, zfs_share_proto_t proto) -{ - return (sa_validate_shareopts(options, proto_table[proto].p_name)); -} - -void -zfs_commit_proto(const zfs_share_proto_t *proto) -{ - const zfs_share_proto_t *curr_proto; - for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) - sa_commit_shares(proto_table[*curr_proto].p_name); + SA_PROTOCOL_SMB) != SHARED_NOT_SHARED); } void zfs_commit_nfs_shares(void) { - zfs_commit_proto(nfs_only); + sa_commit_shares(SA_PROTOCOL_NFS); } void zfs_commit_smb_shares(void) { - zfs_commit_proto(smb_only); + sa_commit_shares(SA_PROTOCOL_SMB); } void zfs_commit_all_shares(void) { - zfs_commit_proto(share_all_proto); + for (enum sa_protocol i = 0; i < SA_PROTOCOL_COUNT; ++i) + sa_commit_shares(i); } void zfs_commit_shares(const char *proto) { if (proto == NULL) - zfs_commit_proto(share_all_proto); - else if (strcmp(proto, "nfs") == 0) - zfs_commit_proto(nfs_only); - else if (strcmp(proto, "smb") == 0) - zfs_commit_proto(smb_only); + zfs_commit_all_shares(); + else + for (enum sa_protocol i = 0; i < ARRAY_SIZE(sa_protocol_names); + ++i) + if (strcmp(proto, sa_protocol_names[i]) == 0) { + sa_commit_shares(i); + return; + } } int zfs_share_nfs(zfs_handle_t *zhp) { + const enum sa_protocol nfs_only[] = {SA_PROTOCOL_NFS, SA_NO_PROTOCOL}; return (zfs_share_proto(zhp, nfs_only)); } int zfs_share_smb(zfs_handle_t *zhp) { + const enum sa_protocol smb_only[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL}; return (zfs_share_proto(zhp, smb_only)); } @@ -931,7 +894,7 @@ zfs_shareall(zfs_handle_t *zhp) */ int zfs_unshare_proto(zfs_handle_t *zhp, const char *mountpoint, - const zfs_share_proto_t *proto) + const enum sa_protocol *proto) { libzfs_handle_t *hdl = zhp->zfs_hdl; struct mnttab entry; @@ -943,12 +906,12 @@ zfs_unshare_proto(zfs_handle_t *zhp, const char *mountpoint, if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) && libzfs_mnttab_find(hdl, zfs_get_name(zhp), &entry) == 0)) { - const zfs_share_proto_t *curr_proto; + const enum sa_protocol *curr_proto; if (mountpoint == NULL) mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp); - for (curr_proto = proto; *curr_proto != PROTO_END; + for (curr_proto = proto; *curr_proto != SA_NO_PROTOCOL; curr_proto++) { if (is_shared(mntpt, *curr_proto)) { @@ -970,12 +933,14 @@ zfs_unshare_proto(zfs_handle_t *zhp, const char *mountpoint, int zfs_unshare_nfs(zfs_handle_t *zhp, const char *mountpoint) { + const enum sa_protocol nfs_only[] = {SA_PROTOCOL_NFS, SA_NO_PROTOCOL}; return (zfs_unshare_proto(zhp, mountpoint, nfs_only)); } int zfs_unshare_smb(zfs_handle_t *zhp, const char *mountpoint) { + const enum sa_protocol smb_only[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL}; return (zfs_unshare_proto(zhp, mountpoint, smb_only)); } @@ -983,7 +948,7 @@ zfs_unshare_smb(zfs_handle_t *zhp, const char *mountpoint) * Same as zfs_unmountall(), but for NFS and SMB unshares. */ static int -zfs_unshareall_proto(zfs_handle_t *zhp, const zfs_share_proto_t *proto) +zfs_unshareall_proto(zfs_handle_t *zhp, const enum sa_protocol *proto) { prop_changelist_t *clp; int ret; @@ -1001,12 +966,14 @@ zfs_unshareall_proto(zfs_handle_t *zhp, const zfs_share_proto_t *proto) int zfs_unshareall_nfs(zfs_handle_t *zhp) { + const enum sa_protocol nfs_only[] = {SA_PROTOCOL_NFS, SA_NO_PROTOCOL}; return (zfs_unshareall_proto(zhp, nfs_only)); } int zfs_unshareall_smb(zfs_handle_t *zhp) { + const enum sa_protocol smb_only[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL}; return (zfs_unshareall_proto(zhp, smb_only)); } @@ -1028,12 +995,14 @@ zfs_unshareall_bytype(zfs_handle_t *zhp, const char *mountpoint, { if (proto == NULL) return (zfs_unshare_proto(zhp, mountpoint, share_all_proto)); - if (strcmp(proto, "nfs") == 0) - return (zfs_unshare_proto(zhp, mountpoint, nfs_only)); - else if (strcmp(proto, "smb") == 0) - return (zfs_unshare_proto(zhp, mountpoint, smb_only)); - else - return (1); + + for (enum sa_protocol i = 0; i < ARRAY_SIZE(sa_protocol_names); ++i) + if (strcmp(proto, sa_protocol_names[i]) == 0) { + enum sa_protocol protocols[] = {i, SA_NO_PROTOCOL}; + return (zfs_unshare_proto(zhp, mountpoint, protocols)); + } + + return (1); } /* @@ -1608,12 +1577,10 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force) * Walk through and first unshare everything. */ for (i = 0; i < used; i++) { - const zfs_share_proto_t *curr_proto; - for (curr_proto = share_all_proto; *curr_proto != PROTO_END; - curr_proto++) { - if (is_shared(sets[i].mountpoint, *curr_proto) && + for (enum sa_protocol i = 0; i < SA_PROTOCOL_COUNT; ++i) { + if (is_shared(sets[i].mountpoint, i) && unshare_one(hdl, sets[i].mountpoint, - sets[i].mountpoint, *curr_proto) != 0) + sets[i].mountpoint, i) != 0) goto out; } }