]> granicus.if.org Git - zfs/commitdiff
Restructure mount option handling
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 9 Mar 2017 00:56:09 +0000 (19:56 -0500)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 10 Mar 2017 17:51:41 +0000 (09:51 -0800)
Restructure the handling of mount options to be consistent with
upstream OpenZFS.  This required making the following changes.

- The zfs_mntopts_t was renamed vfs_t and adjusted to provide
  the minimal needed functionality.  This includes a pointer
  back to the associated zfsvfs_t.  Plus it made it possible
  to revert zfs_register_callbacks() and zfsvfs_create() back
  to their original prototypes.

- A zfs_mnt_t structure was added for the sole purpose of
  providing a structure to pass the osname and raw mount
  pointer to zfs_domount() without having to copy them.

- Mount option parsing was moved down from the zpl_* wrapper
  functions in to the zfs_* functions.  This allowed for the
  code to be simplied and it's where similar functionality
  appears on other platforms.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
include/sys/zfs_vfsops.h
module/zfs/zfs_ctldir.c
module/zfs/zfs_ioctl.c
module/zfs/zfs_vfsops.c
module/zfs/zpl_super.c

index a208bc1f896e0a3998cce40cfc59618f40c864a5..aeecc472dabcb0290b842cfc0b7e4d30dc015fa6 100644 (file)
@@ -41,33 +41,43 @@ extern "C" {
 typedef struct zfsvfs zfsvfs_t;
 struct znode;
 
-typedef struct zfs_mntopts {
-       char            *z_osname;      /* Objset name */
-       char            *z_mntpoint;    /* Primary mount point */
-       uint64_t        z_xattr;
-       boolean_t       z_readonly;
-       boolean_t       z_do_readonly;
-       boolean_t       z_setuid;
-       boolean_t       z_do_setuid;
-       boolean_t       z_exec;
-       boolean_t       z_do_exec;
-       boolean_t       z_devices;
-       boolean_t       z_do_devices;
-       boolean_t       z_do_xattr;
-       boolean_t       z_atime;
-       boolean_t       z_do_atime;
-       boolean_t       z_relatime;
-       boolean_t       z_do_relatime;
-       boolean_t       z_nbmand;
-       boolean_t       z_do_nbmand;
-} zfs_mntopts_t;
+/*
+ * This structure emulates the vfs_t from other platforms.  It's purpose
+ * is to faciliate the handling of mount options and minimize structural
+ * differences between the platforms.
+ */
+typedef struct vfs {
+       struct zfsvfs   *vfs_data;
+       char            *vfs_mntpoint;  /* Primary mount point */
+       uint64_t        vfs_xattr;
+       boolean_t       vfs_readonly;
+       boolean_t       vfs_do_readonly;
+       boolean_t       vfs_setuid;
+       boolean_t       vfs_do_setuid;
+       boolean_t       vfs_exec;
+       boolean_t       vfs_do_exec;
+       boolean_t       vfs_devices;
+       boolean_t       vfs_do_devices;
+       boolean_t       vfs_do_xattr;
+       boolean_t       vfs_atime;
+       boolean_t       vfs_do_atime;
+       boolean_t       vfs_relatime;
+       boolean_t       vfs_do_relatime;
+       boolean_t       vfs_nbmand;
+       boolean_t       vfs_do_nbmand;
+} vfs_t;
+
+typedef struct zfs_mnt {
+       const char      *mnt_osname;    /* Objset name */
+       char            *mnt_data;      /* Raw mount options */
+} zfs_mnt_t;
 
 struct zfsvfs {
+       vfs_t           *z_vfs;         /* generic fs struct */
        struct super_block *z_sb;       /* generic super_block */
        struct backing_dev_info z_bdi;  /* generic backing dev info */
        struct zfsvfs   *z_parent;      /* parent fs */
        objset_t        *z_os;          /* objset reference */
-       zfs_mntopts_t   *z_mntopts;     /* passed mount options */
        uint64_t        z_flags;        /* super_block flags */
        uint64_t        z_root;         /* id of root znode */
        uint64_t        z_unlinkedobj;  /* id of unlinked zapobj */
@@ -193,17 +203,15 @@ extern boolean_t zfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup,
 extern boolean_t zfs_fuid_overobjquota(zfsvfs_t *zfsvfs, boolean_t isgroup,
     uint64_t fuid);
 extern int zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers);
-extern int zfsvfs_create(const char *name, zfs_mntopts_t *zmo, zfsvfs_t **zfvp);
+extern int zfsvfs_create(const char *name, zfsvfs_t **zfvp);
 extern void zfsvfs_free(zfsvfs_t *zfsvfs);
 extern int zfs_check_global_label(const char *dsname, const char *hexsl);
 
 extern boolean_t zfs_is_readonly(zfsvfs_t *zfsvfs);
-extern zfs_mntopts_t *zfs_mntopts_alloc(void);
-extern void zfs_mntopts_free(zfs_mntopts_t *zmo);
-extern int zfs_domount(struct super_block *sb, zfs_mntopts_t *zmo, int silent);
+extern int zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent);
 extern void zfs_preumount(struct super_block *sb);
 extern int zfs_umount(struct super_block *sb);
