xref: /freebsd/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * CDDL HEADER START
4  *
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License (the "License").
7  * You may not use this file except in compliance with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or https://opensource.org/licenses/CDDL-1.0.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
25  * Portions Copyright 2011 Martin Matuska
26  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
27  * Portions Copyright 2012 Pawel Jakub Dawidek <pawel@dawidek.net>
28  * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved.
29  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
30  * Copyright (c) 2014, Joyent, Inc. All rights reserved.
31  * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
32  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
33  * Copyright (c) 2013 Steven Hartland. All rights reserved.
34  * Copyright (c) 2014 Integros [integros.com]
35  * Copyright 2016 Toomas Soome <tsoome@me.com>
36  * Copyright (c) 2016 Actifio, Inc. All rights reserved.
37  * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
38  * Copyright 2017 RackTop Systems.
39  * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
40  * Copyright (c) 2019 Datto Inc.
41  * Copyright (c) 2021 Klara, Inc.
42  */
43 
44 #include <sys/types.h>
45 #include <sys/param.h>
46 #include <sys/errno.h>
47 #include <sys/uio.h>
48 #include <sys/file.h>
49 #include <sys/kmem.h>
50 #include <sys/stat.h>
51 #include <sys/zfs_ioctl.h>
52 #include <sys/zfs_vfsops.h>
53 #include <sys/zap.h>
54 #include <sys/spa.h>
55 #include <sys/nvpair.h>
56 #include <sys/fs/zfs.h>
57 #include <sys/zfs_ctldir.h>
58 #include <sys/zfs_dir.h>
59 #include <sys/zfs_onexit.h>
60 #include <sys/zvol.h>
61 #include <sys/fm/util.h>
62 #include <sys/dsl_crypt.h>
63 #include <sys/crypto/icp.h>
64 #include <sys/zstd/zstd.h>
65 
66 #include <sys/zfs_ioctl_impl.h>
67 
68 #include <sys/zfs_sysfs.h>
69 #include <linux/miscdevice.h>
70 #include <linux/slab.h>
71 
72 boolean_t
zfs_vfs_held(zfsvfs_t * zfsvfs)73 zfs_vfs_held(zfsvfs_t *zfsvfs)
74 {
75 	return (zfsvfs->z_sb != NULL);
76 }
77 
78 int
zfs_vfs_ref(zfsvfs_t ** zfvp)79 zfs_vfs_ref(zfsvfs_t **zfvp)
80 {
81 	if (*zfvp == NULL || (*zfvp)->z_sb == NULL ||
82 	    !atomic_inc_not_zero(&((*zfvp)->z_sb->s_active))) {
83 		return (SET_ERROR(ESRCH));
84 	}
85 	return (0);
86 }
87 
88 void
zfs_vfs_rele(zfsvfs_t * zfsvfs)89 zfs_vfs_rele(zfsvfs_t *zfsvfs)
90 {
91 	deactivate_super(zfsvfs->z_sb);
92 }
93 
94 void
zfsdev_private_set_state(void * priv,zfsdev_state_t * zs)95 zfsdev_private_set_state(void *priv, zfsdev_state_t *zs)
96 {
97 	struct file *filp = priv;
98 
99 	filp->private_data = zs;
100 }
101 
102 zfsdev_state_t *
zfsdev_private_get_state(void * priv)103 zfsdev_private_get_state(void *priv)
104 {
105 	struct file *filp = priv;
106 
107 	return (filp->private_data);
108 }
109 
110 static int
zfsdev_open(struct inode * ino,struct file * filp)111 zfsdev_open(struct inode *ino, struct file *filp)
112 {
113 	int error;
114 
115 	mutex_enter(&zfsdev_state_lock);
116 	error = zfsdev_state_init(filp);
117 	mutex_exit(&zfsdev_state_lock);
118 
119 	return (-error);
120 }
121 
122 static int
zfsdev_release(struct inode * ino,struct file * filp)123 zfsdev_release(struct inode *ino, struct file *filp)
124 {
125 	zfsdev_state_destroy(filp);
126 
127 	return (0);
128 }
129 
130 static long
zfsdev_ioctl(struct file * filp,unsigned cmd,unsigned long arg)131 zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
132 {
133 	uint_t vecnum;
134 	zfs_cmd_t *zc;
135 	int error, rc;
136 
137 	vecnum = cmd - ZFS_IOC_FIRST;
138 
139 	zc = vmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
140 
141 	if (ddi_copyin((void *)(uintptr_t)arg, zc, sizeof (zfs_cmd_t), 0)) {
142 		error = -SET_ERROR(EFAULT);
143 		goto out;
144 	}
145 	error = -zfsdev_ioctl_common(vecnum, zc, 0);
146 	rc = ddi_copyout(zc, (void *)(uintptr_t)arg, sizeof (zfs_cmd_t), 0);
147 	if (error == 0 && rc != 0)
148 		error = -SET_ERROR(EFAULT);
149 out:
150 	vmem_free(zc, sizeof (zfs_cmd_t));
151 	return (error);
152 
153 }
154 
155 static int
zfs_ioc_userns_attach(zfs_cmd_t * zc)156 zfs_ioc_userns_attach(zfs_cmd_t *zc)
157 {
158 	int error;
159 
160 	if (zc == NULL)
161 		return (SET_ERROR(EINVAL));
162 
163 	error = zone_dataset_attach(CRED(), zc->zc_name, zc->zc_cleanup_fd);
164 
165 	/*
166 	 * Translate ENOTTY to ZFS_ERR_NOT_USER_NAMESPACE as we just arrived
167 	 * back from the SPL layer, which does not know about ZFS_ERR_* errors.
168 	 * See the comment at the user_ns_get() function in spl-zone.c for
169 	 * details.
170 	 */
171 	if (error == ENOTTY)
172 		error = ZFS_ERR_NOT_USER_NAMESPACE;
173 
174 	return (error);
175 }
176 
177 static int
zfs_ioc_userns_detach(zfs_cmd_t * zc)178 zfs_ioc_userns_detach(zfs_cmd_t *zc)
179 {
180 	int error;
181 
182 	if (zc == NULL)
183 		return (SET_ERROR(EINVAL));
184 
185 	error = zone_dataset_detach(CRED(), zc->zc_name, zc->zc_cleanup_fd);
186 
187 	/*
188 	 * See the comment in zfs_ioc_userns_attach() for details on what is
189 	 * going on here.
190 	 */
191 	if (error == ENOTTY)
192 		error = ZFS_ERR_NOT_USER_NAMESPACE;
193 
194 	return (error);
195 }
196 
197 uint64_t
zfs_max_nvlist_src_size_os(void)198 zfs_max_nvlist_src_size_os(void)
199 {
200 	if (zfs_max_nvlist_src_size != 0)
201 		return (zfs_max_nvlist_src_size);
202 
203 	return (MIN(ptob(zfs_totalram_pages) / 4, 128 * 1024 * 1024));
204 }
205 
206 /* Update the VFS's cache of mountpoint properties */
207 void
zfs_ioctl_update_mount_cache(const char * dsname)208 zfs_ioctl_update_mount_cache(const char *dsname)
209 {
210 }
211 
212 void
zfs_ioctl_init_os(void)213 zfs_ioctl_init_os(void)
214 {
215 	zfs_ioctl_register_dataset_nolog(ZFS_IOC_USERNS_ATTACH,
216 	    zfs_ioc_userns_attach, zfs_secpolicy_config, POOL_CHECK_NONE);
217 	zfs_ioctl_register_dataset_nolog(ZFS_IOC_USERNS_DETACH,
218 	    zfs_ioc_userns_detach, zfs_secpolicy_config, POOL_CHECK_NONE);
219 }
220 
221 #ifdef CONFIG_COMPAT
222 static long
zfsdev_compat_ioctl(struct file * filp,unsigned cmd,unsigned long arg)223 zfsdev_compat_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
224 {
225 	return (zfsdev_ioctl(filp, cmd, arg));
226 }
227 #else
228 #define	zfsdev_compat_ioctl	NULL
229 #endif
230 
231 static const struct file_operations zfsdev_fops = {
232 	.open		= zfsdev_open,
233 	.release	= zfsdev_release,
234 	.unlocked_ioctl	= zfsdev_ioctl,
235 	.compat_ioctl	= zfsdev_compat_ioctl,
236 	.owner		= THIS_MODULE,
237 };
238 
239 static struct miscdevice zfs_misc = {
240 	.minor		= ZFS_DEVICE_MINOR,
241 	.name		= ZFS_DRIVER,
242 	.fops		= &zfsdev_fops,
243 };
244 
245 MODULE_ALIAS_MISCDEV(ZFS_DEVICE_MINOR);
246 MODULE_ALIAS("devname:zfs");
247 
248 int
zfsdev_attach(void)249 zfsdev_attach(void)
250 {
251 	int error;
252 
253 	error = misc_register(&zfs_misc);
254 	if (error == -EBUSY) {
255 		/*
256 		 * Fallback to dynamic minor allocation in the event of a
257 		 * collision with a reserved minor in linux/miscdevice.h.
258 		 * In this case the kernel modules must be manually loaded.
259 		 */
260 		printk(KERN_INFO "ZFS: misc_register() with static minor %d "
261 		    "failed %d, retrying with MISC_DYNAMIC_MINOR\n",
262 		    ZFS_DEVICE_MINOR, error);
263 
264 		zfs_misc.minor = MISC_DYNAMIC_MINOR;
265 		error = misc_register(&zfs_misc);
266 	}
267 
268 	if (error)
269 		printk(KERN_INFO "ZFS: misc_register() failed %d\n", error);
270 
271 	return (error);
272 }
273 
274 void
zfsdev_detach(void)275 zfsdev_detach(void)
276 {
277 	misc_deregister(&zfs_misc);
278 }
279 
280 #ifdef ZFS_DEBUG
281 #define	ZFS_DEBUG_STR	" (DEBUG mode)"
282 #else
283 #define	ZFS_DEBUG_STR	""
284 #endif
285 
286 zidmap_t *zfs_init_idmap;
287 
288 static int
openzfs_init_os(void)289 openzfs_init_os(void)
290 {
291 	int error;
292 
293 	if ((error = zfs_kmod_init()) != 0) {
294 		printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s"
295 		    ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE,
296 		    ZFS_DEBUG_STR, error);
297 
298 		return (-error);
299 	}
300 
301 	zfs_sysfs_init();
302 
303 	printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, "
304 	    "ZFS pool version %s, ZFS filesystem version %s\n",
305 	    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR,
306 	    SPA_VERSION_STRING, ZPL_VERSION_STRING);
307 #ifdef HAVE_LINUX_EXPERIMENTAL
308 	printk(KERN_NOTICE "ZFS: Using ZFS with kernel %s is EXPERIMENTAL and "
309 	    "SERIOUS DATA LOSS may occur!\n", utsname()->release);
310 	printk(KERN_NOTICE "ZFS: Please report your results at: "
311 	    "https://github.com/openzfs/zfs/issues/new\n");
312 #endif
313 #ifndef CONFIG_FS_POSIX_ACL
314 	printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n");
315 #endif /* CONFIG_FS_POSIX_ACL */
316 
317 	zfs_init_idmap = (zidmap_t *)zfs_get_init_idmap();
318 
319 	return (0);
320 }
321 
322 static void
openzfs_fini_os(void)323 openzfs_fini_os(void)
324 {
325 	zfs_sysfs_fini();
326 	zfs_kmod_fini();
327 
328 	printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n",
329 	    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
330 }
331 
332 
333 extern int __init zcommon_init(void);
334 extern void zcommon_fini(void);
335 
336 static int __init
openzfs_init(void)337 openzfs_init(void)
338 {
339 	int err;
340 	if ((err = zcommon_init()) != 0)
341 		goto zcommon_failed;
342 	if ((err = icp_init()) != 0)
343 		goto icp_failed;
344 	if ((err = zstd_init()) != 0)
345 		goto zstd_failed;
346 	if ((err = openzfs_init_os()) != 0)
347 		goto openzfs_os_failed;
348 	return (0);
349 
350 openzfs_os_failed:
351 	zstd_fini();
352 zstd_failed:
353 	icp_fini();
354 icp_failed:
355 	zcommon_fini();
356 zcommon_failed:
357 	return (err);
358 }
359 
360 static void __exit
openzfs_fini(void)361 openzfs_fini(void)
362 {
363 	openzfs_fini_os();
364 	zstd_fini();
365 	icp_fini();
366 	zcommon_fini();
367 }
368 
369 #if defined(_KERNEL)
370 module_init(openzfs_init);
371 module_exit(openzfs_fini);
372 #endif
373 
374 MODULE_ALIAS("zavl");
375 MODULE_ALIAS("icp");
376 MODULE_ALIAS("zlua");
377 MODULE_ALIAS("znvpair");
378 MODULE_ALIAS("zunicode");
379 MODULE_ALIAS("zcommon");
380 MODULE_ALIAS("zzstd");
381 MODULE_DESCRIPTION("ZFS");
382 MODULE_AUTHOR(ZFS_META_AUTHOR);
383 MODULE_LICENSE("Dual MIT/GPL"); /* lua */
384 MODULE_LICENSE("Dual BSD/GPL"); /* zstd / misc */
385 MODULE_LICENSE(ZFS_META_LICENSE);
386 MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
387