]> git.proxmox.com Git - mirror_zfs.git/commitdiff
libshare: use AVL tree with static data, pass all data in arguments
authorнаб <nabijaczleweli@nabijaczleweli.xyz>
Mon, 28 Feb 2022 13:50:28 +0000 (14:50 +0100)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 12 May 2022 16:26:25 +0000 (09:26 -0700)
This makes it so we don't leak a consistent 64 bytes anymore,
makes the searches simpler and faster, removes /all allocations/
from the driver (quite trivially, since they were absolutely needless),
and makes libshare thread-safe (except, maybe, linux/smb, but that only
does pointer-width loads/stores so it's also mostly fine, except for
leaking smb_shares)

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #13165

lib/libshare/libshare.c
lib/libshare/libshare_impl.h
lib/libshare/nfs.h
lib/libshare/os/freebsd/nfs.c
lib/libshare/os/freebsd/smb.c
lib/libshare/os/linux/nfs.c
lib/libshare/os/linux/smb.c
lib/libshare/smb.h

index f4684cc691077b431cc3db6c8210c9b75266e0b5..4a8e32d773c64552a9a4441a818dd365015d130e 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stddef.h>
 #include <string.h>
 #include <errno.h>
 #include <libintl.h>
 #include <libzfs.h>
 #include <libshare.h>
 #include "libshare_impl.h"
-#include "nfs.h"
-#include "smb.h"
 
