Skip to content

Commit

Permalink
Publish libshare protocols, use enum-based API
Browse files Browse the repository at this point in the history
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes openzfs#13165
  • Loading branch information
nabijaczleweli authored and behlendorf committed May 12, 2022
1 parent 21d976a commit 471e9a1
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 204 deletions.
88 changes: 32 additions & 56 deletions lib/libshare/libshare.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

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));
}

__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);
}
#define VALIDATE_PROTOCOL(proto, ...) \
if ((proto) < 0 || (proto) >= SA_PROTOCOL_COUNT) \
return __VA_ARGS__

const char *const sa_protocol_names[SA_PROTOCOL_COUNT] = {
[SA_PROTOCOL_NFS] = "nfs",
[SA_PROTOCOL_SMB] = "smb",
};

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)
{
/* CSTYLED */
VALIDATE_PROTOCOL(protocol, );

fstypes[protocol]->commit_shares();
}

int
sa_validate_shareopts(const char *options, enum sa_protocol protocol)
{
sa_fstype_t *fstype = find_proto(protocol);
if (!fstype)
return;
VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL);

fstype->commit_shares();
return (fstypes[protocol]->validate_shareopts(options));
}

/*
Expand Down Expand Up @@ -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));
}
8 changes: 1 addition & 7 deletions lib/libshare/libshare_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,20 @@
#ifndef _LIBSPL_LIBSHARE_IMPL_H
#define _LIBSPL_LIBSHARE_IMPL_H

#include <sys/avl.h>

typedef const struct sa_share_impl {
const char *sa_zfsname;
const char *sa_mountpoint;
const char *sa_shareopts;
} *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 */
4 changes: 1 addition & 3 deletions lib/libshare/os/freebsd/nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,7 @@ nfs_commit_shares(void)
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,
Expand Down
4 changes: 1 addition & 3 deletions lib/libshare/os/freebsd/smb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 1 addition & 3 deletions lib/libshare/os/linux/nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 1 addition & 3 deletions lib/libshare/os/linux/smb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
20 changes: 15 additions & 5 deletions lib/libspl/include/libshare.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
5 changes: 3 additions & 2 deletions lib/libzfs/libzfs_changelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
9 changes: 5 additions & 4 deletions lib/libzfs/libzfs_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1418,14 +1418,15 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
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);
Expand Down
33 changes: 11 additions & 22 deletions lib/libzfs/libzfs_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down Expand Up @@ -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 *);
Expand All @@ -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;
Expand Down Expand Up @@ -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
}
Expand Down
Loading

0 comments on commit 471e9a1

Please sign in to comment.