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