xref: /freebsd-src/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c (revision 2eb4d8dc723da3cf7d735a3226ae49da4c8c5dbc)
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 void
91 zfsdev_private_set_state(void *priv, zfsdev_state_t *zs)
92 {
93 	struct file *filp = priv;
94 
95 	filp->private_data = zs;
96 }
97 
98 zfsdev_state_t *
99 zfsdev_private_get_state(void *priv)
100 {
101 	struct file *filp = priv;
102 
103 	return (filp->private_data);
104 }
105 
106 static int
107 zfsdev_open(struct inode *ino, struct file *filp)
108 {
109 	int error;
110 
111 	mutex_enter(&zfsdev_state_lock);
112 	error = zfsdev_state_init(filp);
113 	mutex_exit(&zfsdev_state_lock);
114 
115 	return (-error);
116 }
117 
118 static int
119 zfsdev_release(struct inode *ino, struct file *filp)
120 {
121 	zfsdev_state_destroy(filp);
122 
123 	return (0);
124 }
125 
126 static long
127 zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
128 {
129 	uint_t vecnum;
130 	zfs_cmd_t *zc;
131 	int error, rc;
132 
133 	vecnum = cmd - ZFS_IOC_FIRST;
134 
135 	zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
136 
137 	if (ddi_copyin((void *)(uintptr_t)arg, zc, sizeof (zfs_cmd_t), 0)) {
138 		error = -SET_ERROR(EFAULT);
139 		goto out;
140 	}
141 	error = -zfsdev_ioctl_common(vecnum, zc, 0);
142 	rc = ddi_copyout(zc, (void *)(uintptr_t)arg, sizeof (zfs_cmd_t), 0);
143 	if (error == 0 && rc != 0)
144 		error = -SET_ERROR(EFAULT);
145 out:
146 	kmem_free(zc, sizeof (zfs_cmd_t));
147 	return (error);
148 
149 }
150 
151 uint64_t
152 zfs_max_nvlist_src_size_os(void)
153 {
154 	if (zfs_max_nvlist_src_size != 0)
155 		return (zfs_max_nvlist_src_size);
156 
157 	return (MIN(ptob(zfs_totalram_pages) / 4, 128 * 1024 * 1024));
158 }
159 
160 /* Update the VFS's cache of mountpoint properties */
161 void
162 zfs_ioctl_update_mount_cache(const char *dsname)
163 {
164 }
165 
166 void
167 zfs_ioctl_init_os(void)
168 {
169 }
170 
171 #ifdef CONFIG_COMPAT
172 static long
173 zfsdev_compat_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
174 {
175 	return (zfsdev_ioctl(filp, cmd, arg));
176 }
177 #else
178 #define	zfsdev_compat_ioctl	NULL
179 #endif
180 
181 static const struct file_operations zfsdev_fops = {
182 	.open		= zfsdev_open,
183 	.release	= zfsdev_release,
184 	.unlocked_ioctl	= zfsdev_ioctl,
185 	.compat_ioctl	= zfsdev_compat_ioctl,
186 	.owner		= THIS_MODULE,
187 };
188 
189 static struct miscdevice zfs_misc = {
190 	.minor		= ZFS_DEVICE_MINOR,
191 	.name		= ZFS_DRIVER,
192 	.fops		= &zfsdev_fops,
193 };
194 
195 MODULE_ALIAS_MISCDEV(ZFS_DEVICE_MINOR);
196 MODULE_ALIAS("devname:zfs");
197 
198 int
199 zfsdev_attach(void)
200 {
201 	int error;
202 
203 	error = misc_register(&zfs_misc);
204 	if (error == -EBUSY) {
205 		/*
206 		 * Fallback to dynamic minor allocation in the event of a
207 		 * collision with a reserved minor in linux/miscdevice.h.
208 		 * In this case the kernel modules must be manually loaded.
209 		 */
210 		printk(KERN_INFO "ZFS: misc_register() with static minor %d "
211 		    "failed %d, retrying with MISC_DYNAMIC_MINOR\n",
212 		    ZFS_DEVICE_MINOR, error);
213 
214 		zfs_misc.minor = MISC_DYNAMIC_MINOR;
215 		error = misc_register(&zfs_misc);
216 	}
217 
218 	if (error)
219 		printk(KERN_INFO "ZFS: misc_register() failed %d\n", error);
220 
221 	return (error);
222 }
223 
224 void
225 zfsdev_detach(void)
226 {
227 	misc_deregister(&zfs_misc);
228 }
229 
230 #ifdef ZFS_DEBUG
231 #define	ZFS_DEBUG_STR	" (DEBUG mode)"
232 #else
233 #define	ZFS_DEBUG_STR	""
234 #endif
235 
236 static int __init
237 openzfs_init(void)
238 {
239 	int error;
240 
241 	if ((error = zfs_kmod_init()) != 0) {
242 		printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s"
243 		    ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE,
244 		    ZFS_DEBUG_STR, error);
245 
246 		return (-error);
247 	}
248 
249 	zfs_sysfs_init();
250 
251 	printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, "
252 	    "ZFS pool version %s, ZFS filesystem version %s\n",
253 	    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR,
254 	    SPA_VERSION_STRING, ZPL_VERSION_STRING);
255 #ifndef CONFIG_FS_POSIX_ACL
256 	printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n");
257 #endif /* CONFIG_FS_POSIX_ACL */
258 
259 	return (0);
260 }
261 
262 static void __exit
263 openzfs_fini(void)
264 {
265 	zfs_sysfs_fini();
266 	zfs_kmod_fini();
267 
268 	printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n",
269 	    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
270 }
271 
272 #if defined(_KERNEL)
273 module_init(openzfs_init);
274 module_exit(openzfs_fini);
275 #endif
276 
277 ZFS_MODULE_DESCRIPTION("ZFS");
278 ZFS_MODULE_AUTHOR(ZFS_META_AUTHOR);
279 ZFS_MODULE_LICENSE(ZFS_META_LICENSE);
280 ZFS_MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
281