1/* 2 * Copyright (c) 2020 iXsystems, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD$"); 30 31#include <sys/param.h> 32#include <sys/buf.h> 33#include <sys/cmn_err.h> 34#include <sys/conf.h> 35#include <sys/dmu.h> 36#include <sys/dmu_impl.h> 37#include <sys/dmu_objset.h> 38#include <sys/dmu_send.h> 39#include <sys/dmu_tx.h> 40#include <sys/dsl_bookmark.h> 41#include <sys/dsl_crypt.h> 42#include <sys/dsl_dataset.h> 43#include <sys/dsl_deleg.h> 44#include <sys/dsl_destroy.h> 45#include <sys/dsl_dir.h> 46#include <sys/dsl_prop.h> 47#include <sys/dsl_scan.h> 48#include <sys/dsl_userhold.h> 49#include <sys/errno.h> 50#include <sys/eventhandler.h> 51#include <sys/file.h> 52#include <sys/fm/util.h> 53#include <sys/fs/zfs.h> 54#include <sys/kernel.h> 55#include <sys/kmem.h> 56#include <sys/lock.h> 57#include <sys/malloc.h> 58#include <sys/mount.h> 59#include <sys/mutex.h> 60#include <sys/nvpair.h> 61#include <sys/policy.h> 62#include <sys/proc.h> 63#include <sys/sdt.h> 64#include <sys/spa.h> 65#include <sys/spa_impl.h> 66#include <sys/stat.h> 67#include <sys/sunddi.h> 68#include <sys/systm.h> 69#include <sys/taskqueue.h> 70#include <sys/uio.h> 71#include <sys/vdev.h> 72#include <sys/vdev_removal.h> 73#include <sys/zap.h> 74#include <sys/zcp.h> 75#include <sys/zfeature.h> 76#include <sys/zfs_context.h> 77#include <sys/zfs_ctldir.h> 78#include <sys/zfs_dir.h> 79#include <sys/zfs_ioctl.h> 80#include <sys/zfs_ioctl_compat.h> 81#include <sys/zfs_ioctl_impl.h> 82#include <sys/zfs_onexit.h> 83#include <sys/zfs_vfsops.h> 84#include <sys/zfs_znode.h> 85#include <sys/zio_checksum.h> 86#include <sys/zone.h> 87#include <sys/zvol.h> 88 89#include "zfs_comutil.h" 90#include "zfs_deleg.h" 91#include "zfs_namecheck.h" 92#include "zfs_prop.h" 93 94SYSCTL_DECL(_vfs_zfs); 95SYSCTL_DECL(_vfs_zfs_vdev); 96 97extern uint_t rrw_tsd_key; 98static int zfs_version_ioctl = ZFS_IOCVER_OZFS; 99SYSCTL_DECL(_vfs_zfs_version); 100SYSCTL_INT(_vfs_zfs_version, OID_AUTO, ioctl, CTLFLAG_RD, &zfs_version_ioctl, 101 0, "ZFS_IOCTL_VERSION"); 102 103static struct cdev *zfsdev; 104 105static struct root_hold_token *zfs_root_token; 106 107extern uint_t rrw_tsd_key; 108extern uint_t zfs_allow_log_key; 109extern uint_t zfs_geom_probe_vdev_key; 110 111static int zfs__init(void); 112static int zfs__fini(void); 113static void zfs_shutdown(void *, int); 114 115static eventhandler_tag zfs_shutdown_event_tag; 116extern zfsdev_state_t *zfsdev_state_list; 117 118#define ZFS_MIN_KSTACK_PAGES 4 119 120static int 121zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag, 122 struct thread *td) 123{ 124 uint_t len; 125 int vecnum; 126 zfs_iocparm_t *zp; 127 zfs_cmd_t *zc; 128 zfs_cmd_legacy_t *zcl; 129 int rc, error; 130 void *uaddr; 131 132 len = IOCPARM_LEN(zcmd); 133 vecnum = zcmd & 0xff; 134 zp = (void *)arg; 135 uaddr = (void *)zp->zfs_cmd; 136 error = 0; 137 zcl = NULL; 138 139 if (len != sizeof (zfs_iocparm_t)) { 140 printf("len %d vecnum: %d sizeof (zfs_cmd_t) %ju\n", 141 len, vecnum, (uintmax_t)sizeof (zfs_cmd_t)); 142 return (EINVAL); 143 } 144 145 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); 146 /* 147 * Remap ioctl code for legacy user binaries 148 */ 149 if (zp->zfs_ioctl_version == ZFS_IOCVER_LEGACY) { 150 vecnum = zfs_ioctl_legacy_to_ozfs(vecnum); 151 if (vecnum < 0) { 152 kmem_free(zc, sizeof (zfs_cmd_t)); 153 return (ENOTSUP); 154 } 155 zcl = kmem_zalloc(sizeof (zfs_cmd_legacy_t), KM_SLEEP); 156 if (copyin(uaddr, zcl, sizeof (zfs_cmd_legacy_t))) { 157 error = SET_ERROR(EFAULT); 158 goto out; 159 } 160 zfs_cmd_legacy_to_ozfs(zcl, zc); 161 } else if (copyin(uaddr, zc, sizeof (zfs_cmd_t))) { 162 error = SET_ERROR(EFAULT); 163 goto out; 164 } 165 error = zfsdev_ioctl_common(vecnum, zc, 0); 166 if (zcl) { 167 zfs_cmd_ozfs_to_legacy(zc, zcl); 168 rc = copyout(zcl, uaddr, sizeof (*zcl)); 169 } else { 170 rc = copyout(zc, uaddr, sizeof (*zc)); 171 } 172 if (error == 0 && rc != 0) 173 error = SET_ERROR(EFAULT); 174out: 175 if (zcl) 176 kmem_free(zcl, sizeof (zfs_cmd_legacy_t)); 177 kmem_free(zc, sizeof (zfs_cmd_t)); 178 MPASS(tsd_get(rrw_tsd_key) == NULL); 179 return (error); 180} 181 182static void 183zfsdev_close(void *data) 184{ 185 zfsdev_state_t *zs = data; 186 187 ASSERT(zs != NULL); 188 189 mutex_enter(&zfsdev_state_lock); 190 191 ASSERT(zs->zs_minor != 0); 192 193 zs->zs_minor = -1; 194 zfs_onexit_destroy(zs->zs_onexit); 195 zfs_zevent_destroy(zs->zs_zevent); 196 zs->zs_onexit = NULL; 197 zs->zs_zevent = NULL; 198 199 mutex_exit(&zfsdev_state_lock); 200} 201 202static int 203zfs_ctldev_init(struct cdev *devp) 204{ 205 boolean_t newzs = B_FALSE; 206 minor_t minor; 207 zfsdev_state_t *zs, *zsprev = NULL; 208 209 ASSERT(MUTEX_HELD(&zfsdev_state_lock)); 210 211 minor = zfsdev_minor_alloc(); 212 if (minor == 0) 213 return (SET_ERROR(ENXIO)); 214 215 for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) { 216 if (zs->zs_minor == -1) 217 break; 218 zsprev = zs; 219 } 220 221 if (!zs) { 222 zs = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP); 223 newzs = B_TRUE; 224 } 225 226 devfs_set_cdevpriv(zs, zfsdev_close); 227 228 zfs_onexit_init((zfs_onexit_t **)&zs->zs_onexit); 229 zfs_zevent_init((zfs_zevent_t **)&zs->zs_zevent); 230 231 if (newzs) { 232 zs->zs_minor = minor; 233 wmb(); 234 zsprev->zs_next = zs; 235 } else { 236 wmb(); 237 zs->zs_minor = minor; 238 } 239 return (0); 240} 241 242static int 243zfsdev_open(struct cdev *devp, int flag, int mode, struct thread *td) 244{ 245 int error; 246 247 mutex_enter(&zfsdev_state_lock); 248 error = zfs_ctldev_init(devp); 249 mutex_exit(&zfsdev_state_lock); 250 251 return (error); 252} 253 254static struct cdevsw zfs_cdevsw = { 255 .d_version = D_VERSION, 256 .d_open = zfsdev_open, 257 .d_ioctl = zfsdev_ioctl, 258 .d_name = ZFS_DRIVER 259}; 260 261int 262zfsdev_attach(void) 263{ 264 zfsdev = make_dev(&zfs_cdevsw, 0x0, UID_ROOT, GID_OPERATOR, 0666, 265 ZFS_DRIVER); 266 return (0); 267} 268 269void 270zfsdev_detach(void) 271{ 272 if (zfsdev != NULL) 273 destroy_dev(zfsdev); 274} 275 276int 277zfs__init(void) 278{ 279 int error; 280 281#if KSTACK_PAGES < ZFS_MIN_KSTACK_PAGES 282 printf("ZFS NOTICE: KSTACK_PAGES is %d which could result in stack " 283 "overflow panic!\nPlease consider adding " 284 "'options KSTACK_PAGES=%d' to your kernel config\n", KSTACK_PAGES, 285 ZFS_MIN_KSTACK_PAGES); 286#endif 287 zfs_root_token = root_mount_hold("ZFS"); 288 if ((error = zfs_kmod_init()) != 0) { 289 printf("ZFS: Failed to Load ZFS Filesystem" 290 ", rc = %d\n", error); 291 root_mount_rel(zfs_root_token); 292 return (error); 293 } 294 295 296 tsd_create(&zfs_geom_probe_vdev_key, NULL); 297 298 printf("ZFS storage pool version: features support (" 299 SPA_VERSION_STRING ")\n"); 300 root_mount_rel(zfs_root_token); 301 ddi_sysevent_init(); 302 return (0); 303} 304 305int 306zfs__fini(void) 307{ 308 if (zfs_busy() || zvol_busy() || 309 zio_injection_enabled) { 310 return (EBUSY); 311 } 312 zfs_kmod_fini(); 313 tsd_destroy(&zfs_geom_probe_vdev_key); 314 return (0); 315} 316 317static void 318zfs_shutdown(void *arg __unused, int howto __unused) 319{ 320 321 /* 322 * ZFS fini routines can not properly work in a panic-ed system. 323 */ 324 if (panicstr == NULL) 325 zfs__fini(); 326} 327 328static int 329zfs_modevent(module_t mod, int type, void *unused __unused) 330{ 331 int err; 332 333 switch (type) { 334 case MOD_LOAD: 335 err = zfs__init(); 336 if (err == 0) 337 zfs_shutdown_event_tag = EVENTHANDLER_REGISTER( 338 shutdown_post_sync, zfs_shutdown, NULL, 339 SHUTDOWN_PRI_FIRST); 340 return (err); 341 case MOD_UNLOAD: 342 err = zfs__fini(); 343 if (err == 0 && zfs_shutdown_event_tag != NULL) 344 EVENTHANDLER_DEREGISTER(shutdown_post_sync, 345 zfs_shutdown_event_tag); 346 return (err); 347 case MOD_SHUTDOWN: 348 return (0); 349 default: 350 break; 351 } 352 return (EOPNOTSUPP); 353} 354 355static moduledata_t zfs_mod = { 356 "zfsctrl", 357 zfs_modevent, 358 0 359}; 360 361#ifdef _KERNEL 362EVENTHANDLER_DEFINE(mountroot, spa_boot_init, NULL, 0); 363#endif 364 365DECLARE_MODULE(zfsctrl, zfs_mod, SI_SUB_CLOCKS, SI_ORDER_ANY); 366MODULE_VERSION(zfsctrl, 1); 367#if __FreeBSD_version > 1300092 368MODULE_DEPEND(zfsctrl, xdr, 1, 1, 1); 369#else 370MODULE_DEPEND(zfsctrl, krpc, 1, 1, 1); 371#endif 372MODULE_DEPEND(zfsctrl, acl_nfs4, 1, 1, 1); 373MODULE_DEPEND(zfsctrl, crypto, 1, 1, 1); 374