1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Portions Copyright 2011 Martin Matuska 25 * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. 26 * Portions Copyright 2012 Pawel Jakub Dawidek <pawel@dawidek.net> 27 * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved. 28 * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 29 * Copyright (c) 2014, Joyent, Inc. All rights reserved. 30 * Copyright (c) 2011, 2018 by Delphix. All rights reserved. 31 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. 32 * Copyright (c) 2013 Steven Hartland. All rights reserved. 33 * Copyright (c) 2014 Integros [integros.com] 34 * Copyright 2016 Toomas Soome <tsoome@me.com> 35 * Copyright (c) 2016 Actifio, Inc. All rights reserved. 36 * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. 37 * Copyright 2017 RackTop Systems. 38 * Copyright (c) 2017 Open-E, Inc. All Rights Reserved. 39 * Copyright (c) 2019 Datto Inc. 40 */ 41 42 #include <sys/types.h> 43 #include <sys/param.h> 44 #include <sys/errno.h> 45 #include <sys/uio.h> 46 #include <sys/file.h> 47 #include <sys/kmem.h> 48 #include <sys/stat.h> 49 #include <sys/zfs_ioctl.h> 50 #include <sys/zfs_vfsops.h> 51 #include <sys/zap.h> 52 #include <sys/spa.h> 53 #include <sys/nvpair.h> 54 #include <sys/fs/zfs.h> 55 #include <sys/zfs_ctldir.h> 56 #include <sys/zfs_dir.h> 57 #include <sys/zfs_onexit.h> 58 #include <sys/zvol.h> 59 #include <sys/fm/util.h> 60 #include <sys/dsl_crypt.h> 61 62 #include <sys/zfs_ioctl_impl.h> 63 64 #include <sys/zfs_sysfs.h> 65 #include <linux/miscdevice.h> 66 #include <linux/slab.h> 67 68 boolean_t 69 zfs_vfs_held(zfsvfs_t *zfsvfs) 70 { 71 return (zfsvfs->z_sb != NULL); 72 } 73 74 int 75 zfs_vfs_ref(zfsvfs_t **zfvp) 76 { 77 if (*zfvp == NULL || (*zfvp)->z_sb == NULL || 78 !atomic_inc_not_zero(&((*zfvp)->z_sb->s_active))) { 79 return (SET_ERROR(ESRCH)); 80 } 81 return (0); 82 } 83 84 void 85 zfs_vfs_rele(zfsvfs_t *zfsvfs) 86 { 87 deactivate_super(zfsvfs->z_sb); 88 } 89 90 void 91 zfsdev_private_set_state(void *priv, zfsdev_state_t *zs) 92 { 93 struct file *filp = priv; 94 95 filp->private_data = zs; 96 } 97 98 zfsdev_state_t * 99 zfsdev_private_get_state(void *priv) 100 { 101 struct file *filp = priv; 102 103 return (filp->private_data); 104 } 105 106 static int 107 zfsdev_open(struct inode *ino, struct file *filp) 108 { 109 int error; 110 111 mutex_enter(&zfsdev_state_lock); 112 error = zfsdev_state_init(filp); 113 mutex_exit(&zfsdev_state_lock); 114 115 return (-error); 116 } 117 118 static int 119 zfsdev_release(struct inode *ino, struct file *filp) 120 { 121 zfsdev_state_destroy(filp); 122 123 return (0); 124 } 125 126 static long 127 zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg) 128 { 129 uint_t vecnum; 130 zfs_cmd_t *zc; 131 int error, rc; 132 133 vecnum = cmd - ZFS_IOC_FIRST; 134 135 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); 136 137 if (ddi_copyin((void *)(uintptr_t)arg, zc, sizeof (zfs_cmd_t), 0)) { 138 error = -SET_ERROR(EFAULT); 139 goto out; 140 } 141 error = -zfsdev_ioctl_common(vecnum, zc, 0); 142 rc = ddi_copyout(zc, (void *)(uintptr_t)arg, sizeof (zfs_cmd_t), 0); 143 if (error == 0 && rc != 0) 144 error = -SET_ERROR(EFAULT); 145 out: 146 kmem_free(zc, sizeof (zfs_cmd_t)); 147 return (error); 148 149 } 150 151 uint64_t 152 zfs_max_nvlist_src_size_os(void) 153 { 154 if (zfs_max_nvlist_src_size != 0) 155 return (zfs_max_nvlist_src_size); 156 157 return (MIN(ptob(zfs_totalram_pages) / 4, 128 * 1024 * 1024)); 158 } 159 160 /* Update the VFS's cache of mountpoint properties */ 161 void 162 zfs_ioctl_update_mount_cache(const char *dsname) 163 { 164 } 165 166 void 167 zfs_ioctl_init_os(void) 168 { 169 } 170 171 #ifdef CONFIG_COMPAT 172 static long 173 zfsdev_compat_ioctl(struct file *filp, unsigned cmd, unsigned long arg) 174 { 175 return (zfsdev_ioctl(filp, cmd, arg)); 176 } 177 #else 178 #define zfsdev_compat_ioctl NULL 179 #endif 180 181 static const struct file_operations zfsdev_fops = { 182 .open = zfsdev_open, 183 .release = zfsdev_release, 184 .unlocked_ioctl = zfsdev_ioctl, 185 .compat_ioctl = zfsdev_compat_ioctl, 186 .owner = THIS_MODULE, 187 }; 188 189 static struct miscdevice zfs_misc = { 190 .minor = ZFS_DEVICE_MINOR, 191 .name = ZFS_DRIVER, 192 .fops = &zfsdev_fops, 193 }; 194 195 MODULE_ALIAS_MISCDEV(ZFS_DEVICE_MINOR); 196 MODULE_ALIAS("devname:zfs"); 197 198 int 199 zfsdev_attach(void) 200 { 201 int error; 202 203 error = misc_register(&zfs_misc); 204 if (error == -EBUSY) { 205 /* 206 * Fallback to dynamic minor allocation in the event of a 207 * collision with a reserved minor in linux/miscdevice.h. 208 * In this case the kernel modules must be manually loaded. 209 */ 210 printk(KERN_INFO "ZFS: misc_register() with static minor %d " 211 "failed %d, retrying with MISC_DYNAMIC_MINOR\n", 212 ZFS_DEVICE_MINOR, error); 213 214 zfs_misc.minor = MISC_DYNAMIC_MINOR; 215 error = misc_register(&zfs_misc); 216 } 217 218 if (error) 219 printk(KERN_INFO "ZFS: misc_register() failed %d\n", error); 220 221 return (error); 222 } 223 224 void 225 zfsdev_detach(void) 226 { 227 misc_deregister(&zfs_misc); 228 } 229 230 #ifdef ZFS_DEBUG 231 #define ZFS_DEBUG_STR " (DEBUG mode)" 232 #else 233 #define ZFS_DEBUG_STR "" 234 #endif 235 236 static int __init 237 openzfs_init(void) 238 { 239 int error; 240 241 if ((error = zfs_kmod_init()) != 0) { 242 printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s" 243 ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE, 244 ZFS_DEBUG_STR, error); 245 246 return (-error); 247 } 248 249 zfs_sysfs_init(); 250 251 printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, " 252 "ZFS pool version %s, ZFS filesystem version %s\n", 253 ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR, 254 SPA_VERSION_STRING, ZPL_VERSION_STRING); 255 #ifndef CONFIG_FS_POSIX_ACL 256 printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n"); 257 #endif /* CONFIG_FS_POSIX_ACL */ 258 259 return (0); 260 } 261 262 static void __exit 263 openzfs_fini(void) 264 { 265 zfs_sysfs_fini(); 266 zfs_kmod_fini(); 267 268 printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n", 269 ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR); 270 } 271 272 #if defined(_KERNEL) 273 module_init(openzfs_init); 274 module_exit(openzfs_fini); 275 #endif 276 277 ZFS_MODULE_DESCRIPTION("ZFS"); 278 ZFS_MODULE_AUTHOR(ZFS_META_AUTHOR); 279 ZFS_MODULE_LICENSE(ZFS_META_LICENSE); 280 ZFS_MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE); 281