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
zfs_vfs_held(zfsvfs_t * zfsvfs)69 zfs_vfs_held(zfsvfs_t *zfsvfs)
70 {
71 return (zfsvfs->z_sb != NULL);
72 }
73
74 int
zfs_vfs_ref(zfsvfs_t ** zfvp)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
zfs_vfs_rele(zfsvfs_t * zfsvfs)85 zfs_vfs_rele(zfsvfs_t *zfsvfs)
86 {
87 deactivate_super(zfsvfs->z_sb);
88 }
89
90 static int
zfsdev_state_init(struct file * filp)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
zfsdev_state_destroy(struct file * filp)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
zfsdev_open(struct inode * ino,struct file * filp)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
zfsdev_release(struct inode * ino,struct file * filp)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
zfsdev_ioctl(struct file * filp,unsigned cmd,unsigned long arg)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
zfs_max_nvlist_src_size_os(void)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 (MIN(ptob(zfs_totalram_pages) / 4, 128 * 1024 * 1024));
213 }
214
215 /* Update the VFS's cache of mountpoint properties */
216 void
zfs_ioctl_update_mount_cache(const char * dsname)217 zfs_ioctl_update_mount_cache(const char *dsname)
218 {
219 }
220
221 void
zfs_ioctl_init_os(void)222 zfs_ioctl_init_os(void)
223 {
224 }
225
226 #ifdef CONFIG_COMPAT
227 static long
zfsdev_compat_ioctl(struct file * filp,unsigned cmd,unsigned long arg)228 zfsdev_compat_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
229 {
230 return (zfsdev_ioctl(filp, cmd, arg));
231 }
232 #else
233 #define zfsdev_compat_ioctl NULL
234 #endif
235
236 static const struct file_operations zfsdev_fops = {
237 .open = zfsdev_open,
238 .release = zfsdev_release,
239 .unlocked_ioctl = zfsdev_ioctl,
240 .compat_ioctl = zfsdev_compat_ioctl,
241 .owner = THIS_MODULE,
242 };
243
244 static struct miscdevice zfs_misc = {
245 .minor = ZFS_DEVICE_MINOR,
246 .name = ZFS_DRIVER,
247 .fops = &zfsdev_fops,
248 };
249
250 MODULE_ALIAS_MISCDEV(ZFS_DEVICE_MINOR);
251 MODULE_ALIAS("devname:zfs");
252
253 int
zfsdev_attach(void)254 zfsdev_attach(void)
255 {
256 int error;
257
258 error = misc_register(&zfs_misc);
259 if (error == -EBUSY) {
260 /*
261 * Fallback to dynamic minor allocation in the event of a
262 * collision with a reserved minor in linux/miscdevice.h.
263 * In this case the kernel modules must be manually loaded.
264 */
265 printk(KERN_INFO "ZFS: misc_register() with static minor %d "
266 "failed %d, retrying with MISC_DYNAMIC_MINOR\n",
267 ZFS_DEVICE_MINOR, error);
268
269 zfs_misc.minor = MISC_DYNAMIC_MINOR;
270 error = misc_register(&zfs_misc);
271 }
272
273 if (error)
274 printk(KERN_INFO "ZFS: misc_register() failed %d\n", error);
275
276 return (error);
277 }
278
279 void
zfsdev_detach(void)280 zfsdev_detach(void)
281 {
282 misc_deregister(&zfs_misc);
283 }
284
285 #ifdef ZFS_DEBUG
286 #define ZFS_DEBUG_STR " (DEBUG mode)"
287 #else
288 #define ZFS_DEBUG_STR ""
289 #endif
290
291 zidmap_t *zfs_init_idmap;
292
293 static int __init
openzfs_init(void)294 openzfs_init(void)
295 {
296 int error;
297
298 if ((error = zfs_kmod_init()) != 0) {
299 printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s"
300 ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE,
301 ZFS_DEBUG_STR, error);
302
303 return (-error);
304 }
305
306 zfs_sysfs_init();
307
308 printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, "
309 "ZFS pool version %s, ZFS filesystem version %s\n",
310 ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR,
311 SPA_VERSION_STRING, ZPL_VERSION_STRING);
312 #ifndef CONFIG_FS_POSIX_ACL
313 printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n");
314 #endif /* CONFIG_FS_POSIX_ACL */
315
316 zfs_init_idmap = (zidmap_t *)zfs_get_init_idmap();
317
318 return (0);
319 }
320
321 static void __exit
openzfs_fini(void)322 openzfs_fini(void)
323 {
324 zfs_sysfs_fini();
325 zfs_kmod_fini();
326
327 printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n",
328 ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
329 }
330
331 #if defined(_KERNEL)
332 module_init(openzfs_init);
333 module_exit(openzfs_fini);
334 #endif
335
336 ZFS_MODULE_DESCRIPTION("ZFS");
337 ZFS_MODULE_AUTHOR(ZFS_META_AUTHOR);
338 ZFS_MODULE_LICENSE(ZFS_META_LICENSE);
339 ZFS_MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
340