-extern int zfs_remount(struct super_block *sb, int *flags, zfs_mntopts_t *zmo);
+extern int zfs_remount(struct super_block *sb, int *flags, zfs_mnt_t *zm);
 extern int zfs_statvfs(struct dentry *dentry, struct kstatfs *statp);
 extern int zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp);
 extern int zfs_prune(struct super_block *sb, unsigned long nr_to_scan,
index 5d713f6d7343b0c66c69a09363d197faf6d86022..eea1bb2e80317f163db82381c7eab5fae5940f4b 100644 (file)
@@ -746,7 +746,7 @@ zfsctl_snapshot_path_objset(zfsvfs_t *zfsvfs, uint64_t objsetid,
        uint64_t id, pos = 0;
        int error = 0;
 
-       if (zfsvfs->z_mntopts->z_mntpoint == NULL)
+       if (zfsvfs->z_vfs->vfs_mntpoint == NULL)
                return (ENOENT);
 
        cookie = spl_fstrans_mark();
@@ -767,7 +767,7 @@ zfsctl_snapshot_path_objset(zfsvfs_t *zfsvfs, uint64_t objsetid,
 
        memset(full_path, 0, path_len);
        snprintf(full_path, path_len - 1, "%s/.zfs/snapshot/%s",
-           zfsvfs->z_mntopts->z_mntpoint, snapname);
+           zfsvfs->z_vfs->vfs_mntpoint, snapname);
 out:
        kmem_free(snapname, ZFS_MAX_DATASET_NAME_LEN);
        spl_fstrans_unmark(cookie);
index e89306a592f3d76faa380482b926a5894b004bae..6df61fecb8315632fd4d38d8f4f38f993e92634c 100644 (file)
@@ -1431,7 +1431,7 @@ zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer)
        int error = 0;
 
        if (getzfsvfs(name, zfvp) != 0)
-               error = zfsvfs_create(name, NULL, zfvp);
+               error = zfsvfs_create(name, zfvp);
        if (error == 0) {
                rrm_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER :
                    RW_READER, tag);
index c55c5008836a2633fe3e84b4cd908a6ee18c1342..9f01d30d39871b5b801696bcfd327c4ac1ba88d7 100644 (file)
 #include <sys/zpl.h>
 #include "zfs_comutil.h"
 
+enum {
+       TOKEN_RO,
+       TOKEN_RW,
+       TOKEN_SETUID,
+       TOKEN_NOSETUID,
+       TOKEN_EXEC,
+       TOKEN_NOEXEC,
+       TOKEN_DEVICES,
+       TOKEN_NODEVICES,
+       TOKEN_DIRXATTR,
+       TOKEN_SAXATTR,
+       TOKEN_XATTR,
+       TOKEN_NOXATTR,
+       TOKEN_ATIME,
+       TOKEN_NOATIME,
+       TOKEN_RELATIME,
+       TOKEN_NORELATIME,
+       TOKEN_NBMAND,
+       TOKEN_NONBMAND,
+       TOKEN_MNTPOINT,
+       TOKEN_LAST,
+};
+
+static const match_table_t zpl_tokens = {
+       { TOKEN_RO,             MNTOPT_RO },
+       { TOKEN_RW,             MNTOPT_RW },
+       { TOKEN_SETUID,         MNTOPT_SETUID },
+       { TOKEN_NOSETUID,       MNTOPT_NOSETUID },
+       { TOKEN_EXEC,           MNTOPT_EXEC },
+       { TOKEN_NOEXEC,         MNTOPT_NOEXEC },
+       { TOKEN_DEVICES,        MNTOPT_DEVICES },
+       { TOKEN_NODEVICES,      MNTOPT_NODEVICES },
+       { TOKEN_DIRXATTR,       MNTOPT_DIRXATTR },
+       { TOKEN_SAXATTR,        MNTOPT_SAXATTR },
+       { TOKEN_XATTR,          MNTOPT_XATTR },
+       { TOKEN_NOXATTR,        MNTOPT_NOXATTR },
+       { TOKEN_ATIME,          MNTOPT_ATIME },
+       { TOKEN_NOATIME,        MNTOPT_NOATIME },
+       { TOKEN_RELATIME,       MNTOPT_RELATIME },
+       { TOKEN_NORELATIME,     MNTOPT_NORELATIME },
+       { TOKEN_NBMAND,         MNTOPT_NBMAND },
+       { TOKEN_NONBMAND,       MNTOPT_NONBMAND },
+       { TOKEN_MNTPOINT,       MNTOPT_MNTPOINT "=%s" },
+       { TOKEN_LAST,           NULL },
+};
+
+static void
+zfsvfs_vfs_free(vfs_t *vfsp)
+{
+       if (vfsp != NULL) {
+               if (vfsp->vfs_mntpoint != NULL)
+                       strfree(vfsp->vfs_mntpoint);
+
+               kmem_free(vfsp, sizeof (vfs_t));
+       }
+}
+
+static int
+zfsvfs_parse_option(char *option, int token, substring_t *args, vfs_t *vfsp)
+{
+       switch (token) {
+       case TOKEN_RO:
+               vfsp->vfs_readonly = B_TRUE;
+               vfsp->vfs_do_readonly = B_TRUE;
+               break;
+       case TOKEN_RW:
+               vfsp->vfs_readonly = B_FALSE;
+               vfsp->vfs_do_readonly = B_TRUE;
+               break;
+       case TOKEN_SETUID:
+               vfsp->vfs_setuid = B_TRUE;
+               vfsp->vfs_do_setuid = B_TRUE;
+               break;
+       case TOKEN_NOSETUID:
+               vfsp->vfs_setuid = B_FALSE;
+               vfsp->vfs_do_setuid = B_TRUE;
+               break;
+       case TOKEN_EXEC:
+               vfsp->vfs_exec = B_TRUE;
+               vfsp->vfs_do_exec = B_TRUE;
+               break;
+       case TOKEN_NOEXEC:
+               vfsp->vfs_exec = B_FALSE;
+               vfsp->vfs_do_exec = B_TRUE;
+               break;
+       case TOKEN_DEVICES:
+               vfsp->vfs_devices = B_TRUE;
+               vfsp->vfs_do_devices = B_TRUE;
+               break;
+       case TOKEN_NODEVICES:
+               vfsp->vfs_devices = B_FALSE;
+               vfsp->vfs_do_devices = B_TRUE;
+               break;
+       case TOKEN_DIRXATTR:
+               vfsp->vfs_xattr = ZFS_XATTR_DIR;
+               vfsp->vfs_do_xattr = B_TRUE;
+               break;
+       case TOKEN_SAXATTR:
+               vfsp->vfs_xattr = ZFS_XATTR_SA;
+               vfsp->vfs_do_xattr = B_TRUE;
+               break;
+       case TOKEN_XATTR:
+               vfsp->vfs_xattr = ZFS_XATTR_DIR;
+               vfsp->vfs_do_xattr = B_TRUE;
+               break;
+       case TOKEN_NOXATTR:
+               vfsp->vfs_xattr = ZFS_XATTR_OFF;
+               vfsp->vfs_do_xattr = B_TRUE;
+               break;
+       case TOKEN_ATIME:
+               vfsp->vfs_atime = B_TRUE;
+               vfsp->vfs_do_atime = B_TRUE;
+               break;
+       case TOKEN_NOATIME:
+               vfsp->vfs_atime = B_FALSE;
+               vfsp->vfs_do_atime = B_TRUE;
+               break;
+       case TOKEN_RELATIME:
+               vfsp->vfs_relatime = B_TRUE;
+               vfsp->vfs_do_relatime = B_TRUE;
+               break;
+       case TOKEN_NORELATIME:
+               vfsp->vfs_relatime = B_FALSE;
+               vfsp->vfs_do_relatime = B_TRUE;
+               break;
+       case TOKEN_NBMAND:
+               vfsp->vfs_nbmand = B_TRUE;
+               vfsp->vfs_do_nbmand = B_TRUE;
+               break;
+       case TOKEN_NONBMAND:
+               vfsp->vfs_nbmand = B_FALSE;
+               vfsp->vfs_do_nbmand = B_TRUE;
+               break;
+       case TOKEN_MNTPOINT:
+               vfsp->vfs_mntpoint = match_strdup(&args[0]);
+               if (vfsp->vfs_mntpoint == NULL)
+                       return (SET_ERROR(ENOMEM));
+
+               break;
+       default:
+               break;
+       }
+
+       return (0);
+}
+
+/*
+ * Parse the raw mntopts and return a vfs_t describing the options.
+ */
+static int
+zfsvfs_parse_options(char *mntopts, vfs_t **vfsp)
+{
+       vfs_t *tmp_vfsp;
+       int error;
+
+       tmp_vfsp = kmem_zalloc(sizeof (vfs_t), KM_SLEEP);
+
+       if (mntopts != NULL) {
+               substring_t args[MAX_OPT_ARGS];
+               char *tmp_mntopts, *p, *t;
+               int token;
+
+               tmp_mntopts = t = strdup(mntopts);
+               if (tmp_mntopts == NULL)
+                       return (SET_ERROR(ENOMEM));
+
+               while ((p = strsep(&t, ",")) != NULL) {
+                       if (!*p)
+                               continue;
+
+                       args[0].to = args[0].from = NULL;
+                       token = match_token(p, zpl_tokens, args);
+                       error = zfsvfs_parse_option(p, token, args, tmp_vfsp);
+                       if (error) {
+                               strfree(tmp_mntopts);
+                               zfsvfs_vfs_free(tmp_vfsp);
+                               return (error);
+                       }
+               }
+
+               strfree(tmp_mntopts);
+       }
+
+       *vfsp = tmp_vfsp;
+
+       return (0);
+}
+
+boolean_t
+zfs_is_readonly(zfsvfs_t *zfsvfs)
+{
+       return (!!(zfsvfs->z_sb->s_flags & MS_RDONLY));
+}
+
 /*ARGSUSED*/
 int
 zfs_sync(struct super_block *sb, int wait, cred_t *cr)
@@ -122,12 +316,6 @@ zfs_sync(struct super_block *sb, int wait, cred_t *cr)
        return (0);
 }
 
