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 https://opensource.org/licenses/CDDL-1.0.
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 * Copyright (c) 2021 Klara, Inc.
41 */
42
43#include <sys/types.h>
44#include <sys/param.h>
45#include <sys/errno.h>
46#include <sys/uio.h>
47#include <sys/file.h>
48#include <sys/kmem.h>
49#include <sys/stat.h>
50#include <sys/zfs_ioctl.h>
51#include <sys/zfs_vfsops.h>
52#include <sys/zap.h>
53#include <sys/spa.h>
54#include <sys/nvpair.h>
55#include <sys/fs/zfs.h>
56#include <sys/zfs_ctldir.h>
57#include <sys/zfs_dir.h>
58#include <sys/zfs_onexit.h>
59#include <sys/zvol.h>
60#include <sys/fm/util.h>
61#include <sys/dsl_crypt.h>
62#include <sys/crypto/icp.h>
63#include <sys/zstd/zstd.h>
64
65#include <sys/zfs_ioctl_impl.h>
66
67#include <sys/zfs_sysfs.h>
68#include <linux/miscdevice.h>
69#include <linux/slab.h>
70
71boolean_t
72zfs_vfs_held(zfsvfs_t *zfsvfs)
73{
74	return (zfsvfs->z_sb != NULL);
75}
76
77int
78zfs_vfs_ref(zfsvfs_t **zfvp)
79{
80	if (*zfvp == NULL || (*zfvp)->z_sb == NULL ||
81	    !atomic_inc_not_zero(&((*zfvp)->z_sb->s_active))) {
82		return (SET_ERROR(ESRCH));
83	}
84	return (0);
85}
86
87void
88zfs_vfs_rele(zfsvfs_t *zfsvfs)
89{
90	deactivate_super(zfsvfs->z_sb);
91}
92
93void
94zfsdev_private_set_state(void *priv, zfsdev_state_t *zs)
95{
96	struct file *filp = priv;
97
98	filp->private_data = zs;
99}
100
101zfsdev_state_t *
102zfsdev_private_get_state(void *priv)
103{
104	struct file *filp = priv;
105
106	return (filp->private_data);
107}
108
109static int
110zfsdev_open(struct inode *ino, struct file *filp)
111{
112	int error;
113
114	mutex_enter(&zfsdev_state_lock);
115	error = zfsdev_state_init(filp);
116	mutex_exit(&zfsdev_state_lock);
117
118	return (-error);
119}
120
121static int
122zfsdev_release(struct inode *ino, struct file *filp)
123{
124	zfsdev_state_destroy(filp);
125
126	return (0);
127}
128
129static long
130zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
131{
132	uint_t vecnum;
133	zfs_cmd_t *zc;
134	int error, rc;
135
136	vecnum = cmd - ZFS_IOC_FIRST;
137
138	zc = vmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
139
140	if (ddi_copyin((void *)(uintptr_t)arg, zc, sizeof (zfs_cmd_t), 0)) {
141		error = -SET_ERROR(EFAULT);
142		goto out;
143	}
144	error = -zfsdev_ioctl_common(vecnum, zc, 0);
145	rc = ddi_copyout(zc, (void *)(uintptr_t)arg, sizeof (zfs_cmd_t), 0);
146	if (error == 0 && rc != 0)
147		error = -SET_ERROR(EFAULT);
148out:
149	vmem_free(zc, sizeof (zfs_cmd_t));
150	return (error);
151
152}
153
154static int
155zfs_ioc_userns_attach(zfs_cmd_t *zc)
156{
157	int error;
158
159	if (zc == NULL)
160		return (SET_ERROR(EINVAL));
161
162	error = zone_dataset_attach(CRED(), zc->zc_name, zc->zc_cleanup_fd);
163
164	/*
165	 * Translate ENOTTY to ZFS_ERR_NOT_USER_NAMESPACE as we just arrived
166	 * back from the SPL layer, which does not know about ZFS_ERR_* errors.
167	 * See the comment at the user_ns_get() function in spl-zone.c for
168	 * details.
169	 */
170	if (error == ENOTTY)
171		error = ZFS_ERR_NOT_USER_NAMESPACE;
172
173	return (error);
174}
175
176static int
177zfs_ioc_userns_detach(zfs_cmd_t *zc)
178{
179	int error;
180
181	if (zc == NULL)
182		return (SET_ERROR(EINVAL));
183
184	error = zone_dataset_detach(CRED(), zc->zc_name, zc->zc_cleanup_fd);
185
186	/*
187	 * See the comment in zfs_ioc_userns_attach() for details on what is
188	 * going on here.
189	 */
190	if (error == ENOTTY)
191		error = ZFS_ERR_NOT_USER_NAMESPACE;
192
193	return (error);
194}
195
196uint64_t
197zfs_max_nvlist_src_size_os(void)
198{
199	if (zfs_max_nvlist_src_size != 0)
200		return (zfs_max_nvlist_src_size);
201
202	return (MIN(ptob(zfs_totalram_pages) / 4, 128 * 1024 * 1024));
203}
204
205/* Update the VFS's cache of mountpoint properties */
206void
207zfs_ioctl_update_mount_cache(const char *dsname)
208{
209}
210
211void
212zfs_ioctl_init_os(void)
213{
214	zfs_ioctl_register_dataset_nolog(ZFS_IOC_USERNS_ATTACH,
215	    zfs_ioc_userns_attach, zfs_secpolicy_config, POOL_CHECK_NONE);
216	zfs_ioctl_register_dataset_nolog(ZFS_IOC_USERNS_DETACH,
217	    zfs_ioc_userns_detach, zfs_secpolicy_config, POOL_CHECK_NONE);
218}
219
220#ifdef CONFIG_COMPAT
221static long
222zfsdev_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
230static 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
238static struct miscdevice zfs_misc = {
239	.minor		= ZFS_DEVICE_MINOR,
240	.name		= ZFS_DRIVER,
241	.fops		= &zfsdev_fops,
242};
243
244MODULE_ALIAS_MISCDEV(ZFS_DEVICE_MINOR);
245MODULE_ALIAS("devname:zfs");
246
247int
248zfsdev_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
273void
274zfsdev_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
285zidmap_t *zfs_init_idmap;
286
287static int
288openzfs_init_os(void)
289{
290	int error;
291
292	if ((error = zfs_kmod_init()) != 0) {
293		printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s"
294		    ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE,
295		    ZFS_DEBUG_STR, error);
296
297		return (-error);
298	}
299
300	zfs_sysfs_init();
301
302	printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, "
303	    "ZFS pool version %s, ZFS filesystem version %s\n",
304	    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR,
305	    SPA_VERSION_STRING, ZPL_VERSION_STRING);
306#ifndef CONFIG_FS_POSIX_ACL
307	printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n");
308#endif /* CONFIG_FS_POSIX_ACL */
309
310	zfs_init_idmap = (zidmap_t *)zfs_get_init_idmap();
311
312	return (0);
313}
314
315static void
316openzfs_fini_os(void)
317{
318	zfs_sysfs_fini();
319	zfs_kmod_fini();
320
321	printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n",
322	    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
323}
324
325
326extern int __init zcommon_init(void);
327extern void zcommon_fini(void);
328
329static int __init
330openzfs_init(void)
331{
332	int err;
333	if ((err = zcommon_init()) != 0)
334		goto zcommon_failed;
335	if ((err = icp_init()) != 0)
336		goto icp_failed;
337	if ((err = zstd_init()) != 0)
338		goto zstd_failed;
339	if ((err = openzfs_init_os()) != 0)
340		goto openzfs_os_failed;
341	return (0);
342
343openzfs_os_failed:
344	zstd_fini();
345zstd_failed:
346	icp_fini();
347icp_failed:
348	zcommon_fini();
349zcommon_failed:
350	return (err);
351}
352
353static void __exit
354openzfs_fini(void)
355{
356	openzfs_fini_os();
357	zstd_fini();
358	icp_fini();
359	zcommon_fini();
360}
361
362#if defined(_KERNEL)
363module_init(openzfs_init);
364module_exit(openzfs_fini);
365#endif
366
367MODULE_ALIAS("zavl");
368MODULE_ALIAS("icp");
369MODULE_ALIAS("zlua");
370MODULE_ALIAS("znvpair");
371MODULE_ALIAS("zunicode");
372MODULE_ALIAS("zcommon");
373MODULE_ALIAS("zzstd");
374MODULE_DESCRIPTION("ZFS");
375MODULE_AUTHOR(ZFS_META_AUTHOR);
376MODULE_LICENSE("Dual MIT/GPL"); /* lua */
377MODULE_LICENSE("Dual BSD/GPL"); /* zstd / misc */
378MODULE_LICENSE(ZFS_META_LICENSE);
379MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
380