]> git.proxmox.com Git - mirror_zfs.git/blame - lib/libzpool/kernel.c
Linux 4.7 compat: fix zpl_get_acl returns invalid acl pointer
[mirror_zfs.git] / lib / libzpool / kernel.c
CommitLineData
34dc7c2f
BB
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/*
572e2857 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
a0bd735a 23 * Copyright (c) 2016 Actifio, Inc. All rights reserved.
34dc7c2f
BB
24 */
25
34dc7c2f
BB
26#include <assert.h>
27#include <fcntl.h>
28#include <poll.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <zlib.h>
9867e8be 33#include <libgen.h>
1e33ac1e 34#include <sys/signal.h>
34dc7c2f
BB
35#include <sys/spa.h>
36#include <sys/stat.h>
37#include <sys/processor.h>
38#include <sys/zfs_context.h>
13fe0198 39#include <sys/rrwlock.h>
34dc7c2f 40#include <sys/utsname.h>
d603ed6c 41#include <sys/time.h>
d164b209 42#include <sys/systeminfo.h>
1eeb4562 43#include <zfs_fletcher.h>
0b04990a 44#include <sys/crypto/icp.h>
34dc7c2f
BB
45
46/*
47 * Emulation of kernel services in userland.
48 */
49
428870ff 50int aok;
34dc7c2f
BB
51uint64_t physmem;
52vnode_t *rootdir = (vnode_t *)0xabcd1234;
d164b209 53char hw_serial[HW_HOSTID_LEN];
f0e324f2 54struct utsname hw_utsname;
ca67b33a 55vmem_t *zio_arena = NULL;
34dc7c2f 56
9867e8be
MA
57/* If set, all blocks read will be copied to the specified directory. */
58char *vn_dumpdir = NULL;
59
428870ff
BB
60/* this only exists to have its address taken */
61struct proc p0;
62
34dc7c2f
BB
63/*
64 * =========================================================================
65 * threads
66 * =========================================================================
67 */
1e33ac1e
BB
68
69pthread_cond_t kthread_cond = PTHREAD_COND_INITIALIZER;
70pthread_mutex_t kthread_lock = PTHREAD_MUTEX_INITIALIZER;
71pthread_key_t kthread_key;
72int kthread_nr = 0;
73
519129ff 74void
1e33ac1e
BB
75thread_init(void)
76{
77 kthread_t *kt;
78
79 VERIFY3S(pthread_key_create(&kthread_key, NULL), ==, 0);
80
81 /* Create entry for primary kthread */
d1d7e268 82 kt = umem_zalloc(sizeof (kthread_t), UMEM_NOFAIL);
1e33ac1e
BB
83 kt->t_tid = pthread_self();
84 kt->t_func = NULL;
85
86 VERIFY3S(pthread_setspecific(kthread_key, kt), ==, 0);
87
88 /* Only the main thread should be running at the moment */
89 ASSERT3S(kthread_nr, ==, 0);
90 kthread_nr = 1;
91}
92
519129ff 93void
1e33ac1e
BB
94thread_fini(void)
95{
96 kthread_t *kt = curthread;
97
98 ASSERT(pthread_equal(kt->t_tid, pthread_self()));
99 ASSERT3P(kt->t_func, ==, NULL);
100
d1d7e268 101 umem_free(kt, sizeof (kthread_t));
1e33ac1e
BB
102
103 /* Wait for all threads to exit via thread_exit() */
104 VERIFY3S(pthread_mutex_lock(&kthread_lock), ==, 0);
105
106 kthread_nr--; /* Main thread is exiting */
107
108 while (kthread_nr > 0)
206971d2 109 VERIFY0(pthread_cond_wait(&kthread_cond, &kthread_lock));
1e33ac1e
BB
110
111 ASSERT3S(kthread_nr, ==, 0);
112 VERIFY3S(pthread_mutex_unlock(&kthread_lock), ==, 0);
113
114 VERIFY3S(pthread_key_delete(kthread_key), ==, 0);
115}
116
34dc7c2f 117kthread_t *
1e33ac1e
BB
118zk_thread_current(void)
119{
120 kthread_t *kt = pthread_getspecific(kthread_key);
121
122 ASSERT3P(kt, !=, NULL);
123
d1d7e268 124 return (kt);
1e33ac1e
BB
125}
126
127void *
128zk_thread_helper(void *arg)
34dc7c2f 129{
1e33ac1e
BB
130 kthread_t *kt = (kthread_t *) arg;
131
132 VERIFY3S(pthread_setspecific(kthread_key, kt), ==, 0);
34dc7c2f 133
1e33ac1e
BB
134 VERIFY3S(pthread_mutex_lock(&kthread_lock), ==, 0);
135 kthread_nr++;
136 VERIFY3S(pthread_mutex_unlock(&kthread_lock), ==, 0);
1229323d 137 (void) setpriority(PRIO_PROCESS, 0, kt->t_pri);
34dc7c2f 138
1e33ac1e
BB
139 kt->t_tid = pthread_self();
140 ((thread_func_arg_t) kt->t_func)(kt->t_arg);
141
142 /* Unreachable, thread must exit with thread_exit() */
143 abort();
144
d1d7e268 145 return (NULL);
1e33ac1e
BB
146}
147
148kthread_t *
149zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
d1d7e268 150 size_t len, proc_t *pp, int state, pri_t pri, int detachstate)
1e33ac1e
BB
151{
152 kthread_t *kt;
153 pthread_attr_t attr;
aa0ac7ca 154 char *stkstr;
1e33ac1e 155
aa0ac7ca 156 ASSERT0(state & ~TS_RUN);
1e33ac1e 157
d1d7e268 158 kt = umem_zalloc(sizeof (kthread_t), UMEM_NOFAIL);
1e33ac1e
BB
159 kt->t_func = func;
160 kt->t_arg = arg;
1229323d 161 kt->t_pri = pri;
1e33ac1e 162
aa0ac7ca
BB
163 VERIFY0(pthread_attr_init(&attr));
164 VERIFY0(pthread_attr_setdetachstate(&attr, detachstate));
165
1e33ac1e 166 /*
aa0ac7ca
BB
167 * We allow the default stack size in user space to be specified by
168 * setting the ZFS_STACK_SIZE environment variable. This allows us
169 * the convenience of observing and debugging stack overruns in
170 * user space. Explicitly specified stack sizes will be honored.
171 * The usage of ZFS_STACK_SIZE is discussed further in the
172 * ENVIRONMENT VARIABLES sections of the ztest(1) man page.
1e33ac1e 173 */
aa0ac7ca
BB
174 if (stksize == 0) {
175 stkstr = getenv("ZFS_STACK_SIZE");
176
177 if (stkstr == NULL)
178 stksize = TS_STACK_MAX;
179 else
180 stksize = MAX(atoi(stkstr), TS_STACK_MIN);
181 }
182
183 VERIFY3S(stksize, >, 0);
184 stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);
206971d2
DR
185 /*
186 * If this ever fails, it may be because the stack size is not a
187 * multiple of system page size.
188 */
aa0ac7ca
BB
189 VERIFY0(pthread_attr_setstacksize(&attr, stksize));
190 VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));
191
192 VERIFY0(pthread_create(&kt->t_tid, &attr, &zk_thread_helper, kt));
193 VERIFY0(pthread_attr_destroy(&attr));
1e33ac1e 194
d1d7e268 195 return (kt);
1e33ac1e
BB
196}
197
198void
199zk_thread_exit(void)
200{
201 kthread_t *kt = curthread;
202
203 ASSERT(pthread_equal(kt->t_tid, pthread_self()));
204
d1d7e268 205 umem_free(kt, sizeof (kthread_t));
1e33ac1e 206
206971d2 207 VERIFY0(pthread_mutex_lock(&kthread_lock));
1e33ac1e 208 kthread_nr--;
206971d2 209 VERIFY0(pthread_mutex_unlock(&kthread_lock));
1e33ac1e 210
206971d2 211 VERIFY0(pthread_cond_broadcast(&kthread_cond));
1e33ac1e
BB
212 pthread_exit((void *)TS_MAGIC);
213}
214
215void
216zk_thread_join(kt_did_t tid)
217{
218 void *ret;
219
220 pthread_join((pthread_t)tid, &ret);
221 VERIFY3P(ret, ==, (void *)TS_MAGIC);
34dc7c2f
BB
222}
223
224/*
225 * =========================================================================
226 * kstats
227 * =========================================================================
228 */
229/*ARGSUSED*/
230kstat_t *
330847ff
MA
231kstat_create(const char *module, int instance, const char *name,
232 const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag)
34dc7c2f
BB
233{
234 return (NULL);
235}
236
237/*ARGSUSED*/
238void
239kstat_install(kstat_t *ksp)
240{}
241
242/*ARGSUSED*/
243void
244kstat_delete(kstat_t *ksp)
245{}
246
1421c891 247/*ARGSUSED*/
330847ff
MA
248void
249kstat_waitq_enter(kstat_io_t *kiop)
250{}
251
252/*ARGSUSED*/
253void
254kstat_waitq_exit(kstat_io_t *kiop)
255{}
256
257/*ARGSUSED*/
258void
259kstat_runq_enter(kstat_io_t *kiop)
260{}
261
262/*ARGSUSED*/
263void
264kstat_runq_exit(kstat_io_t *kiop)
265{}
266
267/*ARGSUSED*/
268void
269kstat_waitq_to_runq(kstat_io_t *kiop)
270{}
271
272/*ARGSUSED*/
273void
274kstat_runq_back_to_waitq(kstat_io_t *kiop)
275{}
276
1421c891
PS
277void
278kstat_set_raw_ops(kstat_t *ksp,
279 int (*headers)(char *buf, size_t size),
280 int (*data)(char *buf, size_t size, void *data),
281 void *(*addr)(kstat_t *ksp, loff_t index))
282{}
283
34dc7c2f
BB
284/*
285 * =========================================================================
286 * mutexes
287 * =========================================================================
288 */
1e33ac1e 289
34dc7c2f 290void
1e33ac1e 291mutex_init(kmutex_t *mp, char *name, int type, void *cookie)
34dc7c2f 292{
1e33ac1e
BB
293 ASSERT3S(type, ==, MUTEX_DEFAULT);
294 ASSERT3P(cookie, ==, NULL);
295 mp->m_owner = MTX_INIT;
296 mp->m_magic = MTX_MAGIC;
297 VERIFY3S(pthread_mutex_init(&mp->m_lock, NULL), ==, 0);
34dc7c2f
BB
298}
299
300void
1e33ac1e 301mutex_destroy(kmutex_t *mp)
34dc7c2f 302{
1e33ac1e
BB
303 ASSERT3U(mp->m_magic, ==, MTX_MAGIC);
304 ASSERT3P(mp->m_owner, ==, MTX_INIT);
340dfbe1 305 ASSERT0(pthread_mutex_destroy(&(mp)->m_lock));
1e33ac1e
BB
306 mp->m_owner = MTX_DEST;
307 mp->m_magic = 0;
34dc7c2f
BB
308}
309
310void
311mutex_enter(kmutex_t *mp)
312{
1e33ac1e
BB
313 ASSERT3U(mp->m_magic, ==, MTX_MAGIC);
314 ASSERT3P(mp->m_owner, !=, MTX_DEST);
315 ASSERT3P(mp->m_owner, !=, curthread);
316 VERIFY3S(pthread_mutex_lock(&mp->m_lock), ==, 0);
317 ASSERT3P(mp->m_owner, ==, MTX_INIT);
34dc7c2f
BB
318 mp->m_owner = curthread;
319}
320
321int
322mutex_tryenter(kmutex_t *mp)
323{
206971d2 324 int err;
1e33ac1e
BB
325 ASSERT3U(mp->m_magic, ==, MTX_MAGIC);
326 ASSERT3P(mp->m_owner, !=, MTX_DEST);
206971d2 327 if (0 == (err = pthread_mutex_trylock(&mp->m_lock))) {
1e33ac1e 328 ASSERT3P(mp->m_owner, ==, MTX_INIT);
34dc7c2f
BB
329 mp->m_owner = curthread;
330 return (1);
331 } else {
206971d2 332 VERIFY3S(err, ==, EBUSY);
34dc7c2f
BB
333 return (0);
334 }
335}
336
337void
338mutex_exit(kmutex_t *mp)
339{
1e33ac1e
BB
340 ASSERT3U(mp->m_magic, ==, MTX_MAGIC);
341 ASSERT3P(mutex_owner(mp), ==, curthread);
342 mp->m_owner = MTX_INIT;
343 VERIFY3S(pthread_mutex_unlock(&mp->m_lock), ==, 0);
34dc7c2f
BB
344}
345
346void *
347mutex_owner(kmutex_t *mp)
348{
1e33ac1e 349 ASSERT3U(mp->m_magic, ==, MTX_MAGIC);
34dc7c2f
BB
350 return (mp->m_owner);
351}
352
1e33ac1e
BB
353int
354mutex_held(kmutex_t *mp)
355{
356 return (mp->m_owner == curthread);
357}
358
34dc7c2f
BB
359/*
360 * =========================================================================
361 * rwlocks
362 * =========================================================================
363 */
1e33ac1e 364
34dc7c2f
BB
365void
366rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
367{
1e33ac1e
BB
368 ASSERT3S(type, ==, RW_DEFAULT);
369 ASSERT3P(arg, ==, NULL);
370 VERIFY3S(pthread_rwlock_init(&rwlp->rw_lock, NULL), ==, 0);
371 rwlp->rw_owner = RW_INIT;
372 rwlp->rw_wr_owner = RW_INIT;
373 rwlp->rw_readers = 0;
374 rwlp->rw_magic = RW_MAGIC;
34dc7c2f
BB
375}
376
377void
378rw_destroy(krwlock_t *rwlp)
379{
1e33ac1e 380 ASSERT3U(rwlp->rw_magic, ==, RW_MAGIC);
843b4aad 381 ASSERT(rwlp->rw_readers == 0 && rwlp->rw_wr_owner == RW_INIT);
1e33ac1e
BB
382 VERIFY3S(pthread_rwlock_destroy(&rwlp->rw_lock), ==, 0);
383 rwlp->rw_magic = 0;
34dc7c2f
BB
384}
385
386void
387rw_enter(krwlock_t *rwlp, krw_t rw)
388{
1e33ac1e
BB
389 ASSERT3U(rwlp->rw_magic, ==, RW_MAGIC);
390 ASSERT3P(rwlp->rw_owner, !=, curthread);
391 ASSERT3P(rwlp->rw_wr_owner, !=, curthread);
34dc7c2f 392
1e33ac1e
BB
393 if (rw == RW_READER) {
394 VERIFY3S(pthread_rwlock_rdlock(&rwlp->rw_lock), ==, 0);
395 ASSERT3P(rwlp->rw_wr_owner, ==, RW_INIT);
396
397 atomic_inc_uint(&rwlp->rw_readers);
398 } else {
399 VERIFY3S(pthread_rwlock_wrlock(&rwlp->rw_lock), ==, 0);
400 ASSERT3P(rwlp->rw_wr_owner, ==, RW_INIT);
401 ASSERT3U(rwlp->rw_readers, ==, 0);
402
403 rwlp->rw_wr_owner = curthread;
404 }
34dc7c2f
BB
405
406 rwlp->rw_owner = curthread;
407}
408
409void
410rw_exit(krwlock_t *rwlp)
411{
1e33ac1e
BB
412 ASSERT3U(rwlp->rw_magic, ==, RW_MAGIC);
413 ASSERT(RW_LOCK_HELD(rwlp));
414
415 if (RW_READ_HELD(rwlp))
416 atomic_dec_uint(&rwlp->rw_readers);
417 else
418 rwlp->rw_wr_owner = RW_INIT;
34dc7c2f 419
1e33ac1e
BB
420 rwlp->rw_owner = RW_INIT;
421 VERIFY3S(pthread_rwlock_unlock(&rwlp->rw_lock), ==, 0);
34dc7c2f
BB
422}
423
424int
425rw_tryenter(krwlock_t *rwlp, krw_t rw)
426{
427 int rv;
428
1e33ac1e 429 ASSERT3U(rwlp->rw_magic, ==, RW_MAGIC);
34dc7c2f
BB
430
431 if (rw == RW_READER)
1e33ac1e 432 rv = pthread_rwlock_tryrdlock(&rwlp->rw_lock);
34dc7c2f 433 else
1e33ac1e 434 rv = pthread_rwlock_trywrlock(&rwlp->rw_lock);
34dc7c2f
BB
435
436 if (rv == 0) {
1e33ac1e
BB
437 ASSERT3P(rwlp->rw_wr_owner, ==, RW_INIT);
438
439 if (rw == RW_READER)
440 atomic_inc_uint(&rwlp->rw_readers);
441 else {
442 ASSERT3U(rwlp->rw_readers, ==, 0);
443 rwlp->rw_wr_owner = curthread;
444 }
445
34dc7c2f
BB
446 rwlp->rw_owner = curthread;
447 return (1);
448 }
449
1e33ac1e
BB
450 VERIFY3S(rv, ==, EBUSY);
451
34dc7c2f
BB
452 return (0);
453}
454
34dc7c2f
BB
455int
456rw_tryupgrade(krwlock_t *rwlp)
457{
1e33ac1e 458 ASSERT3U(rwlp->rw_magic, ==, RW_MAGIC);
34dc7c2f
BB
459
460 return (0);
461}
462
463/*
464 * =========================================================================
465 * condition variables
466 * =========================================================================
467 */
1e33ac1e 468
34dc7c2f
BB
469void
470cv_init(kcondvar_t *cv, char *name, int type, void *arg)
471{
1e33ac1e
BB
472 ASSERT3S(type, ==, CV_DEFAULT);
473 cv->cv_magic = CV_MAGIC;
206971d2 474 VERIFY0(pthread_cond_init(&cv->cv, NULL));
34dc7c2f
BB
475}
476
477void
478cv_destroy(kcondvar_t *cv)
479{
1e33ac1e 480 ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
206971d2 481 VERIFY0(pthread_cond_destroy(&cv->cv));
1e33ac1e 482 cv->cv_magic = 0;
34dc7c2f
BB
483}
484
485void
486cv_wait(kcondvar_t *cv, kmutex_t *mp)
487{
1e33ac1e
BB
488 ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
489 ASSERT3P(mutex_owner(mp), ==, curthread);
490 mp->m_owner = MTX_INIT;
206971d2 491 VERIFY0(pthread_cond_wait(&cv->cv, &mp->m_lock));
34dc7c2f
BB
492 mp->m_owner = curthread;
493}
494
495clock_t
496cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
497{
498 int error;
1e33ac1e 499 struct timeval tv;
34dc7c2f
BB
500 timestruc_t ts;
501 clock_t delta;
502
1e33ac1e
BB
503 ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
504
428870ff 505 delta = abstime - ddi_get_lbolt();
34dc7c2f
BB
506 if (delta <= 0)
507 return (-1);
508
1e33ac1e
BB
509 VERIFY(gettimeofday(&tv, NULL) == 0);
510
511 ts.tv_sec = tv.tv_sec + delta / hz;
512 ts.tv_nsec = tv.tv_usec * 1000 + (delta % hz) * (NANOSEC / hz);
513 if (ts.tv_nsec >= NANOSEC) {
514 ts.tv_sec++;
515 ts.tv_nsec -= NANOSEC;
516 }
34dc7c2f 517
1e33ac1e
BB
518 ASSERT3P(mutex_owner(mp), ==, curthread);
519 mp->m_owner = MTX_INIT;
520 error = pthread_cond_timedwait(&cv->cv, &mp->m_lock, &ts);
34dc7c2f
BB
521 mp->m_owner = curthread;
522
1e33ac1e 523 if (error == ETIMEDOUT)
34dc7c2f
BB
524 return (-1);
525
206971d2 526 VERIFY0(error);
34dc7c2f
BB
527
528 return (1);
529}
530
63fd3c6c
AL
531/*ARGSUSED*/
532clock_t
533cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
534 int flag)
535{
536 int error;
537 timestruc_t ts;
538 hrtime_t delta;
539
206971d2
DR
540 ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);
541
542 delta = tim;
543 if (flag & CALLOUT_FLAG_ABSOLUTE)
544 delta -= gethrtime();
63fd3c6c 545
63fd3c6c
AL
546 if (delta <= 0)
547 return (-1);
548
549 ts.tv_sec = delta / NANOSEC;
550 ts.tv_nsec = delta % NANOSEC;
551
552 ASSERT(mutex_owner(mp) == curthread);
553 mp->m_owner = NULL;
554 error = pthread_cond_timedwait(&cv->cv, &mp->m_lock, &ts);
555 mp->m_owner = curthread;
556
206971d2 557 if (error == ETIMEDOUT)
63fd3c6c
AL
558 return (-1);
559
206971d2 560 VERIFY0(error);
63fd3c6c
AL
561
562 return (1);
563}
564
34dc7c2f
BB
565void
566cv_signal(kcondvar_t *cv)
567{
1e33ac1e 568 ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
206971d2 569 VERIFY0(pthread_cond_signal(&cv->cv));
34dc7c2f
BB
570}
571
572void
573cv_broadcast(kcondvar_t *cv)
574{
1e33ac1e 575 ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
206971d2 576 VERIFY0(pthread_cond_broadcast(&cv->cv));
34dc7c2f
BB
577}
578
579/*
580 * =========================================================================
581 * vnode operations
582 * =========================================================================
583 */
584/*
585 * Note: for the xxxat() versions of these functions, we assume that the
586 * starting vp is always rootdir (which is true for spa_directory.c, the only
587 * ZFS consumer of these interfaces). We assert this is true, and then emulate
588 * them by adding '/' in front of the path.
589 */
590
591/*ARGSUSED*/
592int
593vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
594{
595 int fd;
9867e8be 596 int dump_fd;
34dc7c2f 597 vnode_t *vp;
a4914d38 598 int old_umask = 0;
5ae4e2c2 599 char *realpath;
34dc7c2f 600 struct stat64 st;
4d58b69d 601 int err;
34dc7c2f 602
5ae4e2c2
BB
603 realpath = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
604
34dc7c2f
BB
605 /*
606 * If we're accessing a real disk from userland, we need to use
607 * the character interface to avoid caching. This is particularly
608 * important if we're trying to look at a real in-kernel storage
609 * pool from userland, e.g. via zdb, because otherwise we won't
610 * see the changes occurring under the segmap cache.
611 * On the other hand, the stupid character device returns zero
612 * for its size. So -- gag -- we open the block device to get
613 * its size, and remember it for subsequent VOP_GETATTR().
614 */
d603ed6c 615#if defined(__sun__) || defined(__sun)
34dc7c2f 616 if (strncmp(path, "/dev/", 5) == 0) {
d603ed6c
BB
617#else
618 if (0) {
619#endif
34dc7c2f
BB
620 char *dsk;
621 fd = open64(path, O_RDONLY);
5ae4e2c2
BB
622 if (fd == -1) {
623 err = errno;
624 free(realpath);
625 return (err);
626 }
34dc7c2f 627 if (fstat64(fd, &st) == -1) {
5ae4e2c2 628 err = errno;
34dc7c2f 629 close(fd);
5ae4e2c2
BB
630 free(realpath);
631 return (err);
34dc7c2f
BB
632 }
633 close(fd);
634 (void) sprintf(realpath, "%s", path);
635 dsk = strstr(path, "/dsk/");
636 if (dsk != NULL)
637 (void) sprintf(realpath + (dsk - path) + 1, "r%s",
638 dsk + 1);
639 } else {
640 (void) sprintf(realpath, "%s", path);
5ae4e2c2
BB
641 if (!(flags & FCREAT) && stat64(realpath, &st) == -1) {
642 err = errno;
643 free(realpath);
644 return (err);
645 }
34dc7c2f
BB
646 }
647
d603ed6c
BB
648 if (!(flags & FCREAT) && S_ISBLK(st.st_mode)) {
649#ifdef __linux__
650 flags |= O_DIRECT;
651#endif
ada82581
BB
652 /* We shouldn't be writing to block devices in userspace */
653 VERIFY(!(flags & FWRITE));
d603ed6c
BB
654 }
655
34dc7c2f
BB
656 if (flags & FCREAT)
657 old_umask = umask(0);
658
659 /*
660 * The construct 'flags - FREAD' conveniently maps combinations of
661 * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
662 */
663 fd = open64(realpath, flags - FREAD, mode);
9867e8be 664 err = errno;
34dc7c2f
BB
665
666 if (flags & FCREAT)
667 (void) umask(old_umask);
668
9867e8be
MA
669 if (vn_dumpdir != NULL) {
670 char *dumppath = umem_zalloc(MAXPATHLEN, UMEM_NOFAIL);
671 (void) snprintf(dumppath, MAXPATHLEN,
672 "%s/%s", vn_dumpdir, basename(realpath));
673 dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666);
674 umem_free(dumppath, MAXPATHLEN);
675 if (dump_fd == -1) {
676 err = errno;
677 free(realpath);
678 close(fd);
679 return (err);
680 }
681 } else {
682 dump_fd = -1;
683 }
684
685 free(realpath);
686
34dc7c2f 687 if (fd == -1)
9867e8be 688 return (err);
34dc7c2f 689
8d4e8140 690 if (fstat64_blk(fd, &st) == -1) {
4d58b69d 691 err = errno;
34dc7c2f 692 close(fd);
4d58b69d 693 return (err);
34dc7c2f
BB
694 }
695
696 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
697
698 *vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
699
700 vp->v_fd = fd;
701 vp->v_size = st.st_size;
702 vp->v_path = spa_strdup(path);
9867e8be 703 vp->v_dump_fd = dump_fd;
34dc7c2f
BB
704
705 return (0);
706}
707
708/*ARGSUSED*/
709int
710vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
711 int x3, vnode_t *startvp, int fd)
712{
713 char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
714 int ret;
715
716 ASSERT(startvp == rootdir);
717 (void) sprintf(realpath, "/%s", path);
718
719 /* fd ignored for now, need if want to simulate nbmand support */
720 ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
721
722 umem_free(realpath, strlen(path) + 2);
723
724 return (ret);
725}
726
727/*ARGSUSED*/
728int
729vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
730 int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
731{
4d58b69d 732 ssize_t rc, done = 0, split;
34dc7c2f
BB
733
734 if (uio == UIO_READ) {
4d58b69d 735 rc = pread64(vp->v_fd, addr, len, offset);
9867e8be 736 if (vp->v_dump_fd != -1) {
928c58dd
BB
737 int status;
738 status = pwrite64(vp->v_dump_fd, addr, rc, offset);
9867e8be
MA
739 ASSERT(status != -1);
740 }
34dc7c2f
BB
741 } else {
742 /*
743 * To simulate partial disk writes, we split writes into two
744 * system calls so that the process can be killed in between.
745 */
9ae529ec
CS
746 int sectors = len >> SPA_MINBLOCKSHIFT;
747 split = (sectors > 0 ? rand() % sectors : 0) <<
748 SPA_MINBLOCKSHIFT;
4d58b69d
RC
749 rc = pwrite64(vp->v_fd, addr, split, offset);
750 if (rc != -1) {
751 done = rc;
752 rc = pwrite64(vp->v_fd, (char *)addr + split,
753 len - split, offset + split);
754 }
34dc7c2f
BB
755 }
756
d603ed6c
BB
757#ifdef __linux__
758 if (rc == -1 && errno == EINVAL) {
759 /*
760 * Under Linux, this most likely means an alignment issue
761 * (memory or disk) due to O_DIRECT, so we abort() in order to
762 * catch the offender.
763 */
d1d7e268 764 abort();
d603ed6c
BB
765 }
766#endif
4d58b69d 767 if (rc == -1)
34dc7c2f 768 return (errno);
4d58b69d
RC
769
770 done += rc;
771
34dc7c2f 772 if (residp)
4d58b69d
RC
773 *residp = len - done;
774 else if (done != len)
34dc7c2f
BB
775 return (EIO);
776 return (0);
777}
778
779void
780vn_close(vnode_t *vp)
781{
782 close(vp->v_fd);
9867e8be
MA
783 if (vp->v_dump_fd != -1)
784 close(vp->v_dump_fd);
34dc7c2f
BB
785 spa_strfree(vp->v_path);
786 umem_free(vp, sizeof (vnode_t));
787}
788
428870ff
BB
789/*
790 * At a minimum we need to update the size since vdev_reopen()
791 * will no longer call vn_openat().
792 */
793int
794fop_getattr(vnode_t *vp, vattr_t *vap)
795{
796 struct stat64 st;
8d4e8140 797 int err;
428870ff 798
8d4e8140
RC
799 if (fstat64_blk(vp->v_fd, &st) == -1) {
800 err = errno;
428870ff 801 close(vp->v_fd);
8d4e8140 802 return (err);
428870ff
BB
803 }
804
805 vap->va_size = st.st_size;
806 return (0);
807}
808
34dc7c2f
BB
809/*
810 * =========================================================================
811 * Figure out which debugging statements to print
812 * =========================================================================
813 */
814
815static char *dprintf_string;
816static int dprintf_print_all;
817
818int
819dprintf_find_string(const char *string)
820{
821 char *tmp_str = dprintf_string;
822 int len = strlen(string);
823
824 /*
825 * Find out if this is a string we want to print.
826 * String format: file1.c,function_name1,file2.c,file3.c
827 */
828
829 while (tmp_str != NULL) {
830 if (strncmp(tmp_str, string, len) == 0 &&
831 (tmp_str[len] == ',' || tmp_str[len] == '\0'))
832 return (1);
833 tmp_str = strchr(tmp_str, ',');
834 if (tmp_str != NULL)
835 tmp_str++; /* Get rid of , */
836 }
837 return (0);
838}
839
840void
841dprintf_setup(int *argc, char **argv)
842{
843 int i, j;
844
845 /*
846 * Debugging can be specified two ways: by setting the
847 * environment variable ZFS_DEBUG, or by including a
848 * "debug=..." argument on the command line. The command
849 * line setting overrides the environment variable.
850 */
851
852 for (i = 1; i < *argc; i++) {
853 int len = strlen("debug=");
854 /* First look for a command line argument */
855 if (strncmp("debug=", argv[i], len) == 0) {
856 dprintf_string = argv[i] + len;
857 /* Remove from args */
858 for (j = i; j < *argc; j++)
859 argv[j] = argv[j+1];
860 argv[j] = NULL;
861 (*argc)--;
862 }
863 }
864
865 if (dprintf_string == NULL) {
866 /* Look for ZFS_DEBUG environment variable */
867 dprintf_string = getenv("ZFS_DEBUG");
868 }
869
870 /*
871 * Are we just turning on all debugging?
872 */
873 if (dprintf_find_string("on"))
874 dprintf_print_all = 1;
308a451f
MA
875
876 if (dprintf_string != NULL)
877 zfs_flags |= ZFS_DEBUG_DPRINTF;
34dc7c2f
BB
878}
879
880/*
881 * =========================================================================
882 * debug printfs
883 * =========================================================================
884 */
885void
886__dprintf(const char *file, const char *func, int line, const char *fmt, ...)
887{
888 const char *newfile;
889 va_list adx;
890
891 /*
892 * Get rid of annoying "../common/" prefix to filename.
893 */
894 newfile = strrchr(file, '/');
895 if (newfile != NULL) {
896 newfile = newfile + 1; /* Get rid of leading / */
897 } else {
898 newfile = file;
899 }
900
901 if (dprintf_print_all ||
902 dprintf_find_string(newfile) ||
903 dprintf_find_string(func)) {
904 /* Print out just the function name if requested */
905 flockfile(stdout);
906 if (dprintf_find_string("pid"))
907 (void) printf("%d ", getpid());
908 if (dprintf_find_string("tid"))
1e33ac1e 909 (void) printf("%u ", (uint_t) pthread_self());
34dc7c2f
BB
910 if (dprintf_find_string("cpu"))
911 (void) printf("%u ", getcpuid());
912 if (dprintf_find_string("time"))
913 (void) printf("%llu ", gethrtime());
914 if (dprintf_find_string("long"))
915 (void) printf("%s, line %d: ", newfile, line);
916 (void) printf("%s: ", func);
917 va_start(adx, fmt);
918 (void) vprintf(fmt, adx);
919 va_end(adx);
920 funlockfile(stdout);
921 }
922}
923
34dc7c2f
BB
924/*
925 * =========================================================================
926 * cmn_err() and panic()
927 * =========================================================================
928 */
929static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
930static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
931
932void
933vpanic(const char *fmt, va_list adx)
934{
935 (void) fprintf(stderr, "error: ");
936 (void) vfprintf(stderr, fmt, adx);
937 (void) fprintf(stderr, "\n");
938
939 abort(); /* think of it as a "user-level crash dump" */
940}
941
942void
943panic(const char *fmt, ...)
944{
945 va_list adx;
946
947 va_start(adx, fmt);
948 vpanic(fmt, adx);
949 va_end(adx);
950}
951
952void
953vcmn_err(int ce, const char *fmt, va_list adx)
954{
955 if (ce == CE_PANIC)
956 vpanic(fmt, adx);
957 if (ce != CE_NOTE) { /* suppress noise in userland stress testing */
958 (void) fprintf(stderr, "%s", ce_prefix[ce]);
959 (void) vfprintf(stderr, fmt, adx);
960 (void) fprintf(stderr, "%s", ce_suffix[ce]);
961 }
962}
963
964/*PRINTFLIKE2*/
965void
966cmn_err(int ce, const char *fmt, ...)
967{
968 va_list adx;
969
970 va_start(adx, fmt);
971 vcmn_err(ce, fmt, adx);
972 va_end(adx);
973}
974
975/*
976 * =========================================================================
977 * kobj interfaces
978 * =========================================================================
979 */
980struct _buf *
981kobj_open_file(char *name)
982{
983 struct _buf *file;
984 vnode_t *vp;
985
986 /* set vp as the _fd field of the file */
987 if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
988 -1) != 0)
989 return ((void *)-1UL);
990
991 file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
992 file->_fd = (intptr_t)vp;
993 return (file);
994}
995
996int
997kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
998{
999 ssize_t resid;
1000
957dc932
RY
1001 if (vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off,
1002 UIO_SYSSPACE, 0, 0, 0, &resid) != 0)
1003 return (-1);
34dc7c2f
BB
1004
1005 return (size - resid);
1006}
1007
1008void
1009kobj_close_file(struct _buf *file)
1010{
1011 vn_close((vnode_t *)file->_fd);
1012 umem_free(file, sizeof (struct _buf));
1013}
1014
1015int
1016kobj_get_filesize(struct _buf *file, uint64_t *size)
1017{
1018 struct stat64 st;
1019 vnode_t *vp = (vnode_t *)file->_fd;
1020
1021 if (fstat64(vp->v_fd, &st) == -1) {
1022 vn_close(vp);
1023 return (errno);
1024 }
1025 *size = st.st_size;
1026 return (0);
1027}
1028
1029/*
1030 * =========================================================================
1031 * misc routines
1032 * =========================================================================
1033 */
1034
1035void
1036delay(clock_t ticks)
1037{
1038 poll(0, 0, ticks * (1000 / hz));
1039}
1040
1041/*
1042 * Find highest one bit set.
1043 * Returns bit number + 1 of highest bit that is set, otherwise returns 0.
1044 * High order bit is 31 (or 63 in _LP64 kernel).
1045 */
1046int
9bd274dd 1047highbit64(uint64_t i)
34dc7c2f
BB
1048{
1049 register int h = 1;
1050
1051 if (i == 0)
1052 return (0);
9bd274dd 1053 if (i & 0xffffffff00000000ULL) {
34dc7c2f
BB
1054 h += 32; i >>= 32;
1055 }
34dc7c2f
BB
1056 if (i & 0xffff0000) {
1057 h += 16; i >>= 16;
1058 }
1059 if (i & 0xff00) {
1060 h += 8; i >>= 8;
1061 }
1062 if (i & 0xf0) {
1063 h += 4; i >>= 4;
1064 }
1065 if (i & 0xc) {
1066 h += 2; i >>= 2;
1067 }
1068 if (i & 0x2) {
1069 h += 1;
1070 }
1071 return (h);
1072}
1073
193a37cb
TH
1074/*
1075 * Find lowest one bit set.
1076 * Returns bit number + 1 of lowest bit that is set, otherwise returns 0.
1077 * This is basically a reimplementation of ffsll(), which is GNU specific.
1078 */
1079int
1080lowbit64(uint64_t i)
1081{
1082 register int h = 64;
1083 if (i == 0)
1084 return (0);
1085
1086 if (i & 0x00000000ffffffffULL)
1087 h -= 32;
1088 else
1089 i >>= 32;
1090
1091 if (i & 0x0000ffff)
1092 h -= 16;
1093 else
1094 i >>= 16;
1095
1096 if (i & 0x00ff)
1097 h -= 8;
1098 else
1099 i >>= 8;
1100
1101 if (i & 0x0f)
1102 h -= 4;
1103 else
1104 i >>= 4;
1105
1106 if (i & 0x3)
1107 h -= 2;
1108 else
1109 i >>= 2;
1110
1111 if (i & 0x1)
1112 h -= 1;
1113
1114 return (h);
1115}
1116
0b04990a
TC
1117/*
1118 * Find highest one bit set.
1119 * Returns bit number + 1 of highest bit that is set, otherwise returns 0.
1120 * High order bit is 31 (or 63 in _LP64 kernel).
1121 */
1122int
1123highbit(ulong_t i)
1124{
1125register int h = 1;
1126
1127 if (i == 0)
1128 return (0);
1129#ifdef _LP64
1130 if (i & 0xffffffff00000000ul) {
1131 h += 32; i >>= 32;
1132 }
1133#endif
1134 if (i & 0xffff0000) {
1135 h += 16; i >>= 16;
1136 }
1137 if (i & 0xff00) {
1138 h += 8; i >>= 8;
1139 }
1140 if (i & 0xf0) {
1141 h += 4; i >>= 4;
1142 }
1143 if (i & 0xc) {
1144 h += 2; i >>= 2;
1145 }
1146 if (i & 0x2) {
1147 h += 1;
1148 }
1149 return (h);
1150}
1151
1152/*
1153 * Find lowest one bit set.
1154 * Returns bit number + 1 of lowest bit that is set, otherwise returns 0.
1155 * Low order bit is 0.
1156 */
1157int
1158lowbit(ulong_t i)
1159{
1160 register int h = 1;
1161
1162 if (i == 0)
1163 return (0);
1164
1165#ifdef _LP64
1166 if (!(i & 0xffffffff)) {
1167 h += 32; i >>= 32;
1168 }
1169#endif
1170 if (!(i & 0xffff)) {
1171 h += 16; i >>= 16;
1172 }
1173 if (!(i & 0xff)) {
1174 h += 8; i >>= 8;
1175 }
1176 if (!(i & 0xf)) {
1177 h += 4; i >>= 4;
1178 }
1179 if (!(i & 0x3)) {
1180 h += 2; i >>= 2;
1181 }
1182 if (!(i & 0x1)) {
1183 h += 1;
1184 }
1185 return (h);
1186}
193a37cb 1187
34dc7c2f
BB
1188static int random_fd = -1, urandom_fd = -1;
1189
0b04990a
TC
1190void
1191random_init(void)
1192{
1193 VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
1194 VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
1195}
1196
1197void
1198random_fini(void)
1199{
1200 close(random_fd);
1201 close(urandom_fd);
1202
1203 random_fd = -1;
1204 urandom_fd = -1;
1205}
1206
34dc7c2f
BB
1207static int
1208random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
1209{
1210 size_t resid = len;
1211 ssize_t bytes;
1212
1213 ASSERT(fd != -1);
1214
1215 while (resid != 0) {
1216 bytes = read(fd, ptr, resid);
1217 ASSERT3S(bytes, >=, 0);
1218 ptr += bytes;
1219 resid -= bytes;
1220 }
1221
1222 return (0);
1223}
1224
1225int
1226random_get_bytes(uint8_t *ptr, size_t len)
1227{
1228 return (random_get_bytes_common(ptr, len, random_fd));
1229}
1230
1231int
1232random_get_pseudo_bytes(uint8_t *ptr, size_t len)
1233{
1234 return (random_get_bytes_common(ptr, len, urandom_fd));
1235}
1236
1237int
1238ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result)
1239{
1240 char *end;
1241
1242 *result = strtoul(hw_serial, &end, base);
1243 if (*result == 0)
1244 return (errno);
1245 return (0);
1246}
1247
428870ff
BB
1248int
1249ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result)
1250{
1251 char *end;
1252
1253 *result = strtoull(str, &end, base);
1254 if (*result == 0)
1255 return (errno);
1256 return (0);
1257}
1258
f0e324f2
BB
1259utsname_t *
1260utsname(void)
1261{
1262 return (&hw_utsname);
1263}
1264
34dc7c2f
BB
1265/*
1266 * =========================================================================
1267 * kernel emulation setup & teardown
1268 * =========================================================================
1269 */
1270static int
1271umem_out_of_memory(void)
1272{
1273 char errmsg[] = "out of memory -- generating core dump\n";
1274
0e5b68e0 1275 (void) fprintf(stderr, "%s", errmsg);
34dc7c2f
BB
1276 abort();
1277 return (0);
1278}
1279
53698a45
CC
1280static unsigned long
1281get_spl_hostid(void)
1282{
1283 FILE *f;
1284 unsigned long hostid;
1285
1286 f = fopen("/sys/module/spl/parameters/spl_hostid", "r");
1287 if (!f)
1288 return (0);
1289 if (fscanf(f, "%lu", &hostid) != 1)
1290 hostid = 0;
1291 fclose(f);
1292 return (hostid & 0xffffffff);
1293}
1294
1295unsigned long
1296get_system_hostid(void)
1297{
1298 unsigned long system_hostid = get_spl_hostid();
1299 if (system_hostid == 0)
1300 system_hostid = gethostid() & 0xffffffff;
1301 return (system_hostid);
1302}
1303
34dc7c2f
BB
1304void
1305kernel_init(int mode)
1306{
13fe0198
MA
1307 extern uint_t rrw_tsd_key;
1308
34dc7c2f
BB
1309 umem_nofail_callback(umem_out_of_memory);
1310
1311 physmem = sysconf(_SC_PHYS_PAGES);
1312
1313 dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
1314 (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
1315
428870ff 1316 (void) snprintf(hw_serial, sizeof (hw_serial), "%ld",
53698a45 1317 (mode & FWRITE) ? get_system_hostid() : 0);
34dc7c2f 1318
0b04990a
TC
1319 random_init();
1320
f0e324f2 1321 VERIFY0(uname(&hw_utsname));
34dc7c2f 1322
1e33ac1e 1323 thread_init();
b128c09f 1324 system_taskq_init();
0b04990a 1325 icp_init();
b128c09f 1326
34dc7c2f 1327 spa_init(mode);
13fe0198 1328
1eeb4562
JX
1329 fletcher_4_init();
1330
13fe0198 1331 tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
34dc7c2f
BB
1332}
1333
1334void
1335kernel_fini(void)
1336{
1eeb4562 1337 fletcher_4_fini();
34dc7c2f
BB
1338 spa_fini();
1339
0b04990a 1340 icp_fini();
428870ff 1341 system_taskq_fini();
1e33ac1e 1342 thread_fini();
428870ff 1343
0b04990a 1344 random_fini();
34dc7c2f
BB
1345}
1346
34dc7c2f
BB
1347uid_t
1348crgetuid(cred_t *cr)
1349{
1350 return (0);
1351}
1352
6f1ffb06
MA
1353uid_t
1354crgetruid(cred_t *cr)
1355{
1356 return (0);
1357}
1358
34dc7c2f
BB
1359gid_t
1360crgetgid(cred_t *cr)
1361{
1362 return (0);
1363}
1364
1365int
1366crgetngroups(cred_t *cr)
1367{
1368 return (0);
1369}
1370
1371gid_t *
1372crgetgroups(cred_t *cr)
1373{
1374 return (NULL);
1375}
1376
1377int
1378zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
1379{
1380 return (0);
1381}
1382
1383int
1384zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
1385{
1386 return (0);
1387}
1388
1389int
1390zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
1391{
1392 return (0);
1393}
1394
f74b821a
BB
1395int
1396secpolicy_zfs(const cred_t *cr)
1397{
1398 return (0);
1399}
1400
34dc7c2f
BB
1401ksiddomain_t *
1402ksid_lookupdomain(const char *dom)
1403{
1404 ksiddomain_t *kd;
1405
1406 kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
1407 kd->kd_name = spa_strdup(dom);
1408 return (kd);
1409}
1410
1411void
1412ksiddomain_rele(ksiddomain_t *ksid)
1413{
1414 spa_strfree(ksid->kd_name);
1415 umem_free(ksid, sizeof (ksiddomain_t));
1416}
428870ff 1417
428870ff 1418char *
00b46022 1419kmem_vasprintf(const char *fmt, va_list adx)
428870ff 1420{
00b46022
BB
1421 char *buf = NULL;
1422 va_list adx_copy;
428870ff 1423
00b46022
BB
1424 va_copy(adx_copy, adx);
1425 VERIFY(vasprintf(&buf, fmt, adx_copy) != -1);
1426 va_end(adx_copy);
428870ff 1427
00b46022
BB
1428 return (buf);
1429}
1430
1431char *
1432kmem_asprintf(const char *fmt, ...)
1433{
1434 char *buf = NULL;
1435 va_list adx;
428870ff
BB
1436
1437 va_start(adx, fmt);
00b46022 1438 VERIFY(vasprintf(&buf, fmt, adx) != -1);
428870ff
BB
1439 va_end(adx);
1440
1441 return (buf);
1442}
572e2857
BB
1443
1444/* ARGSUSED */
1445int
1446zfs_onexit_fd_hold(int fd, minor_t *minorp)
1447{
1448 *minorp = 0;
1449 return (0);
1450}
1451
1452/* ARGSUSED */
1453void
1454zfs_onexit_fd_rele(int fd)
1455{
1456}
1457
1458/* ARGSUSED */
1459int
1460zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
1461 uint64_t *action_handle)
1462{
1463 return (0);
1464}
1465
1466/* ARGSUSED */
1467int
1468zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire)
1469{
1470 return (0);
1471}
1472
1473/* ARGSUSED */
1474int
1475zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data)
1476{
1477 return (0);
1478}
92119cc2
BB
1479
1480fstrans_cookie_t
1481spl_fstrans_mark(void)
1482{
1483 return ((fstrans_cookie_t) 0);
1484}
1485
1486void
1487spl_fstrans_unmark(fstrans_cookie_t cookie)
1488{
1489}
1490
1491int
1492spl_fstrans_check(void)
1493{
1494 return (0);
1495}
a0bd735a 1496
47dfff3b
MA
1497void *zvol_tag = "zvol_tag";
1498
a0bd735a
BP
1499void
1500zvol_create_minors(spa_t *spa, const char *name, boolean_t async)
1501{
1502}
1503
1504void
1505zvol_remove_minor(spa_t *spa, const char *name, boolean_t async)
1506{
1507}
1508
1509void
1510zvol_remove_minors(spa_t *spa, const char *name, boolean_t async)
1511{
1512}
1513
1514void
1515zvol_rename_minors(spa_t *spa, const char *oldname, const char *newname,
1516 boolean_t async)
1517{
1518}