-boolean_t
-zfs_is_readonly(zfsvfs_t *zfsvfs)
-{
-       return (!!(zfsvfs->z_sb->s_flags & MS_RDONLY));
-}
-
 static void
 atime_changed_cb(void *arg, uint64_t newval)
 {
@@ -255,16 +443,18 @@ acl_inherit_changed_cb(void *arg, uint64_t newval)
        ((zfsvfs_t *)arg)->z_acl_inherit = newval;
 }
 
-int
-zfs_register_callbacks(zfsvfs_t *zfsvfs)
+static int
+zfs_register_callbacks(vfs_t *vfsp)
 {
        struct dsl_dataset *ds = NULL;
-       objset_t *os = zfsvfs->z_os;
-       zfs_mntopts_t *zmo = zfsvfs->z_mntopts;
+       objset_t *os = NULL;
+       zfsvfs_t *zfsvfs = NULL;
        int error = 0;
 
+       ASSERT(vfsp);
+       zfsvfs = vfsp->vfs_data;
        ASSERT(zfsvfs);
-       ASSERT(zmo);
+       os = zfsvfs->z_os;
 
        /*
         * The act of registering our callbacks will destroy any mount
@@ -273,8 +463,8 @@ zfs_register_callbacks(zfsvfs_t *zfsvfs)
         * restore them after we register the callbacks.
         */
        if (zfs_is_readonly(zfsvfs) || !spa_writeable(dmu_objset_spa(os))) {
-               zmo->z_do_readonly = B_TRUE;
-               zmo->z_readonly = B_TRUE;
+               vfsp->vfs_do_readonly = B_TRUE;
+               vfsp->vfs_readonly = B_TRUE;
        }
 
        /*
@@ -320,22 +510,22 @@ zfs_register_callbacks(zfsvfs_t *zfsvfs)
        /*
         * Invoke our callbacks to restore temporary mount options.
         */
-       if (zmo->z_do_readonly)
-               readonly_changed_cb(zfsvfs, zmo->z_readonly);
-       if (zmo->z_do_setuid)
-               setuid_changed_cb(zfsvfs, zmo->z_setuid);
-       if (zmo->z_do_exec)
-               exec_changed_cb(zfsvfs, zmo->z_exec);
-       if (zmo->z_do_devices)
-               devices_changed_cb(zfsvfs, zmo->z_devices);
-       if (zmo->z_do_xattr)
-               xattr_changed_cb(zfsvfs, zmo->z_xattr);
-       if (zmo->z_do_atime)
-               atime_changed_cb(zfsvfs, zmo->z_atime);
-       if (zmo->z_do_relatime)
-               relatime_changed_cb(zfsvfs, zmo->z_relatime);
-       if (zmo->z_do_nbmand)
-               nbmand_changed_cb(zfsvfs, zmo->z_nbmand);
+       if (vfsp->vfs_do_readonly)
+               readonly_changed_cb(zfsvfs, vfsp->vfs_readonly);
+       if (vfsp->vfs_do_setuid)
+               setuid_changed_cb(zfsvfs, vfsp->vfs_setuid);
+       if (vfsp->vfs_do_exec)
+               exec_changed_cb(zfsvfs, vfsp->vfs_exec);
+       if (vfsp->vfs_do_devices)
+               devices_changed_cb(zfsvfs, vfsp->vfs_devices);
+       if (vfsp->vfs_do_xattr)
+               xattr_changed_cb(zfsvfs, vfsp->vfs_xattr);
+       if (vfsp->vfs_do_atime)
+               atime_changed_cb(zfsvfs, vfsp->vfs_atime);
+       if (vfsp->vfs_do_relatime)
+               relatime_changed_cb(zfsvfs, vfsp->vfs_relatime);
+       if (vfsp->vfs_do_nbmand)
+               nbmand_changed_cb(zfsvfs, vfsp->vfs_nbmand);
 
        return (0);
 
@@ -708,26 +898,8 @@ zfs_owner_overquota(zfsvfs_t *zfsvfs, znode_t *zp, boolean_t isgroup)
        return (zfs_fuid_overquota(zfsvfs, isgroup, fuid));
 }
 