-static sa_share_impl_t alloc_share(const char *zfsname, const char *path);
-static void free_share(sa_share_impl_t share);
-
-static int fstypes_count;
-static sa_fstype_t *fstypes;
-
-sa_fstype_t *
-register_fstype(const char *name, const sa_share_ops_t *ops)
+#define        init_share(zfsname, path, shareopts) \
+       { \
+               .sa_zfsname = zfsname, \
+               .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)
 {
-       sa_fstype_t *fstype;
-
-       fstype = calloc(1, sizeof (sa_fstype_t));
-
-       if (fstype == NULL)
-               return (NULL);
-
-       fstype->name = name;
-       fstype->ops = ops;
-       fstype->fsinfo_index = fstypes_count;
-
-       fstypes_count++;
-
-       fstype->next = fstypes;
-       fstypes = fstype;
-
-       return (fstype);
+       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)
 {
-       libshare_nfs_init();
-       libshare_smb_init();
+       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);
 }
 
 int
 sa_enable_share(const char *zfsname, const char *mountpoint,
     const char *shareopts, const char *protocol)
 {
-       int rc, ret = SA_OK;
-       boolean_t found_protocol = B_FALSE;
-       sa_fstype_t *fstype;
-
-       sa_share_impl_t impl_share = alloc_share(zfsname, mountpoint);
-       if (impl_share == NULL)
-               return (SA_NO_MEMORY);
-
-       fstype = fstypes;
-       while (fstype != NULL) {
-               if (strcmp(fstype->name, protocol) == 0) {
-
-                       rc = fstype->ops->update_shareopts(impl_share,
-                           shareopts);
-                       if (rc != SA_OK)
-                               break;
+       sa_fstype_t *fstype = find_proto(protocol);
+       if (!fstype)
+               return (SA_INVALID_PROTOCOL);
 
-                       rc = fstype->ops->enable_share(impl_share);
-                       if (rc != SA_OK)
-                               ret = rc;
-
-                       found_protocol = B_TRUE;
-               }
-
-               fstype = fstype->next;
-       }
-       free_share(impl_share);
-
-       return (found_protocol ? ret : SA_INVALID_PROTOCOL);
+       const struct sa_share_impl args =
+           init_share(zfsname, mountpoint, shareopts);
+       return (fstype->enable_share(&args));
 }
 
 int
 sa_disable_share(const char *mountpoint, const char *protocol)
 {
-       int rc, ret = SA_OK;
-       boolean_t found_protocol = B_FALSE;
-       sa_fstype_t *fstype;
-
-       sa_share_impl_t impl_share = alloc_share(NULL, mountpoint);
-       if (impl_share == NULL)
-               return (SA_NO_MEMORY);
-
-       fstype = fstypes;
-       while (fstype != NULL) {
-               if (strcmp(fstype->name, protocol) == 0) {
+       sa_fstype_t *fstype = find_proto(protocol);
+       if (!fstype)
+               return (SA_INVALID_PROTOCOL);
 
-                       rc = fstype->ops->disable_share(impl_share);
-                       if (rc != SA_OK)
-                               ret = rc;
-
-                       found_protocol = B_TRUE;
-               }
-
-               fstype = fstype->next;
-       }
-       free_share(impl_share);
-
-       return (found_protocol ? ret : SA_INVALID_PROTOCOL);
+       const struct sa_share_impl args = init_share(NULL, mountpoint, NULL);
+       return (fstype->disable_share(&args));
 }
 
 boolean_t
 sa_is_shared(const char *mountpoint, const char *protocol)
 {
-       sa_fstype_t *fstype;
-       boolean_t ret = B_FALSE;
-
-       /* guid value is not used */
-       sa_share_impl_t impl_share = alloc_share(NULL, mountpoint);
-       if (impl_share == NULL)
+       sa_fstype_t *fstype = find_proto(protocol);
+       if (!fstype)
                return (B_FALSE);
 
-       fstype = fstypes;
-       while (fstype != NULL) {
-               if (strcmp(fstype->name, protocol) == 0) {
-                       ret = fstype->ops->is_shared(impl_share);
-               }
-               fstype = fstype->next;
-       }
-       free_share(impl_share);
-       return (ret);
+       const struct sa_share_impl args = init_share(NULL, mountpoint, NULL);
+       return (fstype->is_shared(&args));
 }
 
 void
 sa_commit_shares(const char *protocol)
 {
-       sa_fstype_t *fstype = fstypes;
-       while (fstype != NULL) {
-               if (strcmp(fstype->name, protocol) == 0)
-                       fstype->ops->commit_shares();
-               fstype = fstype->next;
-       }
+       sa_fstype_t *fstype = find_proto(protocol);
+       if (!fstype)
+               return;
+
+       fstype->commit_shares();
 }
 
 /*
@@ -181,185 +127,91 @@ const char *
 sa_errorstr(int err)
 {
        static char errstr[32];
-       char *ret = NULL;
 
        switch (err) {
        case SA_OK:
-               ret = dgettext(TEXT_DOMAIN, "ok");
-               break;
+               return (dgettext(TEXT_DOMAIN, "ok"));
        case SA_NO_SUCH_PATH:
-               ret = dgettext(TEXT_DOMAIN, "path doesn't exist");
-               break;
+               return (dgettext(TEXT_DOMAIN, "path doesn't exist"));
        case SA_NO_MEMORY:
-               ret = dgettext(TEXT_DOMAIN, "no memory");
-               break;
+               return (dgettext(TEXT_DOMAIN, "no memory"));
        case SA_DUPLICATE_NAME:
-               ret = dgettext(TEXT_DOMAIN, "name in use");
-               break;
+               return (dgettext(TEXT_DOMAIN, "name in use"));
        case SA_BAD_PATH:
-               ret = dgettext(TEXT_DOMAIN, "bad path");
-               break;
+               return (dgettext(TEXT_DOMAIN, "bad path"));
        case SA_NO_SUCH_GROUP:
-               ret = dgettext(TEXT_DOMAIN, "no such group");
-               break;
+               return (dgettext(TEXT_DOMAIN, "no such group"));
        case SA_CONFIG_ERR:
-               ret = dgettext(TEXT_DOMAIN, "configuration error");
-               break;
+               return (dgettext(TEXT_DOMAIN, "configuration error"));
        case SA_SYSTEM_ERR:
-               ret = dgettext(TEXT_DOMAIN, "system error");
-               break;
+               return (dgettext(TEXT_DOMAIN, "system error"));
        case SA_SYNTAX_ERR:
-               ret = dgettext(TEXT_DOMAIN, "syntax error");
-               break;
+               return (dgettext(TEXT_DOMAIN, "syntax error"));
        case SA_NO_PERMISSION:
-               ret = dgettext(TEXT_DOMAIN, "no permission");
-               break;
+               return (dgettext(TEXT_DOMAIN, "no permission"));
        case SA_BUSY:
-               ret = dgettext(TEXT_DOMAIN, "busy");
-               break;
+               return (dgettext(TEXT_DOMAIN, "busy"));
        case SA_NO_SUCH_PROP:
-               ret = dgettext(TEXT_DOMAIN, "no such property");
-               break;
+               return (dgettext(TEXT_DOMAIN, "no such property"));
        case SA_INVALID_NAME:
-               ret = dgettext(TEXT_DOMAIN, "invalid name");
-               break;
+               return (dgettext(TEXT_DOMAIN, "invalid name"));
        case SA_INVALID_PROTOCOL:
-               ret = dgettext(TEXT_DOMAIN, "invalid protocol");
-               break;
+               return (dgettext(TEXT_DOMAIN, "invalid protocol"));
        case SA_NOT_ALLOWED:
-               ret = dgettext(TEXT_DOMAIN, "operation not allowed");
-               break;
+               return (dgettext(TEXT_DOMAIN, "operation not allowed"));
        case SA_BAD_VALUE:
-               ret = dgettext(TEXT_DOMAIN, "bad property value");
-               break;
+               return (dgettext(TEXT_DOMAIN, "bad property value"));
        case SA_INVALID_SECURITY:
-               ret = dgettext(TEXT_DOMAIN, "invalid security type");
-               break;
+               return (dgettext(TEXT_DOMAIN, "invalid security type"));
        case SA_NO_SUCH_SECURITY:
-               ret = dgettext(TEXT_DOMAIN, "security type not found");
-               break;
+               return (dgettext(TEXT_DOMAIN, "security type not found"));
        case SA_VALUE_CONFLICT:
-               ret = dgettext(TEXT_DOMAIN, "property value conflict");
-               break;
+               return (dgettext(TEXT_DOMAIN, "property value conflict"));
        case SA_NOT_IMPLEMENTED:
-               ret = dgettext(TEXT_DOMAIN, "not implemented");
-               break;
+               return (dgettext(TEXT_DOMAIN, "not implemented"));
        case SA_INVALID_PATH:
-               ret = dgettext(TEXT_DOMAIN, "invalid path");
-               break;
+               return (dgettext(TEXT_DOMAIN, "invalid path"));
        case SA_NOT_SUPPORTED:
-               ret = dgettext(TEXT_DOMAIN, "operation not supported");
-               break;
+               return (dgettext(TEXT_DOMAIN, "operation not supported"));
        case SA_PROP_SHARE_ONLY:
-               ret = dgettext(TEXT_DOMAIN, "property not valid for group");
-               break;
+               return (dgettext(TEXT_DOMAIN, "property not valid for group"));
        case SA_NOT_SHARED:
-               ret = dgettext(TEXT_DOMAIN, "not shared");
-               break;
+               return (dgettext(TEXT_DOMAIN, "not shared"));
        case SA_NO_SUCH_RESOURCE:
-               ret = dgettext(TEXT_DOMAIN, "no such resource");
-               break;
+               return (dgettext(TEXT_DOMAIN, "no such resource"));
        case SA_RESOURCE_REQUIRED:
-               ret = dgettext(TEXT_DOMAIN, "resource name required");
-               break;
+               return (dgettext(TEXT_DOMAIN, "resource name required"));
        case SA_MULTIPLE_ERROR:
-               ret = dgettext(TEXT_DOMAIN, "errors from multiple protocols");
-               break;
+               return (dgettext(TEXT_DOMAIN,
+                   "errors from multiple protocols"));
        case SA_PATH_IS_SUBDIR:
-               ret = dgettext(TEXT_DOMAIN, "path is a subpath of share");
-               break;
+               return (dgettext(TEXT_DOMAIN, "path is a subpath of share"));
        case SA_PATH_IS_PARENTDIR:
-               ret = dgettext(TEXT_DOMAIN, "path is parent of a share");
-               break;
+               return (dgettext(TEXT_DOMAIN, "path is parent of a share"));
        case SA_NO_SECTION:
-               ret = dgettext(TEXT_DOMAIN, "protocol requires a section");
-               break;
+               return (dgettext(TEXT_DOMAIN, "protocol requires a section"));
        case SA_NO_PROPERTIES:
-               ret = dgettext(TEXT_DOMAIN, "properties not found");
-               break;
+               return (dgettext(TEXT_DOMAIN, "properties not found"));
        case SA_NO_SUCH_SECTION:
-               ret = dgettext(TEXT_DOMAIN, "section not found");
-               break;
+               return (dgettext(TEXT_DOMAIN, "section not found"));
        case SA_PASSWORD_ENC:
-               ret = dgettext(TEXT_DOMAIN, "passwords must be encrypted");
-               break;
+               return (dgettext(TEXT_DOMAIN, "passwords must be encrypted"));
        case SA_SHARE_EXISTS:
-               ret = dgettext(TEXT_DOMAIN, "path or file is already shared");
-               break;
+               return (dgettext(TEXT_DOMAIN,
+                   "path or file is already shared"));
        default:
                (void) snprintf(errstr, sizeof (errstr),
                    dgettext(TEXT_DOMAIN, "unknown %d"), err);
-               ret = errstr;
+               return (errstr);
        }
-       return (ret);
 }
 
 int
-sa_validate_shareopts(const char *options, const char *proto)
-{
-       sa_fstype_t *fstype;
-
-       fstype = fstypes;
-       while (fstype != NULL) {
-               if (strcmp(fstype->name, proto) != 0) {
-                       fstype = fstype->next;
-                       continue;
-               }
-
-               return (fstype->ops->validate_shareopts(options));
-       }
-
-       return (SA_INVALID_PROTOCOL);
-}
-
-static sa_share_impl_t
-alloc_share(const char *zfsname, const char *mountpoint)
+sa_validate_shareopts(const char *options, const char *protocol)
 {
-       sa_share_impl_t impl_share;
-
-       impl_share = calloc(1, sizeof (struct sa_share_impl));
-
-       if (impl_share == NULL)
-               return (NULL);
-
-       if (mountpoint != NULL &&
-           ((impl_share->sa_mountpoint = strdup(mountpoint)) == NULL)) {
-               free(impl_share);
-               return (NULL);
-       }
-
-       if (zfsname != NULL &&
-           ((impl_share->sa_zfsname = strdup(zfsname)) == NULL)) {
-               free(impl_share->sa_mountpoint);
-               free(impl_share);
-               return (NULL);
-       }
-
-       impl_share->sa_fsinfo = calloc(fstypes_count,
-           sizeof (sa_share_fsinfo_t));
-       if (impl_share->sa_fsinfo == NULL) {
-               free(impl_share->sa_mountpoint);
-               free(impl_share->sa_zfsname);
-               free(impl_share);
-               return (NULL);
-       }
-
-       return (impl_share);
-}
-
-static void
-free_share(sa_share_impl_t impl_share)
-{
-       sa_fstype_t *fstype;
-
-       fstype = fstypes;
-       while (fstype != NULL) {
-               fstype->ops->clear_shareopts(impl_share);
-               fstype = fstype->next;
-       }
+       sa_fstype_t *fstype = find_proto(protocol);
+       if (!fstype)
+               return (SA_INVALID_PROTOCOL);
 
-       free(impl_share->sa_mountpoint);
-       free(impl_share->sa_zfsname);
-       free(impl_share->sa_fsinfo);
-       free(impl_share);
+       return (fstype->validate_shareopts(options));
 }
index 63a6907539e085ec9680ebb8ef0b8c0e20528a9f..c79b4f532a4f1fb24724621bdcdba411b249b901 100644 (file)
 #ifndef _LIBSPL_LIBSHARE_IMPL_H
 #define        _LIBSPL_LIBSHARE_IMPL_H
 
-typedef struct sa_share_fsinfo {
-       char *shareopts;
-} sa_share_fsinfo_t;
+#include <sys/avl.h>
 
-typedef struct sa_share_impl {
-       char *sa_mountpoint;
-       char *sa_zfsname;
-
-       sa_share_fsinfo_t *sa_fsinfo; /* per-fstype information */
+typedef const struct sa_share_impl {
+       const char *sa_zfsname;
+       const char *sa_mountpoint;
+       const char *sa_shareopts;
 } *sa_share_impl_t;
 
