summaryrefslogtreecommitdiffstats
path: root/module/os
diff options
context:
space:
mode:
authorMatthew Macy <[email protected]>2019-09-27 10:46:28 -0700
committerBrian Behlendorf <[email protected]>2019-09-27 10:46:28 -0700
commit7bb0c294688ed121477536d7b4a7031c78a5706a (patch)
treee3e78a38a6139bcd32c57d4a67ae08fcb5552a1c /module/os
parent3768db24abe09f964a976945faeb805214817626 (diff)
OpenZFS restructuring - zfs_ioctl
Refactor the zfs ioctls in to platform dependent and independent bits. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Sean Eric Fagan <[email protected]> Signed-off-by: Matthew Macy <[email protected]> Signed-off-by: Ryan Moeller <[email protected]> Closes #9301
Diffstat (limited to 'module/os')
-rw-r--r--module/os/linux/zfs/Makefile.in1
-rw-r--r--module/os/linux/zfs/zfs_ioctl_os.c322
2 files changed, 323 insertions, 0 deletions
diff --git a/module/os/linux/zfs/Makefile.in b/module/os/linux/zfs/Makefile.in
index a4f198907..1a7ea0d69 100644
--- a/module/os/linux/zfs/Makefile.in
+++ b/module/os/linux/zfs/Makefile.in
@@ -22,6 +22,7 @@ $(MODULE)-objs += ../os/linux/zfs/zfs_acl.o
$(MODULE)-objs += ../os/linux/zfs/zfs_ctldir.o
$(MODULE)-objs += ../os/linux/zfs/zfs_debug.o
$(MODULE)-objs += ../os/linux/zfs/zfs_dir.o
+$(MODULE)-objs += ../os/linux/zfs/zfs_ioctl_os.o
$(MODULE)-objs += ../os/linux/zfs/zfs_sysfs.o
$(MODULE)-objs += ../os/linux/zfs/zfs_vfsops.o
$(MODULE)-objs += ../os/linux/zfs/zfs_vnops.o
diff --git a/module/os/linux/zfs/zfs_ioctl_os.c b/module/os/linux/zfs/zfs_ioctl_os.c
new file mode 100644
index 000000000..9b562cab3
--- /dev/null
+++ b/module/os/linux/zfs/zfs_ioctl_os.c
@@ -0,0 +1,322 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Portions Copyright 2011 Martin Matuska
+ * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
+ * Portions Copyright 2012 Pawel Jakub Dawidek <[email protected]>
+ * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved.
+ * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ * Copyright (c) 2014 Integros [integros.com]
+ * Copyright 2016 Toomas Soome <[email protected]>
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2018, loli10K <[email protected]>. All rights reserved.
+ * Copyright 2017 RackTop Systems.
+ * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
+ * Copyright (c) 2019 Datto Inc.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/file.h>
+#include <sys/kmem.h>
+#include <sys/stat.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zfs_vfsops.h>
+#include <sys/zap.h>
+#include <sys/spa.h>
+#include <sys/nvpair.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_ctldir.h>
+#include <sys/zfs_dir.h>
+#include <sys/zfs_onexit.h>
+#include <sys/zvol.h>
+#include <sys/fm/util.h>
+#include <sys/dsl_crypt.h>
+
+#include <sys/zfs_ioctl_impl.h>
+
+#include <sys/zfs_sysfs.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+
+int
+zfs_vfs_ref(zfsvfs_t **zfvp)
+{
+ if (*zfvp == NULL || (*zfvp)->z_sb == NULL ||
+ !atomic_inc_not_zero(&((*zfvp)->z_sb->s_active))) {
+ return (SET_ERROR(ESRCH));
+ }
+ return (0);
+}
+
+static int
+zfsdev_state_init(struct file *filp)
+{
+ zfsdev_state_t *zs, *zsprev = NULL;
+ minor_t minor;
+ boolean_t newzs = B_FALSE;
+
+ ASSERT(MUTEX_HELD(&zfsdev_state_lock));
+
+ minor = zfsdev_minor_alloc();
+ if (minor == 0)
+ return (SET_ERROR(ENXIO));
+
+ for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
+ if (zs->zs_minor == -1)
+ break;
+ zsprev = zs;
+ }
+
+ if (!zs) {
+ zs = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP);
+ newzs = B_TRUE;
+ }
+
+ zs->zs_file = filp;
+ filp->private_data = zs;
+
+ zfs_onexit_init((zfs_onexit_t **)&zs->zs_onexit);
+ zfs_zevent_init((zfs_zevent_t **)&zs->zs_zevent);
+
+ /*
+ * In order to provide for lock-free concurrent read access
+ * to the minor list in zfsdev_get_state_impl(), new entries
+ * must be completely written before linking them into the
+ * list whereas existing entries are already linked; the last
+ * operation must be updating zs_minor (from -1 to the new
+ * value).
+ */
+ if (newzs) {
+ zs->zs_minor = minor;
+ smp_wmb();
+ zsprev->zs_next = zs;
+ } else {
+ smp_wmb();
+ zs->zs_minor = minor;
+ }
+
+ return (0);
+}
+
+static int
+zfsdev_state_destroy(struct file *filp)
+{
+ zfsdev_state_t *zs;
+
+ ASSERT(MUTEX_HELD(&zfsdev_state_lock));
+ ASSERT(filp->private_data != NULL);
+
+ zs = filp->private_data;
+ zs->zs_minor = -1;
+ zfs_onexit_destroy(zs->zs_onexit);
+ zfs_zevent_destroy(zs->zs_zevent);
+
+ return (0);
+}
+
+static int
+zfsdev_open(struct inode *ino, struct file *filp)
+{
+ int error;
+
+ mutex_enter(&zfsdev_state_lock);
+ error = zfsdev_state_init(filp);
+ mutex_exit(&zfsdev_state_lock);
+
+ return (-error);
+}
+
+static int
+zfsdev_release(struct inode *ino, struct file *filp)
+{
+ int error;
+
+ mutex_enter(&zfsdev_state_lock);
+ error = zfsdev_state_destroy(filp);
+ mutex_exit(&zfsdev_state_lock);
+
+ return (-error);
+}
+
+static long
+zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
+{
+ uint_t vecnum;
+
+ vecnum = cmd - ZFS_IOC_FIRST;
+ return (zfsdev_ioctl_common(vecnum, arg));
+}
+
+int
+zfsdev_getminor(struct file *filp, minor_t *minorp)
+{
+ zfsdev_state_t *zs, *fpd;
+
+ ASSERT(filp != NULL);
+ ASSERT(!MUTEX_HELD(&zfsdev_state_lock));
+
+ fpd = filp->private_data;
+ if (fpd == NULL)
+ return (SET_ERROR(EBADF));
+
+ mutex_enter(&zfsdev_state_lock);
+
+ for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
+
+ if (zs->zs_minor == -1)
+ continue;
+
+ if (fpd == zs) {
+ *minorp = fpd->zs_minor;
+ mutex_exit(&zfsdev_state_lock);
+ return (0);
+ }
+ }
+
+ mutex_exit(&zfsdev_state_lock);
+
+ return (SET_ERROR(EBADF));
+}
+
+void
+zfs_ioctl_init_os(void)
+{
+}
+
+#ifdef CONFIG_COMPAT
+static long
+zfsdev_compat_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
+{
+ return (zfsdev_ioctl(filp, cmd, arg));
+}
+#else
+#define zfsdev_compat_ioctl NULL
+#endif
+
+static const struct file_operations zfsdev_fops = {
+ .open = zfsdev_open,
+ .release = zfsdev_release,
+ .unlocked_ioctl = zfsdev_ioctl,
+ .compat_ioctl = zfsdev_compat_ioctl,
+ .owner = THIS_MODULE,
+};
+
+static struct miscdevice zfs_misc = {
+ .minor = ZFS_DEVICE_MINOR,
+ .name = ZFS_DRIVER,
+ .fops = &zfsdev_fops,
+};
+
+MODULE_ALIAS_MISCDEV(ZFS_DEVICE_MINOR);
+MODULE_ALIAS("devname:zfs");
+
+int
+zfsdev_attach(void)
+{
+ int error;
+
+ error = misc_register(&zfs_misc);
+ if (error == -EBUSY) {
+ /*
+ * Fallback to dynamic minor allocation in the event of a
+ * collision with a reserved minor in linux/miscdevice.h.
+ * In this case the kernel modules must be manually loaded.
+ */
+ printk(KERN_INFO "ZFS: misc_register() with static minor %d "
+ "failed %d, retrying with MISC_DYNAMIC_MINOR\n",
+ ZFS_DEVICE_MINOR, error);
+
+ zfs_misc.minor = MISC_DYNAMIC_MINOR;
+ error = misc_register(&zfs_misc);
+ }
+
+ if (error)
+ printk(KERN_INFO "ZFS: misc_register() failed %d\n", error);
+
+ return (error);
+}
+
+void
+zfsdev_detach(void)
+{
+ misc_deregister(&zfs_misc);
+}
+
+#ifdef DEBUG
+#define ZFS_DEBUG_STR " (DEBUG mode)"
+#else
+#define ZFS_DEBUG_STR ""
+#endif
+
+static int __init
+_init(void)
+{
+ int error;
+
+ if ((error = zfs_kmod_init()) != 0) {
+ printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s"
+ ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE,
+ ZFS_DEBUG_STR, error);
+
+ return (-error);
+ }
+
+ zfs_sysfs_init();
+
+ printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, "
+ "ZFS pool version %s, ZFS filesystem version %s\n",
+ ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR,
+ SPA_VERSION_STRING, ZPL_VERSION_STRING);
+#ifndef CONFIG_FS_POSIX_ACL
+ printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n");
+#endif /* CONFIG_FS_POSIX_ACL */
+
+ return (0);
+}
+
+static void __exit
+_fini(void)
+{
+ zfs_sysfs_fini();
+ zfs_kmod_fini();
+
+ printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n",
+ ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
+}
+
+#if defined(_KERNEL)
+module_init(_init);
+module_exit(_fini);
+
+MODULE_DESCRIPTION("ZFS");
+MODULE_AUTHOR(ZFS_META_AUTHOR);
+MODULE_LICENSE(ZFS_META_LICENSE);
+MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
+#endif