-zfs_mntopts_t *
-zfs_mntopts_alloc(void)
-{
-       return (kmem_zalloc(sizeof (zfs_mntopts_t), KM_SLEEP));
-}
-
-void
-zfs_mntopts_free(zfs_mntopts_t *zmo)
-{
-       if (zmo->z_osname)
-               strfree(zmo->z_osname);
-
-       if (zmo->z_mntpoint)
-               strfree(zmo->z_mntpoint);
-
-       kmem_free(zmo, sizeof (zfs_mntopts_t));
-}
-
 int
-zfsvfs_create(const char *osname, zfs_mntopts_t *zmo, zfsvfs_t **zfvp)
+zfsvfs_create(const char *osname, zfsvfs_t **zfvp)
 {
        objset_t *os;
        zfsvfs_t *zfsvfs;
@@ -737,23 +909,21 @@ zfsvfs_create(const char *osname, zfs_mntopts_t *zmo, zfsvfs_t **zfvp)
 
        zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP);
 
-       /*
-        * Optional temporary mount options, free'd in zfsvfs_free().
-        */
-       zfsvfs->z_mntopts = (zmo ? zmo : zfs_mntopts_alloc());
-
        /*
         * We claim to always be readonly so we can open snapshots;
         * other ZPL code will prevent us from writing to snapshots.
         */
        error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zfsvfs, &os);