-#define        FSINFO(impl_share, fstype) \
-       (&(impl_share->sa_fsinfo[fstype->fsinfo_index]))
-
-typedef struct sa_share_ops {
-       int (*enable_share)(sa_share_impl_t share);
-       int (*disable_share)(sa_share_impl_t share);
-       boolean_t (*is_shared)(sa_share_impl_t share);
-       int (*validate_shareopts)(const char *shareopts);
-       int (*update_shareopts)(sa_share_impl_t impl_share,
-           const char *shareopts);
-       void (*clear_shareopts)(sa_share_impl_t impl_share);
-       int (*commit_shares)(void);
-} sa_share_ops_t;
+typedef struct {
+       const char *protocol;
 
-typedef struct sa_fstype {
-       struct sa_fstype *next;
+       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);
 
-       const char *name;
-       const sa_share_ops_t *ops;
-       int fsinfo_index;
+       avl_node_t node;
 } sa_fstype_t;
 
-sa_fstype_t *register_fstype(const char *name, const sa_share_ops_t *ops);
+extern sa_fstype_t libshare_nfs_type, libshare_smb_type;
 
 #endif /* _LIBSPL_LIBSHARE_IMPL_H */
index cfac274c3d266653538b496b6dc3ee835b6d622a..7775816259243cba34bbd27bf9ae81e7c6f35f2f 100644 (file)
@@ -28,8 +28,6 @@
 
 #define        FILE_HEADER             "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n"
 
