19313Ssos/*
29313Ssos * CDDL HEADER START
39313Ssos *
49313Ssos * The contents of this file are subject to the terms of the
59313Ssos * Common Development and Distribution License (the "License").
69313Ssos * You may not use this file except in compliance with the License.
79313Ssos *
89313Ssos * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99313Ssos * or http://www.opensolaris.org/os/licensing.
109313Ssos * See the License for the specific language governing permissions
119313Ssos * and limitations under the License.
129313Ssos *
139313Ssos * When distributing Covered Code, include this CDDL HEADER in each
149313Ssos * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159313Ssos * If applicable, add the following below this CDDL HEADER, with the
169313Ssos * fields enclosed by brackets "[]" replaced with your own identifying
179313Ssos * information: Portions Copyright [yyyy] [name of copyright owner]
189313Ssos *
199313Ssos * CDDL HEADER END
209313Ssos */
219313Ssos/*
229313Ssos * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
239313Ssos * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
249313Ssos * Copyright (c) 2012, Joyent, Inc. All rights reserved.
259313Ssos */
269313Ssos/*
279313Ssos * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
2850477Speter */
299313Ssos
309313Ssos#ifndef _SYS_ZFS_CONTEXT_H
3131784Seivind#define	_SYS_ZFS_CONTEXT_H
3231784Seivind
339313Ssos#ifdef	__cplusplus
349313Ssosextern "C" {
3512458Sbde#endif
369313Ssos
379313Ssos#define	_SYS_MUTEX_H
389313Ssos#define	_SYS_RWLOCK_H
3931561Sbde#define	_SYS_CONDVAR_H
409313Ssos#define	_SYS_SYSTM_H
419313Ssos#define	_SYS_T_LOCK_H
429313Ssos#define	_SYS_VNODE_H
4372538Sjlemon#define	_SYS_VFS_H
449313Ssos#define	_SYS_SUNDDI_H
4514331Speter#define	_SYS_CALLB_H
4614331Speter#define	_SYS_SCHED_H_
4712458Sbde
4872538Sjlemon#include <solaris.h>
4972538Sjlemon#include <stdio.h>
5072538Sjlemon#include <stdlib.h>
5172538Sjlemon#include <stddef.h>
5264905Smarcel#include <stdarg.h>
5368583Smarcel#include <fcntl.h>
5464905Smarcel#include <unistd.h>
559313Ssos#include <errno.h>
5668201Sobrien#include <string.h>
579313Ssos#include <strings.h>
5830994Sphk#include <thread.h>
599313Ssos#include <assert.h>
6012858Speter#include <limits.h>
619313Ssos#include <dirent.h>
629313Ssos#include <time.h>
639313Ssos#include <math.h>
6412858Speter#include <umem.h>
6514331Speter#include <inttypes.h>
669313Ssos#include <fsshare.h>
6714331Speter#include <pthread.h>
6814331Speter#include <sched.h>
6914331Speter#include <sys/debug.h>
709313Ssos#include <sys/note.h>
719313Ssos#include <sys/types.h>
729313Ssos#include <sys/cred.h>
739313Ssos#include <sys/atomic.h>
749313Ssos#include <sys/sysmacros.h>
759313Ssos#include <sys/bitmap.h>
769313Ssos#include <sys/resource.h>
7730994Sphk#include <sys/byteorder.h>
789313Ssos#include <sys/list.h>
7968201Sobrien#include <sys/time.h>
809313Ssos#include <sys/uio.h>
819313Ssos#include <sys/mntent.h>
8230994Sphk#include <sys/mnttab.h>
839313Ssos#include <sys/zfs_debug.h>
8412858Speter#include <sys/sdt.h>
859313Ssos#include <sys/kstat.h>
869313Ssos#include <sys/u8_textprep.h>
879313Ssos#include <sys/kernel.h>
8812858Speter#include <sys/disk.h>
899313Ssos#include <sys/sysevent.h>
9014331Speter#include <sys/sysevent/eventdefs.h>
9114331Speter#include <sys/sysevent/dev.h>
9214331Speter#include <machine/atomic.h>
939313Ssos#include <sys/debug.h>
9414331Speter#ifdef illumos
9514331Speter#include "zfs.h"
9614331Speter#endif
9714331Speter
9814331Speter#define	ZFS_EXPORTS_PATH	"/etc/zfs/exports"
999313Ssos
1009313Ssos/*
1019313Ssos * Debugging
1029313Ssos */
1039313Ssos
1049313Ssos/*
1059313Ssos * Note that we are not using the debugging levels.
1069313Ssos */
1079313Ssos
1089313Ssos#define	CE_CONT		0	/* continuation		*/
1099313Ssos#define	CE_NOTE		1	/* notice		*/
1109313Ssos#define	CE_WARN		2	/* warning		*/
1119313Ssos#define	CE_PANIC	3	/* panic		*/
1129313Ssos#define	CE_IGNORE	4	/* print nothing	*/
1139313Ssos
1149313Ssos/*
1159313Ssos * ZFS debugging
1169313Ssos */
1179313Ssos
1189313Ssos#define	ZFS_LOG(...)	do {  } while (0)
1199313Ssos
1209313Ssostypedef u_longlong_t      rlim64_t;
1219313Ssos#define	RLIM64_INFINITY	((rlim64_t)-3)
1229313Ssos
1239313Ssos#ifdef ZFS_DEBUG
1249313Ssosextern void dprintf_setup(int *argc, char **argv);
1259313Ssos#endif /* ZFS_DEBUG */
1269313Ssos
1279313Ssosextern void cmn_err(int, const char *, ...);
1289313Ssosextern void vcmn_err(int, const char *, __va_list);
1299313Ssosextern void panic(const char *, ...);
1309313Ssosextern void vpanic(const char *, __va_list);
13130994Sphk
13270061Sjhb#define	fm_panic	panic
1339313Ssos
1349313Ssosextern int aok;
1359313Ssos
13630994Sphk/*
1379313Ssos * DTrace SDT probes have different signatures in userland than they do in
13870061Sjhb * kernel.  If they're being used in kernel code, re-define them out of
1399313Ssos * existence for their counterparts in libzpool.
14051418Sgreen */
14170061Sjhb
14270061Sjhb#ifdef DTRACE_PROBE
14314331Speter#undef	DTRACE_PROBE
14414331Speter#endif	/* DTRACE_PROBE */
14514331Speter#ifdef illumos
14614331Speter#define	DTRACE_PROBE(a) \
1479313Ssos	ZFS_PROBE0(#a)
1489313Ssos#endif
1499313Ssos
1509313Ssos#ifdef DTRACE_PROBE1
1519313Ssos#undef	DTRACE_PROBE1
1529313Ssos#endif	/* DTRACE_PROBE1 */
1539313Ssos#ifdef illumos
1549313Ssos#define	DTRACE_PROBE1(a, b, c) \
1559313Ssos	ZFS_PROBE1(#a, (unsigned long)c)
1569313Ssos#endif
1579313Ssos
1589313Ssos#ifdef DTRACE_PROBE2
1599313Ssos#undef	DTRACE_PROBE2
1609313Ssos#endif	/* DTRACE_PROBE2 */
1619313Ssos#ifdef illumos
1629313Ssos#define	DTRACE_PROBE2(a, b, c, d, e) \
1639313Ssos	ZFS_PROBE2(#a, (unsigned long)c, (unsigned long)e)
1649313Ssos#endif
1659313Ssos
1669313Ssos#ifdef DTRACE_PROBE3
1679313Ssos#undef	DTRACE_PROBE3
1689313Ssos#endif	/* DTRACE_PROBE3 */
1699313Ssos#ifdef illumos
1709313Ssos#define	DTRACE_PROBE3(a, b, c, d, e, f, g) \
17149676Smarcel	ZFS_PROBE3(#a, (unsigned long)c, (unsigned long)e, (unsigned long)g)
17249676Smarcel#endif
17349676Smarcel
1749313Ssos#ifdef DTRACE_PROBE4
1759313Ssos#undef	DTRACE_PROBE4
1769313Ssos#endif	/* DTRACE_PROBE4 */
1779313Ssos#ifdef illumos
1789313Ssos#define	DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) \
1799313Ssos	ZFS_PROBE4(#a, (unsigned long)c, (unsigned long)e, (unsigned long)g, \
1809313Ssos	(unsigned long)i)
1819313Ssos#endif
1829313Ssos
1839313Ssos#ifdef illumos
1849313Ssos/*
1859313Ssos * We use the comma operator so that this macro can be used without much
1869313Ssos * additional code.  For example, "return (EINVAL);" becomes
1879313Ssos * "return (SET_ERROR(EINVAL));".  Note that the argument will be evaluated
1889313Ssos * twice, so it should not have side effects (e.g. something like:
1899313Ssos * "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice).
1909313Ssos */
1919313Ssos#define	SET_ERROR(err)	(ZFS_SET_ERROR(err), err)
1929313Ssos#else	/* !illumos */
1939313Ssos
1949313Ssos#define	DTRACE_PROBE(a)	((void)0)
1959313Ssos#define	DTRACE_PROBE1(a, b, c)	((void)0)
1969313Ssos#define	DTRACE_PROBE2(a, b, c, d, e)	((void)0)
1979313Ssos#define	DTRACE_PROBE3(a, b, c, d, e, f, g)	((void)0)
1989313Ssos#define	DTRACE_PROBE4(a, b, c, d, e, f, g, h, i)	((void)0)
1999313Ssos
2009313Ssos#define SET_ERROR(err) (err)
2019313Ssos#endif	/* !illumos */
20230994Sphk
2039313Ssos/*
2049313Ssos * Threads
20512858Speter */
2069313Ssos#define	curthread	((void *)(uintptr_t)thr_self())
2079313Ssos
20868662Smarcel#define	kpreempt(x)	sched_yield()
20968662Smarcel
2109313Ssostypedef struct kthread kthread_t;
21114331Speter
21268662Smarcel#define	thread_create(stk, stksize, func, arg, len, pp, state, pri)	\
21368662Smarcel	zk_thread_create(func, arg)
21414331Speter#define	thread_exit() thr_exit(NULL)
2159313Ssos#define	thread_join(t)	panic("libzpool cannot join threads")
21614331Speter
21714331Speter#define	newproc(f, a, cid, pri, ctp, pid)	(ENOSYS)
21814331Speter
2199313Ssos/* in libzpool, p0 exists only to have its address taken */
22068662Smarcelstruct proc {
22168662Smarcel	uintptr_t	this_is_never_used_dont_dereference_it;
2229313Ssos};
2239313Ssos
2249313Ssosextern struct proc p0;
2259313Ssos#define	curproc		(&p0)
2269313Ssos
2279313Ssos#define	PS_NONE		-1
22849845Smarcel
22930994Sphkextern kthread_t *zk_thread_create(void (*func)(), void *arg);
2309313Ssos
2319313Ssos#define	issig(why)	(FALSE)
2329313Ssos#define	ISSIG(thr, why)	(FALSE)
23330994Sphk
2349313Ssos/*
2359313Ssos * Mutexes
2369313Ssos */
23749845Smarceltypedef struct kmutex {
23830994Sphk	void		*m_owner;
2399313Ssos	boolean_t	initialized;
2409313Ssos	mutex_t		m_lock;
2419313Ssos} kmutex_t;
24230994Sphk
24330994Sphk#define	MUTEX_DEFAULT	USYNC_THREAD
24430994Sphk#undef	MUTEX_HELD
24530994Sphk#undef	MUTEX_NOT_HELD
24630994Sphk#define	MUTEX_HELD(m)	((m)->m_owner == curthread)
24730994Sphk#define	MUTEX_NOT_HELD(m) (!MUTEX_HELD(m))
24830994Sphk#define	_mutex_held(m)	pthread_mutex_isowned_np(m)
24930994Sphk
25030994Sphk/*
25139978Sjfieber * Argh -- we have to get cheesy here because the kernel and userland
2529313Ssos * have different signatures for the same routine.
2539313Ssos */
2549313Ssos//extern int _mutex_init(mutex_t *mp, int type, void *arg);
25549845Smarcel//extern int _mutex_destroy(mutex_t *mp);
2569313Ssos//extern int _mutex_owned(mutex_t *mp);
2579313Ssos
2589313Ssos#define	mutex_init(mp, b, c, d)		zmutex_init((kmutex_t *)(mp))
25939978Sjfieber#define	mutex_destroy(mp)		zmutex_destroy((kmutex_t *)(mp))
2609313Ssos#define	mutex_owned(mp)			zmutex_owned((kmutex_t *)(mp))
26130994Sphk
26249676Smarcelextern void zmutex_init(kmutex_t *mp);
2639313Ssosextern void zmutex_destroy(kmutex_t *mp);
2649313Ssosextern int zmutex_owned(kmutex_t *mp);
2659313Ssosextern void mutex_enter(kmutex_t *mp);
2669313Ssosextern void mutex_exit(kmutex_t *mp);
2679313Ssosextern int mutex_tryenter(kmutex_t *mp);
2689313Ssosextern void *mutex_owner(kmutex_t *mp);
26968201Sobrien
27046571Speter/*
27146571Speter * RW locks
2729313Ssos */
2739313Ssostypedef struct krwlock {
2749313Ssos	int		rw_count;
2759313Ssos	void		*rw_owner;
2769313Ssos	boolean_t	initialized;
2779313Ssos	rwlock_t	rw_lock;
2789313Ssos} krwlock_t;
2799313Ssos
2809313Ssostypedef int krw_t;
2819313Ssos
2829313Ssos#define	RW_READER	0
28368201Sobrien#define	RW_WRITER	1
28430994Sphk#define	RW_DEFAULT	USYNC_THREAD
2859313Ssos
2869313Ssos#undef RW_READ_HELD
2879313Ssos#define RW_READ_HELD(x)		((x)->rw_owner == NULL && (x)->rw_count > 0)
2889313Ssos
2899313Ssos#undef RW_WRITE_HELD
2909313Ssos#define	RW_WRITE_HELD(x)	((x)->rw_owner == curthread)
2919313Ssos#define	RW_LOCK_HELD(x)		rw_lock_held(x)
29268201Sobrien
29330994Sphk#undef RW_LOCK_HELD
2949313Ssos#define	RW_LOCK_HELD(x)		(RW_READ_HELD(x) || RW_WRITE_HELD(x))
29563233Smarcel
29663233Smarcelextern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
29763233Smarcelextern void rw_destroy(krwlock_t *rwlp);
29863233Smarcelextern void rw_enter(krwlock_t *rwlp, krw_t rw);
2999313Ssosextern int rw_tryenter(krwlock_t *rwlp, krw_t rw);
30068662Smarcelextern int rw_tryupgrade(krwlock_t *rwlp);
30168662Smarcelextern void rw_exit(krwlock_t *rwlp);
30268662Smarcelextern int rw_lock_held(krwlock_t *rwlp);
30368662Smarcel#define	rw_downgrade(rwlp) do { } while (0)
30468662Smarcel
30568662Smarcelextern uid_t crgetuid(cred_t *cr);
30668662Smarcelextern uid_t crgetruid(cred_t *cr);
30768662Smarcelextern gid_t crgetgid(cred_t *cr);
30868662Smarcelextern int crgetngroups(cred_t *cr);
30968662Smarcelextern gid_t *crgetgroups(cred_t *cr);
31068662Smarcel
31168662Smarcel/*
31268662Smarcel * Condition variables
31363233Smarcel */
31463233Smarceltypedef cond_t kcondvar_t;
3159313Ssos
3169313Ssos#define	CV_DEFAULT	USYNC_THREAD
3179313Ssos
3189313Ssosextern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
3199313Ssosextern void cv_destroy(kcondvar_t *cv);
32030994Sphkextern void cv_wait(kcondvar_t *cv, kmutex_t *mp);
3219313Ssosextern clock_t cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime);
3229313Ssosextern clock_t cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
32312858Speter    hrtime_t res, int flag);
32412858Speterextern void cv_signal(kcondvar_t *cv);
3259313Ssosextern void cv_broadcast(kcondvar_t *cv);
32612858Speter
3279313Ssos/*
32812858Speter * Thread-specific data
3299313Ssos */
3309313Ssos#define	tsd_get(k) pthread_getspecific(k)
3319313Ssos#define	tsd_set(k, v) pthread_setspecific(k, v)
33237950Sbde#define	tsd_create(kp, d) pthread_key_create(kp, d)
33337950Sbde#define	tsd_destroy(kp) /* nothing */
3349313Ssos
33512858Speter/*
33612858Speter * Kernel memory
3379313Ssos */
33830994Sphk#define	KM_SLEEP		UMEM_NOFAIL
3399313Ssos#define	KM_PUSHPAGE		KM_SLEEP
3409313Ssos#define	KM_NOSLEEP		UMEM_DEFAULT
3419313Ssos#define	KM_NODEBUG		0
34268201Sobrien#define	KMC_NODEBUG		UMC_NODEBUG
34314331Speter#define	KMC_NOTOUCH		0	/* not needed for userland caches */
34430994Sphk#define	kmem_alloc(_s, _f)	umem_alloc(_s, _f)
34514331Speter#define	kmem_zalloc(_s, _f)	umem_zalloc(_s, _f)
34614331Speter#define	kmem_free(_b, _s)	umem_free(_b, _s)
34714331Speter#define	kmem_size()		(physmem * PAGESIZE)
34814331Speter#define	kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \
34914331Speter	umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i)
35014331Speter#define	kmem_cache_destroy(_c)	umem_cache_destroy(_c)
35114331Speter#define	kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f)
35214331Speter#define	kmem_cache_free(_c, _b)	umem_cache_free(_c, _b)
35314331Speter#define	kmem_debugging()	0
35414331Speter#define	kmem_cache_reap_now(_c)		/* nothing */
35514331Speter#define	kmem_cache_set_move(_c, _cb)	/* nothing */
35614331Speter#define	POINTER_INVALIDATE(_pp)		/* nothing */
35714331Speter#define	POINTER_IS_VALID(_p)	0
35814331Speter
35914331Spetertypedef umem_cache_t kmem_cache_t;
36030994Sphk
36114331Spetertypedef enum kmem_cbrc {
36214331Speter	KMEM_CBRC_YES,
36330994Sphk	KMEM_CBRC_NO,
36414331Speter	KMEM_CBRC_LATER,
36514331Speter	KMEM_CBRC_DONT_NEED,
36630994Sphk	KMEM_CBRC_DONT_KNOW
36714331Speter} kmem_cbrc_t;
36814331Speter
36968201Sobrien/*
37014331Speter * Task queues
37114331Speter */
3729313Ssostypedef struct taskq taskq_t;
3739313Ssostypedef uintptr_t taskqid_t;
3749313Ssostypedef void (task_func_t)(void *);
3759313Ssos
3769313Ssostypedef struct taskq_ent {
3779313Ssos	struct taskq_ent	*tqent_next;
3789313Ssos	struct taskq_ent	*tqent_prev;
3799313Ssos	task_func_t		*tqent_func;
3809313Ssos	void			*tqent_arg;
3819313Ssos	uintptr_t		tqent_flags;
38268201Sobrien} taskq_ent_t;
3839313Ssos
38430994Sphk#define	TQENT_FLAG_PREALLOC	0x1	/* taskq_dispatch_ent used */
3859313Ssos
38614331Speter#define	TASKQ_PREPOPULATE	0x0001
38714331Speter#define	TASKQ_CPR_SAFE		0x0002	/* Use CPR safe protocol */
38814331Speter#define	TASKQ_DYNAMIC		0x0004	/* Use dynamic thread scheduling */
38914331Speter#define	TASKQ_THREADS_CPU_PCT	0x0008	/* Scale # threads by # cpus */
39014331Speter#define	TASKQ_DC_BATCH		0x0010	/* Mark threads as batch */
39130994Sphk
39214331Speter#define	TQ_SLEEP	KM_SLEEP	/* Can block for memory */
39368201Sobrien#define	TQ_NOSLEEP	KM_NOSLEEP	/* cannot block for memory; may fail */
39414331Speter#define	TQ_NOQUEUE	0x02		/* Do not enqueue if can't dispatch */
39514331Speter#define	TQ_FRONT	0x08		/* Queue in front */
39630994Sphk
39714331Speter
3989313Ssosextern taskq_t *system_taskq;
3999313Ssos
4009313Ssosextern taskq_t	*taskq_create(const char *, int, pri_t, int, int, uint_t);
4019313Ssos#define	taskq_create_proc(a, b, c, d, e, p, f) \
4029313Ssos	    (taskq_create(a, b, c, d, e, f))
4039313Ssos#define	taskq_create_sysdc(a, b, d, e, p, dc, f) \
4049313Ssos	    (taskq_create(a, b, maxclsyspri, d, e, f))
4059313Ssosextern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
4069313Ssosextern void	taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
4079313Ssos    taskq_ent_t *);
4089313Ssosextern void	taskq_destroy(taskq_t *);
4099313Ssosextern void	taskq_wait(taskq_t *);
41024654Sdfrextern int	taskq_member(taskq_t *, void *);
41124654Sdfrextern void	system_taskq_init(void);
41224654Sdfrextern void	system_taskq_fini(void);
4139313Ssos
4149313Ssos#define	taskq_dispatch_safe(tq, func, arg, flags, task)			\
41514331Speter	taskq_dispatch((tq), (func), (arg), (flags))
4169313Ssos
4179313Ssos#define	XVA_MAPSIZE	3
41810355Sswallace#define	XVA_MAGIC	0x78766174
4199313Ssos
42014331Speter/*
4219313Ssos * vnodes
4229313Ssos */
4239313Ssostypedef struct vnode {
4249313Ssos	uint64_t	v_size;
4259313Ssos	int		v_fd;
4269313Ssos	char		*v_path;
4279313Ssos} vnode_t;
4289313Ssos
4299313Ssos#define	AV_SCANSTAMP_SZ	32		/* length of anti-virus scanstamp */
43071699Sjhb
4319313Ssostypedef struct xoptattr {
43211418Sswallace	timestruc_t	xoa_createtime;	/* Create time of file */
4339313Ssos	uint8_t		xoa_archive;
4349313Ssos	uint8_t		xoa_system;
4359313Ssos	uint8_t		xoa_readonly;
4369313Ssos	uint8_t		xoa_hidden;
4379313Ssos	uint8_t		xoa_nounlink;
4389313Ssos	uint8_t		xoa_immutable;
4399313Ssos	uint8_t		xoa_appendonly;
4409313Ssos	uint8_t		xoa_nodump;
4419313Ssos	uint8_t		xoa_settable;
44210355Sswallace	uint8_t		xoa_opaque;
44324672Sdfr	uint8_t		xoa_av_quarantined;
44424654Sdfr	uint8_t		xoa_av_modified;
44511418Sswallace	uint8_t		xoa_av_scanstamp[AV_SCANSTAMP_SZ];
4469313Ssos	uint8_t		xoa_reparse;
44722521Sdyson	uint8_t		xoa_offline;
4489313Ssos	uint8_t		xoa_sparse;
4499313Ssos} xoptattr_t;
4509313Ssos
4519313Ssostypedef struct vattr {
4529313Ssos	uint_t		va_mask;	/* bit-mask of attributes */
4539313Ssos	u_offset_t	va_size;	/* file size in bytes */
4549313Ssos} vattr_t;
4559313Ssos
4569313Ssos
45724654Sdfrtypedef struct xvattr {
4589313Ssos	vattr_t		xva_vattr;	/* Embedded vattr structure */
45924654Sdfr	uint32_t	xva_magic;	/* Magic Number */
46024654Sdfr	uint32_t	xva_mapsize;	/* Size of attr bitmap (32-bit words) */
46124654Sdfr	uint32_t	*xva_rtnattrmapp;	/* Ptr to xva_rtnattrmap[] */
46224654Sdfr	uint32_t	xva_reqattrmap[XVA_MAPSIZE];	/* Requested attrs */
46324654Sdfr	uint32_t	xva_rtnattrmap[XVA_MAPSIZE];	/* Returned attrs */
46424654Sdfr	xoptattr_t	xva_xoptattrs;	/* Optional attributes */
46510355Sswallace} xvattr_t;
4669313Ssos
46714331Spetertypedef struct vsecattr {
4689313Ssos	uint_t		vsa_mask;	/* See below */
4699313Ssos	int		vsa_aclcnt;	/* ACL entry count */
4709313Ssos	void		*vsa_aclentp;	/* pointer to ACL entries */
4719313Ssos	int		vsa_dfaclcnt;	/* default ACL entry count */
47224654Sdfr	void		*vsa_dfaclentp;	/* pointer to default ACL entries */
4739313Ssos	size_t		vsa_aclentsz;	/* ACE size in bytes of vsa_aclentp */
47414331Speter} vsecattr_t;
4759313Ssos
47624654Sdfr#define	AT_TYPE		0x00001
47724654Sdfr#define	AT_MODE		0x00002
47824654Sdfr#define	AT_UID		0x00004
47924654Sdfr#define	AT_GID		0x00008
48024654Sdfr#define	AT_FSID		0x00010
48124654Sdfr#define	AT_NODEID	0x00020
48224654Sdfr#define	AT_NLINK	0x00040
48324654Sdfr#define	AT_SIZE		0x00080
48424654Sdfr#define	AT_ATIME	0x00100
48524654Sdfr#define	AT_MTIME	0x00200
48624654Sdfr#define	AT_CTIME	0x00400
48724654Sdfr#define	AT_RDEV		0x00800
48824654Sdfr#define	AT_BLKSIZE	0x01000
48924654Sdfr#define	AT_NBLOCKS	0x02000
49024654Sdfr#define	AT_SEQ		0x08000
49124654Sdfr#define	AT_XVATTR	0x10000
49224654Sdfr
49324654Sdfr#define	CRCREAT		0
49424654Sdfr
4959313Ssosextern int fop_getattr(vnode_t *vp, vattr_t *vap);
49624654Sdfr
49724654Sdfr#define	VOP_CLOSE(vp, f, c, o, cr, ct)	0
49810355Sswallace#define	VOP_PUTPAGE(vp, of, sz, fl, cr, ct)	0
49910355Sswallace#define	VOP_GETATTR(vp, vap, cr)  fop_getattr((vp), (vap));
50010355Sswallace
50110355Sswallace#define	VOP_FSYNC(vp, f, cr, ct)	fsync((vp)->v_fd)
50210355Sswallace
50310355Sswallace#define	VN_RELE(vp)			vn_close(vp, 0, NULL, NULL)
50410355Sswallace#define	VN_RELE_ASYNC(vp, taskq)	vn_close(vp, 0, NULL, NULL)
50510355Sswallace
5069313Ssos#define	vn_lock(vp, type)
5079313Ssos#define	VOP_UNLOCK(vp, type)
50824654Sdfr#ifdef VFS_LOCK_GIANT
50924654Sdfr#undef VFS_LOCK_GIANT
51024654Sdfr#endif
51124654Sdfr#define	VFS_LOCK_GIANT(mp)	0
51224654Sdfr#ifdef VFS_UNLOCK_GIANT
51310355Sswallace#undef VFS_UNLOCK_GIANT
5149313Ssos#endif
5159313Ssos#define	VFS_UNLOCK_GIANT(vfslocked)
5169313Ssos
5179313Ssosextern int vn_open(char *path, int x1, int oflags, int mode, vnode_t **vpp,
5189313Ssos    int x2, int x3);
5199313Ssosextern int vn_openat(char *path, int x1, int oflags, int mode, vnode_t **vpp,
5209313Ssos    int x2, int x3, vnode_t *vp, int fd);
5219313Ssosextern int vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len,
52214465Speter    offset_t offset, int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp);
52314465Speterextern void vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td);
52414465Speter
52514465Speter#define	vn_remove(path, x1, x2)		remove(path)
52614465Speter#define	vn_rename(from, to, seg)	rename((from), (to))
52714465Speter#define	vn_is_readonly(vp)		B_FALSE
52814465Speter
52968347Smarcelextern vnode_t *rootdir;
53068347Smarcel
53168347Smarcel#include <sys/file.h>		/* for FREAD, FWRITE, etc */
53268347Smarcel#define	FTRUNC	O_TRUNC
53314465Speter
53414465Speter/*
5359313Ssos * Random stuff
53610355Sswallace */
5379313Ssos#define	ddi_get_lbolt()		(gethrtime() >> 23)
53814331Speter#define	ddi_get_lbolt64()	(gethrtime() >> 23)
5399313Ssos#define	hz	119	/* frequency when using gethrtime() >> 23 for lbolt */
54024654Sdfr
54124654Sdfrextern void delay(clock_t ticks);
54224654Sdfr
54324654Sdfr#define	SEC_TO_TICK(sec)	((sec) * hz)
54424654Sdfr#define	NSEC_TO_TICK(usec)	((usec) / (NANOSEC / hz))
5459313Ssos
5469313Ssos#define	gethrestime_sec() time(NULL)
5479313Ssos#define	gethrestime(t) \
5489313Ssos	do {\
5499313Ssos		(t)->tv_sec = gethrestime_sec();\
5509313Ssos		(t)->tv_nsec = 0;\
5519313Ssos	} while (0);
5529313Ssos
5539313Ssos#define	max_ncpus	64
5549313Ssos
5559313Ssos#define	minclsyspri	60
5569313Ssos#define	maxclsyspri	99
5579313Ssos
55810355Sswallace#define	CPU_SEQID	(thr_self() & (max_ncpus - 1))
5599313Ssos
56030994Sphk#define	kcred		NULL
5619313Ssos#define	CRED()		NULL
56224654Sdfr
56324654Sdfr#ifndef ptob
56422543Smpp#define	ptob(x)		((x) * PAGESIZE)
5659313Ssos#endif
5669313Ssos
5679313Ssosextern uint64_t physmem;
56814331Speter
56914331Speterextern int highbit64(uint64_t i);
57014331Speterextern int random_get_bytes(uint8_t *ptr, size_t len);
57114331Speterextern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
57214331Speter
57314331Speterextern void kernel_init(int);
57430994Sphkextern void kernel_fini(void);
57514331Speter
57614331Speterstruct spa;
57714331Speterextern void nicenum(uint64_t num, char *buf);
57814331Speterextern void show_pool_stats(struct spa *);
57914331Speter
58014331Spetertypedef struct callb_cpr {
58114331Speter	kmutex_t	*cc_lockp;
58214331Speter} callb_cpr_t;
58314331Speter
58414331Speter#define	CALLB_CPR_INIT(cp, lockp, func, name)	{		\
58514331Speter	(cp)->cc_lockp = lockp;					\
58614331Speter}
58714331Speter
58814331Speter#define	CALLB_CPR_SAFE_BEGIN(cp) {				\
58930994Sphk	ASSERT(MUTEX_HELD((cp)->cc_lockp));			\
59014331Speter}
59114331Speter
59214331Speter#define	CALLB_CPR_SAFE_END(cp, lockp) {				\
59330994Sphk	ASSERT(MUTEX_HELD((cp)->cc_lockp));			\
59414331Speter}
59514331Speter
59614331Speter#define	CALLB_CPR_EXIT(cp) {					\
59714331Speter	ASSERT(MUTEX_HELD((cp)->cc_lockp));			\
59814331Speter	mutex_exit((cp)->cc_lockp);				\
59914331Speter}
60014331Speter
60114331Speter#define	zone_dataset_visible(x, y)	(1)
60214331Speter#define	INGLOBALZONE(z)			(1)
60314331Speter
60414331Speterextern char *kmem_asprintf(const char *fmt, ...);
60514331Speter#define	strfree(str) kmem_free((str), strlen(str) + 1)
60614331Speter
60730994Sphk/*
60814331Speter * Hostname information
60914331Speter */
61014331Speterextern struct utsname utsname;
61130994Sphkextern char hw_serial[];	/* for userland-emulated hostid access */
61214331Speterextern int ddi_strtoul(const char *str, char **nptr, int base,
61314331Speter    unsigned long *result);
61414331Speter
61514331Speterextern int ddi_strtoull(const char *str, char **nptr, int base,
61614331Speter    u_longlong_t *result);
61714331Speter
61814331Speter/* ZFS Boot Related stuff. */
61914331Speter
62014331Speterstruct _buf {
62114331Speter	intptr_t	_fd;
62214331Speter};
62314331Speter
62414331Speterstruct bootstat {
62530994Sphk	uint64_t st_size;
62614331Speter};
62714331Speter
62814331Spetertypedef struct ace_object {
62930994Sphk	uid_t		a_who;
63014331Speter	uint32_t	a_access_mask;
63114331Speter	uint16_t	a_flags;
63214331Speter	uint16_t	a_type;
63314331Speter	uint8_t		a_obj_type[16];
63414331Speter	uint8_t		a_inherit_obj_type[16];
63514331Speter} ace_object_t;
63614331Speter
63714331Speter
63814331Speter#define	ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE	0x05
63914331Speter#define	ACE_ACCESS_DENIED_OBJECT_ACE_TYPE	0x06
64014331Speter#define	ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE	0x07
64114331Speter#define	ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE	0x08
64214331Speter
64314331Speterextern struct _buf *kobj_open_file(char *name);
64430994Sphkextern int kobj_read_file(struct _buf *file, char *buf, unsigned size,
64514331Speter    unsigned off);
64614331Speterextern void kobj_close_file(struct _buf *file);
64714331Speterextern int kobj_get_filesize(struct _buf *file, uint64_t *size);
64830994Sphkextern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
64914331Speterextern int zfs_secpolicy_rename_perms(const char *from, const char *to,
65014331Speter    cred_t *cr);
65114331Speterextern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
65214331Speterextern zoneid_t getzoneid(void);
65314331Speter/* Random compatibility stuff. */
65414331Speter#define	lbolt	(gethrtime() >> 23)
65514331Speter#define	lbolt64	(gethrtime() >> 23)
65614331Speter
65714331Speterextern uint64_t physmem;
65814331Speter
65914331Speter#define	gethrestime_sec()	time(NULL)
66014331Speter
66114331Speter#define	pwrite64(d, p, n, o)	pwrite(d, p, n, o)
66214331Speter#define	readdir64(d)		readdir(d)
66314331Speter#define	SIGPENDING(td)		(0)
66414331Speter#define	root_mount_wait()	do { } while (0)
66530994Sphk#define	root_mounted()		(1)
66614331Speter
66714331Speterstruct file {
66814331Speter	void *dummy;
66934941Speter};
67034941Speter
67134941Speter#define	FCREAT	O_CREAT
67234941Speter#define	FOFFMAX	0x0
67334941Speter
67434941Speter/* SID stuff */
67534941Spetertypedef struct ksiddomain {
67634941Speter	uint_t	kd_ref;
67734941Speter	uint_t	kd_len;
67834941Speter	char	*kd_name;
67934941Speter} ksiddomain_t;
68034941Speter
68134941Speterksiddomain_t *ksid_lookupdomain(const char *);
68234941Spetervoid ksiddomain_rele(ksiddomain_t *);
68334941Speter
68434941Spetertypedef	uint32_t	idmap_rid_t;
68534941Speter
68634941Speter#define	DDI_SLEEP	KM_SLEEP
68734941Speter#define	ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g)	(0)
68834941Speter
68934941Speter#define	SX_SYSINIT(name, lock, desc)
69030994Sphk
69114331Speter#define SYSCTL_HANDLER_ARGS struct sysctl_oid *oidp, void *arg1,	\
69214331Speter	intptr_t arg2, struct sysctl_req *req
69314331Speter
69414331Speter/*
69514331Speter * This describes the access space for a sysctl request.  This is needed
69614331Speter * so that we can use the interface from the kernel or from user-space.
69714331Speter */
69814331Speterstruct sysctl_req {
69914331Speter	struct thread	*td;		/* used for access checking */
70014331Speter	int		lock;		/* wiring state */
70114331Speter	void		*oldptr;
70214331Speter	size_t		oldlen;
70314331Speter	size_t		oldidx;
70414331Speter	int		(*oldfunc)(struct sysctl_req *, const void *, size_t);
70530994Sphk	void		*newptr;
70614331Speter	size_t		newlen;
70714331Speter	size_t		newidx;
70814331Speter	int		(*newfunc)(struct sysctl_req *, void *, size_t);
70930994Sphk	size_t		validlen;
71014331Speter	int		flags;
71114331Speter};
71214331Speter
71314331SpeterSLIST_HEAD(sysctl_oid_list, sysctl_oid);
71414331Speter
71514331Speter/*
71614331Speter * This describes one "oid" in the MIB tree.  Potentially more nodes can
71714331Speter * be hidden behind it, expanded by the handler.
71814331Speter */
71914331Speterstruct sysctl_oid {
72014331Speter	struct sysctl_oid_list *oid_parent;
72114331Speter	SLIST_ENTRY(sysctl_oid) oid_link;
72214331Speter	int		oid_number;
72330994Sphk	u_int		oid_kind;
72414331Speter	void		*oid_arg1;
72514331Speter	intptr_t	oid_arg2;
72614331Speter	const char	*oid_name;
72730994Sphk	int 		(*oid_handler)(SYSCTL_HANDLER_ARGS);
72814331Speter	const char	*oid_fmt;
72914331Speter	int		oid_refcnt;
73014331Speter	u_int		oid_running;
73114331Speter	const char	*oid_descr;
73214331Speter};
73314331Speter
73414331Speter#define	SYSCTL_DECL(...)
73514331Speter#define	SYSCTL_NODE(...)
73614331Speter#define	SYSCTL_INT(...)
73714331Speter#define	SYSCTL_UINT(...)
73814331Speter#define	SYSCTL_ULONG(...)
73914331Speter#define	SYSCTL_PROC(...)
74014331Speter#define	SYSCTL_QUAD(...)
74114331Speter#define	SYSCTL_UQUAD(...)
74214331Speter#ifdef TUNABLE_INT
74330994Sphk#undef TUNABLE_INT
74414331Speter#undef TUNABLE_ULONG
74514331Speter#undef TUNABLE_QUAD
74614331Speter#endif
74730994Sphk#define	TUNABLE_INT(...)
74814331Speter#define	TUNABLE_ULONG(...)
74914331Speter#define	TUNABLE_QUAD(...)
75014331Speter
75114331Speterint sysctl_handle_64(SYSCTL_HANDLER_ARGS);
75214331Speter
75314331Speter/* Errors */
75414331Speter
75514331Speter#ifndef	ERESTART
75614331Speter#define	ERESTART	(-1)
75714331Speter#endif
75814331Speter
75914331Speter#ifdef illumos
76014331Speter/*
76114331Speter * Cyclic information
76214331Speter */
76330994Sphkextern kmutex_t cpu_lock;
76414331Speter
76514331Spetertypedef uintptr_t cyclic_id_t;
76614331Spetertypedef uint16_t cyc_level_t;
76730994Sphktypedef void (*cyc_func_t)(void *);
76814331Speter
76914331Speter#define	CY_LOW_LEVEL	0
77014331Speter#define	CY_INFINITY	INT64_MAX
77114331Speter#define	CYCLIC_NONE	((cyclic_id_t)0)
77214331Speter
77314331Spetertypedef struct cyc_time {
77414331Speter	hrtime_t cyt_when;
77514331Speter	hrtime_t cyt_interval;
77637950Sbde} cyc_time_t;
77737950Sbde
77814331Spetertypedef struct cyc_handler {
77914331Speter	cyc_func_t cyh_func;
78014331Speter	void *cyh_arg;
78114331Speter	cyc_level_t cyh_level;
78214331Speter} cyc_handler_t;
78330994Sphk
78414331Speterextern cyclic_id_t cyclic_add(cyc_handler_t *, cyc_time_t *);
78514331Speterextern void cyclic_remove(cyclic_id_t);
78614331Speterextern int cyclic_reprogram(cyclic_id_t, hrtime_t);
78730994Sphk#endif	/* illumos */
78814331Speter
78942499Seivind#ifdef illumos
79014331Speter/*
79114331Speter * Buf structure
79214331Speter */
79314331Speter#define	B_BUSY		0x0001
79414331Speter#define	B_DONE		0x0002
79514331Speter#define	B_ERROR		0x0004
79632266Sjmb#define	B_READ		0x0040	/* read when I/O occurs */
79732266Sjmb#define	B_WRITE		0x0100	/* non-read pseudo-flag */
79814331Speter
79914331Spetertypedef struct buf {
80032265Sjmb	int	b_flags;
80114331Speter	size_t b_bcount;
80242499Seivind	union {
80314331Speter		caddr_t b_addr;
80414331Speter	} b_un;
80549662Smarcel
80649662Smarcel	lldaddr_t	_b_blkno;
80749662Smarcel#define	b_lblkno	_b_blkno._f
80849662Smarcel	size_t	b_resid;
80949662Smarcel	size_t	b_bufsize;
81049662Smarcel	int	(*b_iodone)(struct buf *);
81149662Smarcel	int	b_error;
81249662Smarcel	void	*b_private;
81349662Smarcel} buf_t;
81449662Smarcel
81549662Smarcelextern void bioinit(buf_t *);
81649662Smarcelextern void biodone(buf_t *);
81749662Smarcelextern void bioerror(buf_t *, int);
81849662Smarcelextern int geterror(buf_t *);
81949662Smarcel#endif
82049662Smarcel
82149662Smarcel#ifdef	__cplusplus
82249662Smarcel}
82349662Smarcel#endif
82449788Smarcel
82549788Smarcel#endif	/* _SYS_ZFS_CONTEXT_H */
82649788Smarcel