-       if (error)
-               goto out_zmo;
+       if (error) {
+               kmem_free(zfsvfs, sizeof (zfsvfs_t));
+               return (error);
+       }
 
        /*
         * Initialize the zfs-specific filesystem structure.
         * Should probably make this a kmem cache, shuffle fields.
         */
+       zfsvfs->z_vfs = NULL;
        zfsvfs->z_sb = NULL;
        zfsvfs->z_parent = zfsvfs;
        zfsvfs->z_max_blksz = SPA_OLD_MAXBLOCKSIZE;
@@ -889,9 +1059,7 @@ zfsvfs_create(const char *osname, zfs_mntopts_t *zmo, zfsvfs_t **zfvp)
 
 out:
        dmu_objset_disown(os, zfsvfs);
-out_zmo:
        *zfvp = NULL;
-       zfs_mntopts_free(zfsvfs->z_mntopts);
        kmem_free(zfsvfs, sizeof (zfsvfs_t));
        return (error);
 }
@@ -901,7 +1069,7 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
 {
        int error;
 
-       error = zfs_register_callbacks(zfsvfs);
+       error = zfs_register_callbacks(zfsvfs->z_vfs);
        if (error)
                return (error);
 
@@ -997,7 +1165,7 @@ zfsvfs_free(zfsvfs_t *zfsvfs)
        }
        vmem_free(zfsvfs->z_hold_trees, sizeof (avl_tree_t) * size);
        vmem_free(zfsvfs->z_hold_locks, sizeof (kmutex_t) * size);