-void libshare_nfs_init(void);
-
 boolean_t nfs_is_shared_impl(const char *exports, sa_share_impl_t impl_share);
 int nfs_toggle_share(const char *lockfile, const char *exports,
     const char *expdir, sa_share_impl_t impl_share,
index d0cd5f2b3fd9679411a9ba99270219999e369a82..388bafc2836be0d996dcbdfee302636f41618d8d 100644 (file)
@@ -52,8 +52,6 @@ __FBSDID("$FreeBSD$");
 #define        ZFS_EXPORTS_FILE        "/etc/zfs/exports"
 #define        ZFS_EXPORTS_LOCK        ZFS_EXPORTS_FILE".lock"
 
-static sa_fstype_t *nfs_fstype;
-
 /*
  * This function translates options to a format acceptable by exports(5), eg.
  *
@@ -107,7 +105,7 @@ translate_opts(const char *shareopts, FILE *out)
 static int
 nfs_enable_share_impl(sa_share_impl_t impl_share, FILE *tmpfile)
 {
-       char *shareopts = FSINFO(impl_share, nfs_fstype)->shareopts;
+       const char *shareopts = impl_share->sa_shareopts;
        if (strcmp(shareopts, "on") == 0)
                shareopts = "";
 
@@ -158,19 +156,6 @@ nfs_validate_shareopts(const char *shareopts)
        return (SA_OK);
 }
 
-static int
-nfs_update_shareopts(sa_share_impl_t impl_share, const char *shareopts)
-{
-       FSINFO(impl_share, nfs_fstype)->shareopts = (char *)shareopts;
-       return (SA_OK);
-}
-
-static void
-nfs_clear_shareopts(sa_share_impl_t impl_share)
-{
-       FSINFO(impl_share, nfs_fstype)->shareopts = NULL;
-}
-
 /*
  * Commit the shares by restarting mountd.
  */
@@ -201,22 +186,13 @@ start:
        return (SA_OK);
 }
 
