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 static int 91 zfsdev_state_init(struct file *filp) 92 { 93 zfsdev_state_t *zs, *zsprev = NULL; 94 minor_t minor; 95 boolean_t newzs = B_FALSE; 96 97 ASSERT(MUTEX_HELD(&zfsdev_state_lock)); 98 99 minor = zfsdev_minor_alloc(); 100 if (minor == 0) 101 return (SET_ERROR(ENXIO)); 102 103 for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) { 104 if (zs->zs_minor == -1) 105 break; 106 zsprev = zs; 107 } 108 109 if (!zs) { 110 zs = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP); 111 newzs = B_TRUE; 112 } 113 114 filp->private_data = zs; 115 116 zfs_onexit_init((zfs_onexit_t **)&zs->zs_onexit); 117 zfs_zevent_init((zfs_zevent_t **)&zs->zs_zevent); 118 119 /* 120 * In order to provide for lock-free concurrent read access 121 * to the minor list in zfsdev_get_state_impl(), new entries 122 * must be completely written before linking them into the 123 * list whereas existing entries are already linked; the last 124 * operation must be updating zs_minor (from -1 to the new 125 * value). 126 */ 127 if (newzs) { 128 zs->zs_minor = minor; 129 smp_wmb(); 130 zsprev->zs_next = zs; 131 } else { 132 smp_wmb(); 133 zs->zs_minor = minor; 134 } 135 136 return (0); 137 } 138 139 static int 140 zfsdev_state_destroy(struct file *filp) 141 { 142 zfsdev_state_t *zs; 143 144 ASSERT(MUTEX_HELD(&zfsdev_state_lock)); 145 ASSERT(filp->private_data != NULL); 146 147 zs = filp->private_data; 148 zs->zs_minor = -1; 149 zfs_onexit_destroy(zs->zs_onexit); 150 zfs_zevent_destroy(zs->zs_zevent); 151 zs->zs_onexit = NULL; 152 zs->zs_zevent = NULL; 153 154 return (0); 155 } 156 157 static int 158 zfsdev_open(struct inode *ino, struct file *filp) 159 { 160 int error; 161 162 mutex_enter(&zfsdev_state_lock); 163 error = zfsdev_state_init(filp); 164 mutex_exit(&zfsdev_state_lock); 165 166 return (-error); 167 } 168 169 static int 170 zfsdev_release(struct inode *ino, struct file *filp) 171 { 172 int error; 173 174 mutex_enter(&zfsdev_state_lock); 175 error = zfsdev_state_destroy(filp); 176 mutex_exit(&zfsdev_state_lock); 177 178 return (-error); 179 } 180 181 static long 182 zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg) 183 { 184 uint_t vecnum; 185 zfs_cmd_t *zc; 186 int error, rc; 187 188 vecnum = cmd - ZFS_IOC_FIRST; 189 190 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); 191 192 if (ddi_copyin((void *)(uintptr_t)arg, zc, sizeof (zfs_cmd_t), 0)) { 193 error = -SET_ERROR(EFAULT); 194 goto out; 195 } 196 error = -zfsdev_ioctl_common(vecnum, zc, 0); 197 rc = ddi_copyout(zc, (void *)(uintptr_t)arg, sizeof (zfs_cmd_t), 0); 198 if (error == 0 && rc != 0) 199 error = -SET_ERROR(EFAULT); 200 out: 201 kmem_free(zc, sizeof (zfs_cmd_t)); 202 return (error); 203 204 } 205 206 uint64_t 207 zfs_max_nvlist_src_size_os(void) 208 { 209 if (zfs_max_nvlist_src_size != 0) 210 return (zfs_max_nvlist_src_size); 211 212 return (KMALLOC_MAX_SIZE); 213 } 214 215 void 216 zfs_ioctl_init_os(void) 217 { 218 } 219 220 #ifdef CONFIG_COMPAT 221 static long 222 zfsdev_compat_ioctl(struct file *filp, unsigned cmd, unsigned long arg) 223 { 224 return (zfsdev_ioctl(filp, cmd, arg)); 225 } 226 #else 227 #define zfsdev_compat_ioctl NULL 228 #endif 229 230 static const struct file_operations zfsdev_fops = { 231 .open = zfsdev_open, 232 .release = zfsdev_release, 233 .unlocked_ioctl = zfsdev_ioctl, 234 .compat_ioctl = zfsdev_compat_ioctl, 235 .owner = THIS_MODULE, 236 }; 237 238 static struct miscdevice zfs_misc = { 239 .minor = ZFS_DEVICE_MINOR, 240 .name = ZFS_DRIVER, 241 .fops = &zfsdev_fops, 242 }; 243 244 MODULE_ALIAS_MISCDEV(ZFS_DEVICE_MINOR); 245 MODULE_ALIAS("devname:zfs"); 246 247 int 248 zfsdev_attach(void) 249 { 250 int error; 251 252 error = misc_register(&zfs_misc); 253 if (error == -EBUSY) { 254 /* 255 * Fallback to dynamic minor allocation in the event of a 256 * collision with a reserved minor in linux/miscdevice.h. 257 * In this case the kernel modules must be manually loaded. 258 */ 259 printk(KERN_INFO "ZFS: misc_register() with static minor %d " 260 "failed %d, retrying with MISC_DYNAMIC_MINOR\n", 261 ZFS_DEVICE_MINOR, error); 262 263 zfs_misc.minor = MISC_DYNAMIC_MINOR; 264 error = misc_register(&zfs_misc); 265 } 266 267 if (error) 268 printk(KERN_INFO "ZFS: misc_register() failed %d\n", error); 269 270 return (error); 271 } 272 273 void 274 zfsdev_detach(void) 275 { 276 misc_deregister(&zfs_misc); 277 } 278 279 #ifdef ZFS_DEBUG 280 #define ZFS_DEBUG_STR " (DEBUG mode)" 281 #else 282 #define ZFS_DEBUG_STR "" 283 #endif 284 285 static int __init 286 _init(void) 287 { 288 int error; 289 290 if ((error = zfs_kmod_init()) != 0) { 291 printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s" 292 ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE, 293 ZFS_DEBUG_STR, error); 294 295 return (-error); 296 } 297 298 zfs_sysfs_init(); 299 300 printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, " 301 "ZFS pool version %s, ZFS filesystem version %s\n", 302 ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR, 303 SPA_VERSION_STRING, ZPL_VERSION_STRING); 304 #ifndef CONFIG_FS_POSIX_ACL 305 printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n"); 306 #endif /* CONFIG_FS_POSIX_ACL */ 307 308 return (0); 309 } 310 311 static void __exit 312 _fini(void) 313 { 314 zfs_sysfs_fini(); 315 zfs_kmod_fini(); 316 317 printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n", 318 ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR); 319 } 320 321 #if defined(_KERNEL) 322 module_init(_init); 323 module_exit(_fini); 324 #endif 325 326 ZFS_MODULE_DESCRIPTION("ZFS"); 327 ZFS_MODULE_AUTHOR(ZFS_META_AUTHOR); 328 ZFS_MODULE_LICENSE(ZFS_META_LICENSE); 329 ZFS_MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE); 330