-       zfs_mntopts_free(zfsvfs->z_mntopts);
+       zfsvfs_vfs_free(zfsvfs->z_vfs);
        kmem_free(zfsvfs, sizeof (zfsvfs_t));
 }
 
@@ -1380,22 +1548,30 @@ atomic_long_t zfs_bdi_seq = ATOMIC_LONG_INIT(0);
 #endif
 
 int
-zfs_domount(struct super_block *sb, zfs_mntopts_t *zmo, int silent)
+zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent)
 {
-       const char *osname = zmo->z_osname;
-       zfsvfs_t *zfsvfs;
+       const char *osname = zm->mnt_osname;
        struct inode *root_inode;
        uint64_t recordsize;
-       int error;
+       int error = 0;
+       zfsvfs_t *zfsvfs;
+
+       ASSERT(zm);
+       ASSERT(osname);
 
-       error = zfsvfs_create(osname, zmo, &zfsvfs);
+       error = zfsvfs_create(osname, &zfsvfs);
        if (error)
                return (error);
 
+       error = zfsvfs_parse_options(zm->mnt_data, &zfsvfs->z_vfs);
+       if (error)
+               goto out;
+
        if ((error = dsl_prop_get_integer(osname, "recordsize",
            &recordsize, NULL)))
                goto out;
 
+       zfsvfs->z_vfs->vfs_data = zfsvfs;
        zfsvfs->z_sb = sb;
        sb->s_fs_info = zfsvfs;
        sb->s_magic = ZFS_SUPER_MAGIC;
@@ -1555,13 +1731,22 @@ zfs_umount(struct super_block *sb)
 }
 
 int
-zfs_remount(struct super_block *sb, int *flags, zfs_mntopts_t *zmo)
+zfs_remount(struct super_block *sb, int *flags, zfs_mnt_t *zm)
 {
        zfsvfs_t *zfsvfs = sb->s_fs_info;
+       vfs_t *vfsp;
        int error;
 
+       error = zfsvfs_parse_options(zm->mnt_data, &vfsp);
+       if (error)
+               return (error);
+
        zfs_unregister_callbacks(zfsvfs);
-       error = zfs_register_callbacks(zfsvfs);
+       zfsvfs_vfs_free(zfsvfs->z_vfs);
+
+       vfsp->vfs_data = zfsvfs;
+       zfsvfs->z_vfs = vfsp;
+       (void) zfs_register_callbacks(vfsp);
 
        return (error);
 }
index 16017ff447a5b29f182ae503713ea0ab439179a9..b6ef60277664b76b086ad5ba7836a9163ace5ece 100644 (file)
@@ -184,211 +184,15 @@ zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
        return (error);
 }
 