-static const sa_share_ops_t nfs_shareops = {
+sa_fstype_t libshare_nfs_type = {
+       .protocol = "nfs",
+
        .enable_share = nfs_enable_share,
        .disable_share = nfs_disable_share,
        .is_shared = nfs_is_shared,
 
        .validate_shareopts = nfs_validate_shareopts,
-       .update_shareopts = nfs_update_shareopts,
-       .clear_shareopts = nfs_clear_shareopts,
        .commit_shares = nfs_commit_shares,
 };
-
-/*
- * Initializes the NFS functionality of libshare.
- */
-void
-libshare_nfs_init(void)
-{
-       nfs_fstype = register_fstype("nfs", &nfs_shareops);
-}
index f14e631b233272cdcbb1e5f0c643a15e17ce1d7f..fd61d473d5c6654771d8a9a2ef1858de469d8d09 100644 (file)
@@ -27,8 +27,6 @@
 #include <libshare.h>
 #include "libshare_impl.h"
 
-static sa_fstype_t *smb_fstype;
-
 /*
  * Enables SMB sharing for the specified share.
  */
@@ -71,51 +69,20 @@ smb_is_share_active(sa_share_impl_t impl_share)
        return (B_FALSE);
 }
 
-/*
- * Called to update a share's options. A share's options might be out of
- * date if the share was loaded from disk and the "sharesmb" dataset
- * property has changed in the meantime. This function also takes care
- * of re-enabling the share if necessary.
- */
-static int
-smb_update_shareopts(sa_share_impl_t impl_share, const char *shareopts)
-{
-       (void) impl_share, (void) shareopts;
-       return (SA_OK);
-}
-
 static int
 smb_update_shares(void)
 {
        /* Not implemented */
        return (0);
 }
-/*
- * Clears a share's SMB options. Used by libshare to
- * clean up shares that are about to be free()'d.
- */
-static void
-smb_clear_shareopts(sa_share_impl_t impl_share)
-{
-       FSINFO(impl_share, smb_fstype)->shareopts = NULL;
-}
 
-static const sa_share_ops_t smb_shareops = {
+sa_fstype_t libshare_smb_type = {
+       .protocol = "smb",
+
        .enable_share = smb_enable_share,
        .disable_share = smb_disable_share,
        .is_shared = smb_is_share_active,
 
        .validate_shareopts = smb_validate_shareopts,
-       .update_shareopts = smb_update_shareopts,
-       .clear_shareopts = smb_clear_shareopts,
        .commit_shares = smb_update_shares,
 };
-
-/*
- * Initializes the SMB functionality of libshare.
- */
-void
-libshare_smb_init(void)
-{
-       smb_fstype = register_fstype("smb", &smb_shareops);
-}
index 72653b6d40f53052f1b0d9c107df055b464c2884..f8a34924c1eb4a05b08b3fac9421e5adaf6a37de 100644 (file)
@@ -45,8 +45,6 @@
 #define        ZFS_EXPORTS_FILE        ZFS_EXPORTS_DIR"/zfs.exports"
 #define        ZFS_EXPORTS_LOCK        ZFS_EXPORTS_FILE".lock"
 
-static sa_fstype_t *nfs_fstype;
-
 typedef int (*nfs_shareopt_callback_t)(const char *opt, const char *value,
     void *cookie);
 
@@ -229,7 +227,6 @@ foreach_nfs_host(sa_share_impl_t impl_share, FILE *tmpfile,
     nfs_host_callback_t callback, void *cookie)
 {
        nfs_host_cookie_t udata;
-       char *shareopts;
 
        udata.callback = callback;
        udata.sharepath = impl_share->sa_mountpoint;
@@ -237,10 +234,8 @@ foreach_nfs_host(sa_share_impl_t impl_share, FILE *tmpfile,
        udata.tmpfile = tmpfile;
        udata.security = "sys";
 
-       shareopts = FSINFO(impl_share, nfs_fstype)->shareopts;
-
-       return (foreach_nfs_shareopt(shareopts, foreach_nfs_host_cb,
-           &udata));
+       return (foreach_nfs_shareopt(impl_share->sa_shareopts,
+           foreach_nfs_host_cb, &udata));
 }
 
 /*
@@ -411,11 +406,10 @@ nfs_add_entry(FILE *tmpfile, const char *sharepath,
 static int
 nfs_enable_share_impl(sa_share_impl_t impl_share, FILE *tmpfile)
 {
-       char *shareopts, *linux_opts;
+       char *linux_opts;
        int error;
 
-       shareopts = FSINFO(impl_share, nfs_fstype)->shareopts;
-       error = get_linux_shareopts(shareopts, &linux_opts);
+       error = get_linux_shareopts(impl_share->sa_shareopts, &linux_opts);
        if (error != SA_OK)
                return (error);
 
@@ -475,23 +469,6 @@ nfs_validate_shareopts(const char *shareopts)
        return (SA_OK);
 }
 
-static int
-nfs_update_shareopts(sa_share_impl_t impl_share, const char *shareopts)
-{
-       FSINFO(impl_share, nfs_fstype)->shareopts = (char *)shareopts;
-       return (SA_OK);
-}
-
-/*
- * Clears a share's NFS options. Used by libshare to
- * clean up shares that are about to be free()'d.
- */
-static void
-nfs_clear_shareopts(sa_share_impl_t impl_share)
-{
-       FSINFO(impl_share, nfs_fstype)->shareopts = NULL;
-}
-
 static int
 nfs_commit_shares(void)
 {
@@ -504,22 +481,13 @@ nfs_commit_shares(void)
        return (libzfs_run_process(argv[0], argv, 0));
 }
 
-static const sa_share_ops_t nfs_shareops = {
+sa_fstype_t libshare_nfs_type = {
+       .protocol = "nfs",
+
        .enable_share = nfs_enable_share,
        .disable_share = nfs_disable_share,
        .is_shared = nfs_is_shared,
 
        .validate_shareopts = nfs_validate_shareopts,
-       .update_shareopts = nfs_update_shareopts,
-       .clear_shareopts = nfs_clear_shareopts,
        .commit_shares = nfs_commit_shares,
 };
-
-/*
- * Initializes the NFS functionality of libshare.
- */
-void
-libshare_nfs_init(void)
-{
-       nfs_fstype = register_fstype("nfs", &nfs_shareops);
-}
index f4a0bfd6bf9bdbc827cc1e324640204924ba75a7..91dffc9bb8a707a47c96cfd9cbbf9b2afb25e9d0 100644 (file)
@@ -63,8 +63,6 @@
 
 static boolean_t smb_available(void);
 
-static sa_fstype_t *smb_fstype;
-
 static smb_share_t *smb_shares;
 static int smb_disable_share(sa_share_impl_t impl_share);
 static boolean_t smb_is_share_active(sa_share_impl_t impl_share);
@@ -265,19 +263,16 @@ smb_enable_share_one(const char *sharename, const char *sharepath)
 static int
 smb_enable_share(sa_share_impl_t impl_share)
 {
-       char *shareopts;
-
        if (!smb_available())
                return (SA_SYSTEM_ERR);
 
        if (smb_is_share_active(impl_share))
                smb_disable_share(impl_share);
 
-       shareopts = FSINFO(impl_share, smb_fstype)->shareopts;
-       if (shareopts == NULL) /* on/off */
+       if (impl_share->sa_shareopts == NULL) /* on/off */
                return (SA_SYSTEM_ERR);
 
-       if (strcmp(shareopts, "off") == 0)
+       if (strcmp(impl_share->sa_shareopts, "off") == 0)
                return (SA_OK);
 
        /* Magic: Enable (i.e., 'create new') share */
@@ -361,22 +356,6 @@ smb_is_share_active(sa_share_impl_t impl_share)
        return (B_FALSE);
 }
 
-/*
- * Called to update a share's options. A share's options might be out of
- * date if the share was loaded from disk and the "sharesmb" dataset
- * property has changed in the meantime. This function also takes care
- * of re-enabling the share if necessary.
- */
-static int
-smb_update_shareopts(sa_share_impl_t impl_share, const char *shareopts)
-{
-       if (!impl_share)
-               return (SA_SYSTEM_ERR);
-
-       FSINFO(impl_share, smb_fstype)->shareopts = (char *)shareopts;
-       return (SA_OK);
-}
-
 static int
 smb_update_shares(void)
 {
@@ -384,24 +363,14 @@ smb_update_shares(void)
        return (0);
 }
 
-/*
- * Clears a share's SMB options. Used by libshare to
- * clean up shares that are about to be free()'d.
- */
-static void
-smb_clear_shareopts(sa_share_impl_t impl_share)
-{
-       FSINFO(impl_share, smb_fstype)->shareopts = NULL;
-}
+sa_fstype_t libshare_smb_type = {
+       .protocol = "smb",
 
-static const sa_share_ops_t smb_shareops = {
        .enable_share = smb_enable_share,
        .disable_share = smb_disable_share,
        .is_shared = smb_is_share_active,
 
        .validate_shareopts = smb_validate_shareopts,
-       .update_shareopts = smb_update_shareopts,
-       .clear_shareopts = smb_clear_shareopts,
        .commit_shares = smb_update_shares,
 };
 
@@ -422,12 +391,3 @@ smb_available(void)
 
        return (B_TRUE);
 }
-
-/*
- * Initializes the SMB functionality of libshare.
- */
-void
-libshare_smb_init(void)
-{
-       smb_fstype = register_fstype("smb", &smb_shareops);
-}
index c45e0aec60672022cf83e7dde148616a56921354..ca3577751923b11e116f0b23f860c3035e9de37b 100644 (file)
@@ -43,5 +43,3 @@ typedef struct smb_share_s {
 
        struct smb_share_s *next;
 } smb_share_t;
-
-void libshare_smb_init(void);