-enum {
-       TOKEN_RO,
-       TOKEN_RW,
-       TOKEN_SETUID,
-       TOKEN_NOSETUID,
-       TOKEN_EXEC,
-       TOKEN_NOEXEC,
-       TOKEN_DEVICES,
-       TOKEN_NODEVICES,
-       TOKEN_DIRXATTR,
-       TOKEN_SAXATTR,
-       TOKEN_XATTR,
-       TOKEN_NOXATTR,
-       TOKEN_ATIME,
-       TOKEN_NOATIME,
-       TOKEN_RELATIME,
-       TOKEN_NORELATIME,
-       TOKEN_NBMAND,
-       TOKEN_NONBMAND,
-       TOKEN_MNTPOINT,
-       TOKEN_LAST,
-};
-
-static const match_table_t zpl_tokens = {
-       { TOKEN_RO,             MNTOPT_RO },
-       { TOKEN_RW,             MNTOPT_RW },
-       { TOKEN_SETUID,         MNTOPT_SETUID },
-       { TOKEN_NOSETUID,       MNTOPT_NOSETUID },
-       { TOKEN_EXEC,           MNTOPT_EXEC },
-       { TOKEN_NOEXEC,         MNTOPT_NOEXEC },
-       { TOKEN_DEVICES,        MNTOPT_DEVICES },
-       { TOKEN_NODEVICES,      MNTOPT_NODEVICES },
-       { TOKEN_DIRXATTR,       MNTOPT_DIRXATTR },
-       { TOKEN_SAXATTR,        MNTOPT_SAXATTR },
-       { TOKEN_XATTR,          MNTOPT_XATTR },
-       { TOKEN_NOXATTR,        MNTOPT_NOXATTR },
-       { TOKEN_ATIME,          MNTOPT_ATIME },
-       { TOKEN_NOATIME,        MNTOPT_NOATIME },
-       { TOKEN_RELATIME,       MNTOPT_RELATIME },
-       { TOKEN_NORELATIME,     MNTOPT_NORELATIME },
-       { TOKEN_NBMAND,         MNTOPT_NBMAND },
-       { TOKEN_NONBMAND,       MNTOPT_NONBMAND },
-       { TOKEN_MNTPOINT,       MNTOPT_MNTPOINT "=%s" },
-       { TOKEN_LAST,           NULL },
-};
-
-static int
-zpl_parse_option(char *option, int token, substring_t *args, zfs_mntopts_t *zmo)
-{
-       switch (token) {
-       case TOKEN_RO:
-               zmo->z_readonly = B_TRUE;
-               zmo->z_do_readonly = B_TRUE;
-               break;
-       case TOKEN_RW:
-               zmo->z_readonly = B_FALSE;
-               zmo->z_do_readonly = B_TRUE;
-               break;
-       case TOKEN_SETUID:
-               zmo->z_setuid = B_TRUE;
-               zmo->z_do_setuid = B_TRUE;
-               break;
-       case TOKEN_NOSETUID:
-               zmo->z_setuid = B_FALSE;
-               zmo->z_do_setuid = B_TRUE;
-               break;
-       case TOKEN_EXEC:
-               zmo->z_exec = B_TRUE;
-               zmo->z_do_exec = B_TRUE;
-               break;
-       case TOKEN_NOEXEC:
-               zmo->z_exec = B_FALSE;
-               zmo->z_do_exec = B_TRUE;
-               break;
-       case TOKEN_DEVICES:
-               zmo->z_devices = B_TRUE;
-               zmo->z_do_devices = B_TRUE;
-               break;
-       case TOKEN_NODEVICES:
-               zmo->z_devices = B_FALSE;
-               zmo->z_do_devices = B_TRUE;
-               break;
-       case TOKEN_DIRXATTR:
-               zmo->z_xattr = ZFS_XATTR_DIR;
-               zmo->z_do_xattr = B_TRUE;
-               break;
-       case TOKEN_SAXATTR:
-               zmo->z_xattr = ZFS_XATTR_SA;
-               zmo->z_do_xattr = B_TRUE;
-               break;
-       case TOKEN_XATTR:
-               zmo->z_xattr = ZFS_XATTR_DIR;
-               zmo->z_do_xattr = B_TRUE;
-               break;
-       case TOKEN_NOXATTR:
-               zmo->z_xattr = ZFS_XATTR_OFF;
-               zmo->z_do_xattr = B_TRUE;
-               break;
-       case TOKEN_ATIME:
-               zmo->z_atime = B_TRUE;
-               zmo->z_do_atime = B_TRUE;
-               break;
-       case TOKEN_NOATIME:
-               zmo->z_atime = B_FALSE;
-               zmo->z_do_atime = B_TRUE;
-               break;
-       case TOKEN_RELATIME:
-               zmo->z_relatime = B_TRUE;
-               zmo->z_do_relatime = B_TRUE;
-               break;
-       case TOKEN_NORELATIME:
-               zmo->z_relatime = B_FALSE;
-               zmo->z_do_relatime = B_TRUE;
-               break;
-       case TOKEN_NBMAND:
-               zmo->z_nbmand = B_TRUE;
-               zmo->z_do_nbmand = B_TRUE;
-               break;
-       case TOKEN_NONBMAND:
-               zmo->z_nbmand = B_FALSE;
-               zmo->z_do_nbmand = B_TRUE;
-               break;
-       case TOKEN_MNTPOINT:
-               zmo->z_mntpoint = match_strdup(&args[0]);
-               if (zmo->z_mntpoint == NULL)
-                       return (-ENOMEM);
-
-               break;
-       default:
-               break;
-       }
-
-       return (0);
-}
-
-/*
- * Parse the mntopts string storing the results in provided zmo argument.
- * If an error occurs the zmo argument will not be modified.  The caller
- * needs to set isremount when recycling an existing zfs_mntopts_t.
- */
-static int
-zpl_parse_options(char *osname, char *mntopts, zfs_mntopts_t *zmo,
-    boolean_t isremount)
-{
-       zfs_mntopts_t *tmp_zmo;
-       int error;
-
-       tmp_zmo = zfs_mntopts_alloc();
-       tmp_zmo->z_osname = strdup(osname);
-
-       if (mntopts) {
-               substring_t args[MAX_OPT_ARGS];
-               char *tmp_mntopts, *p, *t;
-               int token;
-
-               t = tmp_mntopts = strdup(mntopts);
-
-               while ((p = strsep(&t, ",")) != NULL) {
-                       if (!*p)
-                               continue;
-
-                       args[0].to = args[0].from = NULL;
-                       token = match_token(p, zpl_tokens, args);
-                       error = zpl_parse_option(p, token, args, tmp_zmo);
-                       if (error) {
-                               zfs_mntopts_free(tmp_zmo);
-                               strfree(tmp_mntopts);
-                               return (error);
-                       }
-               }
-
-               strfree(tmp_mntopts);
-       }
-
-       if (isremount == B_TRUE) {
-               if (zmo->z_osname)
-                       strfree(zmo->z_osname);
-
-               if (zmo->z_mntpoint)
-                       strfree(zmo->z_mntpoint);
-       } else {
-               ASSERT3P(zmo->z_osname, ==, NULL);
-               ASSERT3P(zmo->z_mntpoint, ==, NULL);
-       }
-
-       memcpy(zmo, tmp_zmo, sizeof (zfs_mntopts_t));
-       kmem_free(tmp_zmo, sizeof (zfs_mntopts_t));
-
-       return (0);
-}
-
 static int
 zpl_remount_fs(struct super_block *sb, int *flags, char *data)
 {
-       zfsvfs_t *zfsvfs = sb->s_fs_info;
+       zfs_mnt_t zm = { .mnt_osname = NULL, .mnt_data = data };
        fstrans_cookie_t cookie;
        int error;
 
-       error = zpl_parse_options(zfsvfs->z_mntopts->z_osname, data,
-           zfsvfs->z_mntopts, B_TRUE);
-       if (error)
-               return (error);
-
        cookie = spl_fstrans_mark();
-       error = -zfs_remount(sb, flags, zfsvfs->z_mntopts);
+       error = -zfs_remount(sb, flags, &zm);
        spl_fstrans_unmark(cookie);
        ASSERT3S(error, <=, 0);
 
@@ -432,12 +236,12 @@ zpl_show_options(struct seq_file *seq, struct vfsmount *vfsp)
 static int
 zpl_fill_super(struct super_block *sb, void *data, int silent)
 {
-       zfs_mntopts_t *zmo = (zfs_mntopts_t *)data;
+       zfs_mnt_t *zm = (zfs_mnt_t *)data;
        fstrans_cookie_t cookie;
        int error;
 
        cookie = spl_fstrans_mark();
-       error = -zfs_domount(sb, zmo, silent);
+       error = -zfs_domount(sb, zm, silent);
        spl_fstrans_unmark(cookie);
        ASSERT3S(error, <=, 0);
 
@@ -449,32 +253,18 @@ static struct dentry *
 zpl_mount(struct file_system_type *fs_type, int flags,
     const char *osname, void *data)
 {
-       zfs_mntopts_t *zmo = zfs_mntopts_alloc();
-       int error;
-
-       error = zpl_parse_options((char *)osname, (char *)data, zmo, B_FALSE);
-       if (error) {
-               zfs_mntopts_free(zmo);
-               return (ERR_PTR(error));
-       }
+       zfs_mnt_t zm = { .mnt_osname = osname, .mnt_data = data };
 
-       return (mount_nodev(fs_type, flags, zmo, zpl_fill_super));
+       return (mount_nodev(fs_type, flags, &zm, zpl_fill_super));
 }
 #else
 static int
 zpl_get_sb(struct file_system_type *fs_type, int flags,
     const char *osname, void *data, struct vfsmount *mnt)
 {
-       zfs_mntopts_t *zmo = zfs_mntopts_alloc();
-       int error;
-
-       error = zpl_parse_options((char *)osname, (char *)data, zmo, B_FALSE);
-       if (error) {
-               zfs_mntopts_free(zmo);
-               return (error);
-       }
+       zfs_mnt_t zm = { .mnt_osname = osname, .mnt_data = data };
 
-       return (get_sb_nodev(fs_type, flags, zmo, zpl_fill_super, mnt));
+       return (get_sb_nodev(fs_type, flags, &zm, zpl_fill_super, mnt));
 }
 #endif /* HAVE_MOUNT_NODEV */