diff --git a/zfs/lib/libspl/Makefile.in b/zfs/lib/libspl/Makefile.in index cc197a7c0a..474311fe8a 100644 --- a/zfs/lib/libspl/Makefile.in +++ b/zfs/lib/libspl/Makefile.in @@ -2,16 +2,21 @@ subdir-m += include DISTFILES = kernel.c mkdirp.c strlcpy.c taskq.c util.c DISTFILES += list.c strlcat.c strnlen.c u8_textprep.c -LIBRARY := libzport +LIBRARY := libspl # Compile as shared library. There's an extra useless host program # here called 'zu' because it was the easiest way I could convince # the kernel build system to construct a user space shared library. HOSTCFLAGS += @HOSTCFLAGS@ -HOSTCFLAGS += -I@LIBDIR@/libzcommon/include +HOSTCFLAGS += -I@LIBDIR@/libumem/include HOSTCFLAGS += -I@LIBDIR@/libspl/include +HOSTLDFLAGS += -lumem -L@LIBDIR@/libumem + +# Additional shared library paths for executing binaries in-tree +export LD_RUN_PATH = @LIBDIR@/libumem + hostprogs-y := zu always := $(hostprogs-y) diff --git a/zfs/lib/libspl/include/atomic.h b/zfs/lib/libspl/include/atomic.h new file mode 100644 index 0000000000..8ce8f592dc --- /dev/null +++ b/zfs/lib/libspl/include/atomic.h @@ -0,0 +1,438 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_ATOMIC_H +#define _SYS_ATOMIC_H + + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_KERNEL) && defined(__GNUC__) && defined(_ASM_INLINES) && \ + (defined(__i386) || defined(__amd64)) +#include +#endif + +#if defined(_KERNEL) || defined(__STDC__) +/* + * Increment target. + */ +extern void atomic_inc_8(volatile uint8_t *); +extern void atomic_inc_uchar(volatile uchar_t *); +extern void atomic_inc_16(volatile uint16_t *); +extern void atomic_inc_ushort(volatile ushort_t *); +extern void atomic_inc_32(volatile uint32_t *); +extern void atomic_inc_uint(volatile uint_t *); +extern void atomic_inc_ulong(volatile ulong_t *); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern void atomic_inc_64(volatile uint64_t *); +#endif + +/* + * Decrement target + */ +extern void atomic_dec_8(volatile uint8_t *); +extern void atomic_dec_uchar(volatile uchar_t *); +extern void atomic_dec_16(volatile uint16_t *); +extern void atomic_dec_ushort(volatile ushort_t *); +extern void atomic_dec_32(volatile uint32_t *); +extern void atomic_dec_uint(volatile uint_t *); +extern void atomic_dec_ulong(volatile ulong_t *); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern void atomic_dec_64(volatile uint64_t *); +#endif + +/* + * Add delta to target + */ +extern void atomic_add_8(volatile uint8_t *, int8_t); +extern void atomic_add_char(volatile uchar_t *, signed char); +extern void atomic_add_16(volatile uint16_t *, int16_t); +extern void atomic_add_short(volatile ushort_t *, short); +extern void atomic_add_32(volatile uint32_t *, int32_t); +extern void atomic_add_int(volatile uint_t *, int); +extern void atomic_add_ptr(volatile void *, ssize_t); +extern void atomic_add_long(volatile ulong_t *, long); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern void atomic_add_64(volatile uint64_t *, int64_t); +#endif + +/* + * logical OR bits with target + */ +extern void atomic_or_8(volatile uint8_t *, uint8_t); +extern void atomic_or_uchar(volatile uchar_t *, uchar_t); +extern void atomic_or_16(volatile uint16_t *, uint16_t); +extern void atomic_or_ushort(volatile ushort_t *, ushort_t); +extern void atomic_or_32(volatile uint32_t *, uint32_t); +extern void atomic_or_uint(volatile uint_t *, uint_t); +extern void atomic_or_ulong(volatile ulong_t *, ulong_t); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern void atomic_or_64(volatile uint64_t *, uint64_t); +#endif + +/* + * logical AND bits with target + */ +extern void atomic_and_8(volatile uint8_t *, uint8_t); +extern void atomic_and_uchar(volatile uchar_t *, uchar_t); +extern void atomic_and_16(volatile uint16_t *, uint16_t); +extern void atomic_and_ushort(volatile ushort_t *, ushort_t); +extern void atomic_and_32(volatile uint32_t *, uint32_t); +extern void atomic_and_uint(volatile uint_t *, uint_t); +extern void atomic_and_ulong(volatile ulong_t *, ulong_t); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern void atomic_and_64(volatile uint64_t *, uint64_t); +#endif + +/* + * As above, but return the new value. Note that these _nv() variants are + * substantially more expensive on some platforms than the no-return-value + * versions above, so don't use them unless you really need to know the + * new value *atomically* (e.g. when decrementing a reference count and + * checking whether it went to zero). + */ + +/* + * Increment target and return new value. + */ +extern uint8_t atomic_inc_8_nv(volatile uint8_t *); +extern uchar_t atomic_inc_uchar_nv(volatile uchar_t *); +extern uint16_t atomic_inc_16_nv(volatile uint16_t *); +extern ushort_t atomic_inc_ushort_nv(volatile ushort_t *); +extern uint32_t atomic_inc_32_nv(volatile uint32_t *); +extern uint_t atomic_inc_uint_nv(volatile uint_t *); +extern ulong_t atomic_inc_ulong_nv(volatile ulong_t *); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern uint64_t atomic_inc_64_nv(volatile uint64_t *); +#endif + +/* + * Decrement target and return new value. + */ +extern uint8_t atomic_dec_8_nv(volatile uint8_t *); +extern uchar_t atomic_dec_uchar_nv(volatile uchar_t *); +extern uint16_t atomic_dec_16_nv(volatile uint16_t *); +extern ushort_t atomic_dec_ushort_nv(volatile ushort_t *); +extern uint32_t atomic_dec_32_nv(volatile uint32_t *); +extern uint_t atomic_dec_uint_nv(volatile uint_t *); +extern ulong_t atomic_dec_ulong_nv(volatile ulong_t *); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern uint64_t atomic_dec_64_nv(volatile uint64_t *); +#endif + +/* + * Add delta to target + */ +extern uint8_t atomic_add_8_nv(volatile uint8_t *, int8_t); +extern uchar_t atomic_add_char_nv(volatile uchar_t *, signed char); +extern uint16_t atomic_add_16_nv(volatile uint16_t *, int16_t); +extern ushort_t atomic_add_short_nv(volatile ushort_t *, short); +extern uint32_t atomic_add_32_nv(volatile uint32_t *, int32_t); +extern uint_t atomic_add_int_nv(volatile uint_t *, int); +extern void *atomic_add_ptr_nv(volatile void *, ssize_t); +extern ulong_t atomic_add_long_nv(volatile ulong_t *, long); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern uint64_t atomic_add_64_nv(volatile uint64_t *, int64_t); +#endif + +/* + * logical OR bits with target and return new value. + */ +extern uint8_t atomic_or_8_nv(volatile uint8_t *, uint8_t); +extern uchar_t atomic_or_uchar_nv(volatile uchar_t *, uchar_t); +extern uint16_t atomic_or_16_nv(volatile uint16_t *, uint16_t); +extern ushort_t atomic_or_ushort_nv(volatile ushort_t *, ushort_t); +extern uint32_t atomic_or_32_nv(volatile uint32_t *, uint32_t); +extern uint_t atomic_or_uint_nv(volatile uint_t *, uint_t); +extern ulong_t atomic_or_ulong_nv(volatile ulong_t *, ulong_t); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern uint64_t atomic_or_64_nv(volatile uint64_t *, uint64_t); +#endif + +/* + * logical AND bits with target and return new value. + */ +extern uint8_t atomic_and_8_nv(volatile uint8_t *, uint8_t); +extern uchar_t atomic_and_uchar_nv(volatile uchar_t *, uchar_t); +extern uint16_t atomic_and_16_nv(volatile uint16_t *, uint16_t); +extern ushort_t atomic_and_ushort_nv(volatile ushort_t *, ushort_t); +extern uint32_t atomic_and_32_nv(volatile uint32_t *, uint32_t); +extern uint_t atomic_and_uint_nv(volatile uint_t *, uint_t); +extern ulong_t atomic_and_ulong_nv(volatile ulong_t *, ulong_t); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern uint64_t atomic_and_64_nv(volatile uint64_t *, uint64_t); +#endif + +/* + * If *arg1 == arg2, set *arg1 = arg3; return old value + */ +extern uint8_t atomic_cas_8(volatile uint8_t *, uint8_t, uint8_t); +extern uchar_t atomic_cas_uchar(volatile uchar_t *, uchar_t, uchar_t); +extern uint16_t atomic_cas_16(volatile uint16_t *, uint16_t, uint16_t); +extern ushort_t atomic_cas_ushort(volatile ushort_t *, ushort_t, ushort_t); +extern uint32_t atomic_cas_32(volatile uint32_t *, uint32_t, uint32_t); +extern uint_t atomic_cas_uint(volatile uint_t *, uint_t, uint_t); +extern void *atomic_cas_ptr(volatile void *, void *, void *); +extern ulong_t atomic_cas_ulong(volatile ulong_t *, ulong_t, ulong_t); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern uint64_t atomic_cas_64(volatile uint64_t *, uint64_t, uint64_t); +#endif + +/* + * Swap target and return old value + */ +extern uint8_t atomic_swap_8(volatile uint8_t *, uint8_t); +extern uchar_t atomic_swap_uchar(volatile uchar_t *, uchar_t); +extern uint16_t atomic_swap_16(volatile uint16_t *, uint16_t); +extern ushort_t atomic_swap_ushort(volatile ushort_t *, ushort_t); +extern uint32_t atomic_swap_32(volatile uint32_t *, uint32_t); +extern uint_t atomic_swap_uint(volatile uint_t *, uint_t); +extern void *atomic_swap_ptr(volatile void *, void *); +extern ulong_t atomic_swap_ulong(volatile ulong_t *, ulong_t); +#if defined(_KERNEL) || defined(_INT64_TYPE) +extern uint64_t atomic_swap_64(volatile uint64_t *, uint64_t); +#endif + +/* + * Perform an exclusive atomic bit set/clear on a target. + * Returns 0 if bit was sucessfully set/cleared, or -1 + * if the bit was already set/cleared. + */ +extern int atomic_set_long_excl(volatile ulong_t *, uint_t); +extern int atomic_clear_long_excl(volatile ulong_t *, uint_t); + +/* + * Generic memory barrier used during lock entry, placed after the + * memory operation that acquires the lock to guarantee that the lock + * protects its data. No stores from after the memory barrier will + * reach visibility, and no loads from after the barrier will be + * resolved, before the lock acquisition reaches global visibility. + */ +extern void membar_enter(void); + +/* + * Generic memory barrier used during lock exit, placed before the + * memory operation that releases the lock to guarantee that the lock + * protects its data. All loads and stores issued before the barrier + * will be resolved before the subsequent lock update reaches visibility. + */ +extern void membar_exit(void); + +/* + * Arrange that all stores issued before this point in the code reach + * global visibility before any stores that follow; useful in producer + * modules that update a data item, then set a flag that it is available. + * The memory barrier guarantees that the available flag is not visible + * earlier than the updated data, i.e. it imposes store ordering. + */ +extern void membar_producer(void); + +/* + * Arrange that all loads issued before this point in the code are + * completed before any subsequent loads; useful in consumer modules + * that check to see if data is available and read the data. + * The memory barrier guarantees that the data is not sampled until + * after the available flag has been seen, i.e. it imposes load ordering. + */ +extern void membar_consumer(void); +#endif + +#if !defined(_KERNEL) && !defined(__STDC__) +extern void atomic_inc_8(); +extern void atomic_inc_uchar(); +extern void atomic_inc_16(); +extern void atomic_inc_ushort(); +extern void atomic_inc_32(); +extern void atomic_inc_uint(); +extern void atomic_inc_ulong(); +#if defined(_INT64_TYPE) +extern void atomic_inc_64(); +#endif /* defined(_INT64_TYPE) */ +extern void atomic_dec_8(); +extern void atomic_dec_uchar(); +extern void atomic_dec_16(); +extern void atomic_dec_ushort(); +extern void atomic_dec_32(); +extern void atomic_dec_uint(); +extern void atomic_dec_ulong(); +#if defined(_INT64_TYPE) +extern void atomic_dec_64(); +#endif /* defined(_INT64_TYPE) */ +extern void atomic_add_8(); +extern void atomic_add_char(); +extern void atomic_add_16(); +extern void atomic_add_short(); +extern void atomic_add_32(); +extern void atomic_add_int(); +extern void atomic_add_ptr(); +extern void atomic_add_long(); +#if defined(_INT64_TYPE) +extern void atomic_add_64(); +#endif /* defined(_INT64_TYPE) */ +extern void atomic_or_8(); +extern void atomic_or_uchar(); +extern void atomic_or_16(); +extern void atomic_or_ushort(); +extern void atomic_or_32(); +extern void atomic_or_uint(); +extern void atomic_or_ulong(); +#if defined(_INT64_TYPE) +extern void atomic_or_64(); +#endif /* defined(_INT64_TYPE) */ +extern void atomic_and_8(); +extern void atomic_and_uchar(); +extern void atomic_and_16(); +extern void atomic_and_ushort(); +extern void atomic_and_32(); +extern void atomic_and_uint(); +extern void atomic_and_ulong(); +#if defined(_INT64_TYPE) +extern void atomic_and_64(); +#endif /* defined(_INT64_TYPE) */ +extern uint8_t atomic_inc_8_nv(); +extern uchar_t atomic_inc_uchar_nv(); +extern uint16_t atomic_inc_16_nv(); +extern ushort_t atomic_inc_ushort_nv(); +extern uint32_t atomic_inc_32_nv(); +extern uint_t atomic_inc_uint_nv(); +extern ulong_t atomic_inc_ulong_nv(); +#if defined(_INT64_TYPE) +extern uint64_t atomic_inc_64_nv(); +#endif /* defined(_INT64_TYPE) */ +extern uint8_t atomic_dec_8_nv(); +extern uchar_t atomic_dec_uchar_nv(); +extern uint16_t atomic_dec_16_nv(); +extern ushort_t atomic_dec_ushort_nv(); +extern uint32_t atomic_dec_32_nv(); +extern uint_t atomic_dec_uint_nv(); +extern ulong_t atomic_dec_ulong_nv(); +#if defined(_INT64_TYPE) +extern uint64_t atomic_dec_64_nv(); +#endif /* defined(_INT64_TYPE) */ +extern uint8_t atomic_add_8_nv(); +extern uchar_t atomic_add_char_nv(); +extern uint16_t atomic_add_16_nv(); +extern ushort_t atomic_add_short_nv(); +extern uint32_t atomic_add_32_nv(); +extern uint_t atomic_add_int_nv(); +extern void *atomic_add_ptr_nv(); +extern ulong_t atomic_add_long_nv(); +#if defined(_INT64_TYPE) +extern uint64_t atomic_add_64_nv(); +#endif /* defined(_INT64_TYPE) */ +extern uint8_t atomic_or_8_nv(); +extern uchar_t atomic_or_uchar_nv(); +extern uint16_t atomic_or_16_nv(); +extern ushort_t atomic_or_ushort_nv(); +extern uint32_t atomic_or_32_nv(); +extern uint_t atomic_or_uint_nv(); +extern ulong_t atomic_or_ulong_nv(); +#if defined(_INT64_TYPE) +extern uint64_t atomic_or_64_nv(); +#endif /* defined(_INT64_TYPE) */ +extern uint8_t atomic_and_8_nv(); +extern uchar_t atomic_and_uchar_nv(); +extern uint16_t atomic_and_16_nv(); +extern ushort_t atomic_and_ushort_nv(); +extern uint32_t atomic_and_32_nv(); +extern uint_t atomic_and_uint_nv(); +extern ulong_t atomic_and_ulong_nv(); +#if defined(_INT64_TYPE) +extern uint64_t atomic_and_64_nv(); +#endif /* defined(_INT64_TYPE) */ +extern uint8_t atomic_cas_8(); +extern uchar_t atomic_cas_uchar(); +extern uint16_t atomic_cas_16(); +extern ushort_t atomic_cas_ushort(); +extern uint32_t atomic_cas_32(); +extern uint_t atomic_cas_uint(); +extern void *atomic_cas_ptr(); +extern ulong_t atomic_cas_ulong(); +#if defined(_INT64_TYPE) +extern uint64_t atomic_cas_64(); +#endif /* defined(_INT64_TYPE) */ +extern uint8_t atomic_swap_8(); +extern uchar_t atomic_swap_uchar(); +extern uint16_t atomic_swap_16(); +extern ushort_t atomic_swap_ushort(); +extern uint32_t atomic_swap_32(); +extern uint_t atomic_swap_uint(); +extern void *atomic_swap_ptr(); +extern ulong_t atomic_swap_ulong(); +#if defined(_INT64_TYPE) +extern uint64_t atomic_swap_64(); +#endif /* defined(_INT64_TYPE) */ + + +extern int atomic_set_long_excl(); +extern int atomic_clear_long_excl(); + +extern void membar_enter(); +extern void membar_exit(); +extern void membar_producer(); +extern void membar_consumer(); + +#endif + +#if defined(_KERNEL) + +#if defined(_LP64) || defined(_ILP32) +#define atomic_add_ip atomic_add_long +#define atomic_add_ip_nv atomic_add_long_nv +#define casip atomic_cas_ulong +#endif + +#if defined(__sparc) +extern uint8_t ldstub(uint8_t *); +#endif + +/* + * Legacy kernel interfaces; they will go away (eventually). + */ +extern uint8_t cas8(uint8_t *, uint8_t, uint8_t); +extern uint32_t cas32(uint32_t *, uint32_t, uint32_t); +extern uint64_t cas64(uint64_t *, uint64_t, uint64_t); +extern ulong_t caslong(ulong_t *, ulong_t, ulong_t); +extern void *casptr(void *, void *, void *); +extern void atomic_and_long(ulong_t *, ulong_t); +extern void atomic_or_long(ulong_t *, ulong_t); +#if defined(__sparc) +extern uint32_t swapl(uint32_t *, uint32_t); +#endif + +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_ATOMIC_H */ diff --git a/zfs/lib/libspl/include/sys/bitmap.h b/zfs/lib/libspl/include/sys/bitmap.h new file mode 100644 index 0000000000..9f494fe72b --- /dev/null +++ b/zfs/lib/libspl/include/sys/bitmap.h @@ -0,0 +1,30 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SOL_SYS_BITMAP_H +#define _SOL_SYS_BITMAP_H + +#endif diff --git a/zfs/lib/libspl/include/sys/byteorder.h b/zfs/lib/libspl/include/sys/byteorder.h new file mode 100644 index 0000000000..528d2d208d --- /dev/null +++ b/zfs/lib/libspl/include/sys/byteorder.h @@ -0,0 +1,199 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +/* + * University Copyright- Copyright (c) 1982, 1986, 1988 + * The Regents of the University of California + * All Rights Reserved + * + * University Acknowledgment- Portions of this document are derived from + * software developed by the University of California, Berkeley, and its + * contributors. + */ + +#ifndef _SYS_BYTEORDER_H +#define _SYS_BYTEORDER_H + + + +#include +#include + +#if defined(__GNUC__) && defined(_ASM_INLINES) && \ + (defined(__i386) || defined(__amd64)) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * macros for conversion between host and (internet) network byte order + */ + +#if defined(_BIG_ENDIAN) && !defined(ntohl) && !defined(__lint) +/* big-endian */ +#define ntohl(x) (x) +#define ntohs(x) (x) +#define htonl(x) (x) +#define htons(x) (x) + +#elif !defined(ntohl) /* little-endian */ + +#ifndef _IN_PORT_T +#define _IN_PORT_T +typedef uint16_t in_port_t; +#endif + +#ifndef _IN_ADDR_T +#define _IN_ADDR_T +typedef uint32_t in_addr_t; +#endif + +#if !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5) +extern uint32_t htonl(uint32_t); +extern uint16_t htons(uint16_t); +extern uint32_t ntohl(uint32_t); +extern uint16_t ntohs(uint16_t); +#else +extern in_addr_t htonl(in_addr_t); +extern in_port_t htons(in_port_t); +extern in_addr_t ntohl(in_addr_t); +extern in_port_t ntohs(in_port_t); +#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5) */ +#endif + +#if !defined(_XPG4_2) || defined(__EXTENSIONS__) + +/* + * Macros to reverse byte order + */ +#define BSWAP_8(x) ((x) & 0xff) +#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8)) +#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16)) +#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32)) + +#define BMASK_8(x) ((x) & 0xff) +#define BMASK_16(x) ((x) & 0xffff) +#define BMASK_32(x) ((x) & 0xffffffff) +#define BMASK_64(x) (x) + +/* + * Macros to convert from a specific byte order to/from native byte order + */ +#ifdef _BIG_ENDIAN +#define BE_8(x) BMASK_8(x) +#define BE_16(x) BMASK_16(x) +#define BE_32(x) BMASK_32(x) +#define BE_64(x) BMASK_64(x) +#define LE_8(x) BSWAP_8(x) +#define LE_16(x) BSWAP_16(x) +#define LE_32(x) BSWAP_32(x) +#define LE_64(x) BSWAP_64(x) +#else +#define LE_8(x) BMASK_8(x) +#define LE_16(x) BMASK_16(x) +#define LE_32(x) BMASK_32(x) +#define LE_64(x) BMASK_64(x) +#define BE_8(x) BSWAP_8(x) +#define BE_16(x) BSWAP_16(x) +#define BE_32(x) BSWAP_32(x) +#define BE_64(x) BSWAP_64(x) +#endif + +/* + * Macros to read unaligned values from a specific byte order to + * native byte order + */ + +#define BE_IN8(xa) \ + *((uint8_t *)(xa)) + +#define BE_IN16(xa) \ + (((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1)) + +#define BE_IN32(xa) \ + (((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2)) + +#define BE_IN64(xa) \ + (((uint64_t)BE_IN32(xa) << 32) | BE_IN32((uint8_t *)(xa)+4)) + +#define LE_IN8(xa) \ + *((uint8_t *)(xa)) + +#define LE_IN16(xa) \ + (((uint16_t)LE_IN8((uint8_t *)(xa) + 1) << 8) | LE_IN8(xa)) + +#define LE_IN32(xa) \ + (((uint32_t)LE_IN16((uint8_t *)(xa) + 2) << 16) | LE_IN16(xa)) + +#define LE_IN64(xa) \ + (((uint64_t)LE_IN32((uint8_t *)(xa) + 4) << 32) | LE_IN32(xa)) + +/* + * Macros to write unaligned values from native byte order to a specific byte + * order. + */ + +#define BE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv); + +#define BE_OUT16(xa, yv) \ + BE_OUT8((uint8_t *)(xa) + 1, yv); \ + BE_OUT8((uint8_t *)(xa), (yv) >> 8); + +#define BE_OUT32(xa, yv) \ + BE_OUT16((uint8_t *)(xa) + 2, yv); \ + BE_OUT16((uint8_t *)(xa), (yv) >> 16); + +#define BE_OUT64(xa, yv) \ + BE_OUT32((uint8_t *)(xa) + 4, yv); \ + BE_OUT32((uint8_t *)(xa), (yv) >> 32); + +#define LE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv); + +#define LE_OUT16(xa, yv) \ + LE_OUT8((uint8_t *)(xa), yv); \ + LE_OUT8((uint8_t *)(xa) + 1, (yv) >> 8); + +#define LE_OUT32(xa, yv) \ + LE_OUT16((uint8_t *)(xa), yv); \ + LE_OUT16((uint8_t *)(xa) + 2, (yv) >> 16); + +#define LE_OUT64(xa, yv) \ + LE_OUT32((uint8_t *)(xa), yv); \ + LE_OUT32((uint8_t *)(xa) + 4, (yv) >> 32); + +#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_BYTEORDER_H */ diff --git a/zfs/lib/libspl/include/sys/cmn_err.h b/zfs/lib/libspl/include/sys/cmn_err.h index e69de29bb2..525e3cadb2 100644 --- a/zfs/lib/libspl/include/sys/cmn_err.h +++ b/zfs/lib/libspl/include/sys/cmn_err.h @@ -0,0 +1,30 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SOL_SYS_CMN_ERR_H +#define _SOL_SYS_CMN_ERR_H + +#endif diff --git a/zfs/lib/libspl/include/sys/cred.h b/zfs/lib/libspl/include/sys/cred.h new file mode 100644 index 0000000000..b4fb6381ec --- /dev/null +++ b/zfs/lib/libspl/include/sys/cred.h @@ -0,0 +1,32 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SOL_SYS_CRED_H +#define _SOL_SYS_CRED_H + +typedef struct cred cred_t; + +#endif diff --git a/zfs/lib/libspl/include/sys/kstat.h b/zfs/lib/libspl/include/sys/kstat.h new file mode 100644 index 0000000000..fcd3ed98b3 --- /dev/null +++ b/zfs/lib/libspl/include/sys/kstat.h @@ -0,0 +1,820 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_KSTAT_H +#define _SYS_KSTAT_H + + + +/* + * Definition of general kernel statistics structures and /dev/kstat ioctls + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int kid_t; /* unique kstat id */ + +/* + * Kernel statistics driver (/dev/kstat) ioctls + */ + +#define KSTAT_IOC_BASE ('K' << 8) + +#define KSTAT_IOC_CHAIN_ID KSTAT_IOC_BASE | 0x01 +#define KSTAT_IOC_READ KSTAT_IOC_BASE | 0x02 +#define KSTAT_IOC_WRITE KSTAT_IOC_BASE | 0x03 + +/* + * /dev/kstat ioctl usage (kd denotes /dev/kstat descriptor): + * + * kcid = ioctl(kd, KSTAT_IOC_CHAIN_ID, NULL); + * kcid = ioctl(kd, KSTAT_IOC_READ, kstat_t *); + * kcid = ioctl(kd, KSTAT_IOC_WRITE, kstat_t *); + */ + +#define KSTAT_STRLEN 31 /* 30 chars + NULL; must be 16 * n - 1 */ + +/* + * The generic kstat header + */ + +typedef struct kstat { + /* + * Fields relevant to both kernel and user + */ + hrtime_t ks_crtime; /* creation time (from gethrtime()) */ + struct kstat *ks_next; /* kstat chain linkage */ + kid_t ks_kid; /* unique kstat ID */ + char ks_module[KSTAT_STRLEN]; /* provider module name */ + uchar_t ks_resv; /* reserved, currently just padding */ + int ks_instance; /* provider module's instance */ + char ks_name[KSTAT_STRLEN]; /* kstat name */ + uchar_t ks_type; /* kstat data type */ + char ks_class[KSTAT_STRLEN]; /* kstat class */ + uchar_t ks_flags; /* kstat flags */ + void *ks_data; /* kstat type-specific data */ + uint_t ks_ndata; /* # of type-specific data records */ + size_t ks_data_size; /* total size of kstat data section */ + hrtime_t ks_snaptime; /* time of last data shapshot */ + /* + * Fields relevant to kernel only + */ + int (*ks_update)(struct kstat *, int); /* dynamic update */ + void *ks_private; /* arbitrary provider-private data */ + int (*ks_snapshot)(struct kstat *, void *, int); + void *ks_lock; /* protects this kstat's data */ +} kstat_t; + +#ifdef _SYSCALL32 + +typedef int32_t kid32_t; + +typedef struct kstat32 { + /* + * Fields relevant to both kernel and user + */ + hrtime_t ks_crtime; + caddr32_t ks_next; /* struct kstat pointer */ + kid32_t ks_kid; + char ks_module[KSTAT_STRLEN]; + uint8_t ks_resv; + int32_t ks_instance; + char ks_name[KSTAT_STRLEN]; + uint8_t ks_type; + char ks_class[KSTAT_STRLEN]; + uint8_t ks_flags; + caddr32_t ks_data; /* type-specific data */ + uint32_t ks_ndata; + size32_t ks_data_size; + hrtime_t ks_snaptime; + /* + * Fields relevant to kernel only (only needed here for padding) + */ + int32_t _ks_update; + caddr32_t _ks_private; + int32_t _ks_snapshot; + caddr32_t _ks_lock; +} kstat32_t; + +#endif /* _SYSCALL32 */ + +/* + * kstat structure and locking strategy + * + * Each kstat consists of a header section (a kstat_t) and a data section. + * The system maintains a set of kstats, protected by kstat_chain_lock. + * kstat_chain_lock protects all additions to/deletions from this set, + * as well as all changes to kstat headers. kstat data sections are + * *optionally* protected by the per-kstat ks_lock. If ks_lock is non-NULL, + * kstat clients (e.g. /dev/kstat) will acquire this lock for all of their + * operations on that kstat. It is up to the kstat provider to decide whether + * guaranteeing consistent data to kstat clients is sufficiently important + * to justify the locking cost. Note, however, that most statistic updates + * already occur under one of the provider's mutexes, so if the provider sets + * ks_lock to point to that mutex, then kstat data locking is free. + * + * NOTE: variable-size kstats MUST employ kstat data locking, to prevent + * data-size races with kstat clients. + * + * NOTE: ks_lock is really of type (kmutex_t *); it is declared as (void *) + * in the kstat header so that users don't have to be exposed to all of the + * kernel's lock-related data structures. + */ + +#if defined(_KERNEL) + +#define KSTAT_ENTER(k) \ + { kmutex_t *lp = (k)->ks_lock; if (lp) mutex_enter(lp); } + +#define KSTAT_EXIT(k) \ + { kmutex_t *lp = (k)->ks_lock; if (lp) mutex_exit(lp); } + +#define KSTAT_UPDATE(k, rw) (*(k)->ks_update)((k), (rw)) + +#define KSTAT_SNAPSHOT(k, buf, rw) (*(k)->ks_snapshot)((k), (buf), (rw)) + +#endif /* defined(_KERNEL) */ + +/* + * kstat time + * + * All times associated with kstats (e.g. creation time, snapshot time, + * kstat_timer_t and kstat_io_t timestamps, etc.) are 64-bit nanosecond values, + * as returned by gethrtime(). The accuracy of these timestamps is machine + * dependent, but the precision (units) is the same across all platforms. + */ + +/* + * kstat identity (KID) + * + * Each kstat is assigned a unique KID (kstat ID) when it is added to the + * global kstat chain. The KID is used as a cookie by /dev/kstat to + * request information about the corresponding kstat. There is also + * an identity associated with the entire kstat chain, kstat_chain_id, + * which is bumped each time a kstat is added or deleted. /dev/kstat uses + * the chain ID to detect changes in the kstat chain (e.g., a new disk + * coming online) between ioctl()s. + */ + +/* + * kstat module, kstat instance + * + * ks_module and ks_instance contain the name and instance of the module + * that created the kstat. In cases where there can only be one instance, + * ks_instance is 0. The kernel proper (/kernel/unix) uses "unix" as its + * module name. + */ + +/* + * kstat name + * + * ks_name gives a meaningful name to a kstat. The full kstat namespace + * is module.instance.name, so the name only need be unique within a + * module. kstat_create() will fail if you try to create a kstat with + * an already-used (ks_module, ks_instance, ks_name) triplet. Spaces are + * allowed in kstat names, but strongly discouraged, since they hinder + * awk-style processing at user level. + */ + +/* + * kstat type + * + * The kstat mechanism provides several flavors of kstat data, defined + * below. The "raw" kstat type is just treated as an array of bytes; you + * can use this to export any kind of data you want. + * + * Some kstat types allow multiple data structures per kstat, e.g. + * KSTAT_TYPE_NAMED; others do not. This is part of the spec for each + * kstat data type. + * + * User-level tools should *not* rely on the #define KSTAT_NUM_TYPES. To + * get this information, read out the standard system kstat "kstat_types". + */ + +#define KSTAT_TYPE_RAW 0 /* can be anything */ + /* ks_ndata >= 1 */ +#define KSTAT_TYPE_NAMED 1 /* name/value pair */ + /* ks_ndata >= 1 */ +#define KSTAT_TYPE_INTR 2 /* interrupt statistics */ + /* ks_ndata == 1 */ +#define KSTAT_TYPE_IO 3 /* I/O statistics */ + /* ks_ndata == 1 */ +#define KSTAT_TYPE_TIMER 4 /* event timer */ + /* ks_ndata >= 1 */ + +#define KSTAT_NUM_TYPES 5 + +/* + * kstat class + * + * Each kstat can be characterized as belonging to some broad class + * of statistics, e.g. disk, tape, net, vm, streams, etc. This field + * can be used as a filter to extract related kstats. The following + * values are currently in use: disk, tape, net, controller, vm, kvm, + * hat, streams, kstat, and misc. (The kstat class encompasses things + * like kstat_types.) + */ + +/* + * kstat flags + * + * Any of the following flags may be passed to kstat_create(). They are + * all zero by default. + * + * KSTAT_FLAG_VIRTUAL: + * + * Tells kstat_create() not to allocate memory for the + * kstat data section; instead, you will set the ks_data + * field to point to the data you wish to export. This + * provides a convenient way to export existing data + * structures. + * + * KSTAT_FLAG_VAR_SIZE: + * + * The size of the kstat you are creating will vary over time. + * For example, you may want to use the kstat mechanism to + * export a linked list. NOTE: The kstat framework does not + * manage the data section, so all variable-size kstats must be + * virtual kstats. Moreover, variable-size kstats MUST employ + * kstat data locking to prevent data-size races with kstat + * clients. See the section on "kstat snapshot" for details. + * + * KSTAT_FLAG_WRITABLE: + * + * Makes the kstat's data section writable by root. + * The ks_snapshot routine (see below) does not need to check for + * this; permission checking is handled in the kstat driver. + * + * KSTAT_FLAG_PERSISTENT: + * + * Indicates that this kstat is to be persistent over time. + * For persistent kstats, kstat_delete() simply marks the + * kstat as dormant; a subsequent kstat_create() reactivates + * the kstat. This feature is provided so that statistics + * are not lost across driver close/open (e.g., raw disk I/O + * on a disk with no mounted partitions.) + * NOTE: Persistent kstats cannot be virtual, since ks_data + * points to garbage as soon as the driver goes away. + * + * The following flags are maintained by the kstat framework: + * + * KSTAT_FLAG_DORMANT: + * + * For persistent kstats, indicates that the kstat is in the + * dormant state (e.g., the corresponding device is closed). + * + * KSTAT_FLAG_INVALID: + * + * This flag is set when a kstat is in a transitional state, + * e.g. between kstat_create() and kstat_install(). + * kstat clients must not attempt to access the kstat's data + * if this flag is set. + */ + +#define KSTAT_FLAG_VIRTUAL 0x01 +#define KSTAT_FLAG_VAR_SIZE 0x02 +#define KSTAT_FLAG_WRITABLE 0x04 +#define KSTAT_FLAG_PERSISTENT 0x08 +#define KSTAT_FLAG_DORMANT 0x10 +#define KSTAT_FLAG_INVALID 0x20 + +/* + * Dynamic update support + * + * The kstat mechanism allows for an optional ks_update function to update + * kstat data. This is useful for drivers where the underlying device + * keeps cheap hardware stats, but extraction is expensive. Instead of + * constantly keeping the kstat data section up to date, you can supply a + * ks_update function which updates the kstat's data section on demand. + * To take advantage of this feature, simply set the ks_update field before + * calling kstat_install(). + * + * The ks_update function, if supplied, must have the following structure: + * + * int + * foo_kstat_update(kstat_t *ksp, int rw) + * { + * if (rw == KSTAT_WRITE) { + * ... update the native stats from ksp->ks_data; + * return EACCES if you don't support this + * } else { + * ... update ksp->ks_data from the native stats + * } + * } + * + * The ks_update return codes are: 0 for success, EACCES if you don't allow + * KSTAT_WRITE, and EIO for any other type of error. + * + * In general, the ks_update function may need to refer to provider-private + * data; for example, it may need a pointer to the provider's raw statistics. + * The ks_private field is available for this purpose. Its use is entirely + * at the provider's discretion. + * + * All variable-size kstats MUST supply a ks_update routine, which computes + * and sets ks_data_size (and ks_ndata if that is meaningful), since these + * are needed to perform kstat snapshots (see below). + * + * No kstat locking should be done inside the ks_update routine. The caller + * will already be holding the kstat's ks_lock (to ensure consistent data). + */ + +#define KSTAT_READ 0 +#define KSTAT_WRITE 1 + +/* + * Kstat snapshot + * + * In order to get a consistent view of a kstat's data, clients must obey + * the kstat's locking strategy. However, these clients may need to perform + * operations on the data which could cause a fault (e.g. copyout()), or + * operations which are simply expensive. Doing so could cause deadlock + * (e.g. if you're holding a disk's kstat lock which is ultimately required + * to resolve a copyout() fault), performance degradation (since the providers' + * activity is serialized at the kstat lock), device timing problems, etc. + * + * To avoid these problems, kstat data is provided via snapshots. Taking + * a snapshot is a simple process: allocate a wired-down kernel buffer, + * acquire the kstat's data lock, copy the data into the buffer ("take the + * snapshot"), and release the lock. This ensures that the kstat's data lock + * will be held as briefly as possible, and that no faults will occur while + * the lock is held. + * + * Normally, the snapshot is taken by default_kstat_snapshot(), which + * timestamps the data (sets ks_snaptime), copies it, and does a little + * massaging to deal with incomplete transactions on i/o kstats. However, + * this routine only works for kstats with contiguous data (the typical case). + * If you create a kstat whose data is, say, a linked list, you must provide + * your own ks_snapshot routine. The routine you supply must have the + * following prototype (replace "foo" with something appropriate): + * + * int foo_kstat_snapshot(kstat_t *ksp, void *buf, int rw); + * + * The minimal snapshot routine -- one which copies contiguous data that + * doesn't need any massaging -- would be this: + * + * ksp->ks_snaptime = gethrtime(); + * if (rw == KSTAT_WRITE) + * bcopy(buf, ksp->ks_data, ksp->ks_data_size); + * else + * bcopy(ksp->ks_data, buf, ksp->ks_data_size); + * return (0); + * + * A more illuminating example is taking a snapshot of a linked list: + * + * ksp->ks_snaptime = gethrtime(); + * if (rw == KSTAT_WRITE) + * return (EACCES); ... See below ... + * for (foo = first_foo; foo; foo = foo->next) { + * bcopy((char *) foo, (char *) buf, sizeof (struct foo)); + * buf = ((struct foo *) buf) + 1; + * } + * return (0); + * + * In the example above, we have decided that we don't want to allow + * KSTAT_WRITE access, so we return EACCES if this is attempted. + * + * The key points are: + * + * (1) ks_snaptime must be set (via gethrtime()) to timestamp the data. + * (2) Data gets copied from the kstat to the buffer on KSTAT_READ, + * and from the buffer to the kstat on KSTAT_WRITE. + * (3) ks_snapshot return values are: 0 for success, EACCES if you + * don't allow KSTAT_WRITE, and EIO for any other type of error. + * + * Named kstats (see section on "Named statistics" below) containing long + * strings (KSTAT_DATA_STRING) need special handling. The kstat driver + * assumes that all strings are copied into the buffer after the array of + * named kstats, and the pointers (KSTAT_NAMED_STR_PTR()) are updated to point + * into the copy within the buffer. The default snapshot routine does this, + * but overriding routines should contain at least the following: + * + * if (rw == KSTAT_READ) { + * kstat_named_t *knp = buf; + * char *end = knp + ksp->ks_ndata; + * uint_t i; + * + * ... Do the regular copy ... + * bcopy(ksp->ks_data, buf, sizeof (kstat_named_t) * ksp->ks_ndata); + * + * for (i = 0; i < ksp->ks_ndata; i++, knp++) { + * if (knp[i].data_type == KSTAT_DATA_STRING && + * KSTAT_NAMED_STR_PTR(knp) != NULL) { + * bcopy(KSTAT_NAMED_STR_PTR(knp), end, + * KSTAT_NAMED_STR_BUFLEN(knp)); + * KSTAT_NAMED_STR_PTR(knp) = end; + * end += KSTAT_NAMED_STR_BUFLEN(knp); + * } + * } + */ + +/* + * Named statistics. + * + * List of arbitrary name=value statistics. + */ + +typedef struct kstat_named { + char name[KSTAT_STRLEN]; /* name of counter */ + uchar_t data_type; /* data type */ + union { + char c[16]; /* enough for 128-bit ints */ + int32_t i32; + uint32_t ui32; + struct { + union { + char *ptr; /* NULL-term string */ +#if defined(_KERNEL) && defined(_MULTI_DATAMODEL) + caddr32_t ptr32; +#endif + char __pad[8]; /* 64-bit padding */ + } addr; + uint32_t len; /* # bytes for strlen + '\0' */ + } str; +/* + * The int64_t and uint64_t types are not valid for a maximally conformant + * 32-bit compilation environment (cc -Xc) using compilers prior to the + * introduction of C99 conforming compiler (reference ISO/IEC 9899:1990). + * In these cases, the visibility of i64 and ui64 is only permitted for + * 64-bit compilation environments or 32-bit non-maximally conformant + * C89 or C90 ANSI C compilation environments (cc -Xt and cc -Xa). In the + * C99 ANSI C compilation environment, the long long type is supported. + * The _INT64_TYPE is defined by the implementation (see sys/int_types.h). + */ +#if defined(_INT64_TYPE) + int64_t i64; + uint64_t ui64; +#endif + long l; + ulong_t ul; + + /* These structure members are obsolete */ + + longlong_t ll; + u_longlong_t ull; + float f; + double d; + } value; /* value of counter */ +} kstat_named_t; + +#define KSTAT_DATA_CHAR 0 +#define KSTAT_DATA_INT32 1 +#define KSTAT_DATA_UINT32 2 +#define KSTAT_DATA_INT64 3 +#define KSTAT_DATA_UINT64 4 + +#if !defined(_LP64) +#define KSTAT_DATA_LONG KSTAT_DATA_INT32 +#define KSTAT_DATA_ULONG KSTAT_DATA_UINT32 +#else +#if !defined(_KERNEL) +#define KSTAT_DATA_LONG KSTAT_DATA_INT64 +#define KSTAT_DATA_ULONG KSTAT_DATA_UINT64 +#else +#define KSTAT_DATA_LONG 7 /* only visible to the kernel */ +#define KSTAT_DATA_ULONG 8 /* only visible to the kernel */ +#endif /* !_KERNEL */ +#endif /* !_LP64 */ + +/* + * Statistics exporting named kstats with long strings (KSTAT_DATA_STRING) + * may not make the assumption that ks_data_size is equal to (ks_ndata * sizeof + * (kstat_named_t)). ks_data_size in these cases is equal to the sum of the + * amount of space required to store the strings (ie, the sum of + * KSTAT_NAMED_STR_BUFLEN() for all KSTAT_DATA_STRING statistics) plus the + * space required to store the kstat_named_t's. + * + * The default update routine will update ks_data_size automatically for + * variable-length kstats containing long strings (using the default update + * routine only makes sense if the string is the only thing that is changing + * in size, and ks_ndata is constant). Fixed-length kstats containing long + * strings must explicitly change ks_data_size (after creation but before + * initialization) to reflect the correct amount of space required for the + * long strings and the kstat_named_t's. + */ +#define KSTAT_DATA_STRING 9 + +/* These types are obsolete */ + +#define KSTAT_DATA_LONGLONG KSTAT_DATA_INT64 +#define KSTAT_DATA_ULONGLONG KSTAT_DATA_UINT64 +#define KSTAT_DATA_FLOAT 5 +#define KSTAT_DATA_DOUBLE 6 + +#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data) + +/* + * Retrieve the pointer of the string contained in the given named kstat. + */ +#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr) + +/* + * Retrieve the length of the buffer required to store the string in the given + * named kstat. + */ +#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.str.len) + +/* + * Interrupt statistics. + * + * An interrupt is a hard interrupt (sourced from the hardware device + * itself), a soft interrupt (induced by the system via the use of + * some system interrupt source), a watchdog interrupt (induced by + * a periodic timer call), spurious (an interrupt entry point was + * entered but there was no interrupt condition to service), + * or multiple service (an interrupt condition was detected and + * serviced just prior to returning from any of the other types). + * + * Measurement of the spurious class of interrupts is useful for + * autovectored devices in order to pinpoint any interrupt latency + * problems in a particular system configuration. + * + * Devices that have more than one interrupt of the same + * type should use multiple structures. + */ + +#define KSTAT_INTR_HARD 0 +#define KSTAT_INTR_SOFT 1 +#define KSTAT_INTR_WATCHDOG 2 +#define KSTAT_INTR_SPURIOUS 3 +#define KSTAT_INTR_MULTSVC 4 + +#define KSTAT_NUM_INTRS 5 + +typedef struct kstat_intr { + uint_t intrs[KSTAT_NUM_INTRS]; /* interrupt counters */ +} kstat_intr_t; + +#define KSTAT_INTR_PTR(kptr) ((kstat_intr_t *)(kptr)->ks_data) + +/* + * I/O statistics. + */ + +typedef struct kstat_io { + + /* + * Basic counters. + * + * The counters should be updated at the end of service + * (e.g., just prior to calling biodone()). + */ + + u_longlong_t nread; /* number of bytes read */ + u_longlong_t nwritten; /* number of bytes written */ + uint_t reads; /* number of read operations */ + uint_t writes; /* number of write operations */ + + /* + * Accumulated time and queue length statistics. + * + * Accumulated time statistics are kept as a running sum + * of "active" time. Queue length statistics are kept as a + * running sum of the product of queue length and elapsed time + * at that length -- i.e., a Riemann sum for queue length + * integrated against time. (You can also think of the active time + * as a Riemann sum, for the boolean function (queue_length > 0) + * integrated against time, or you can think of it as the + * Lebesgue measure of the set on which queue_length > 0.) + * + * ^ + * | _________ + * 8 | i4 | + * | | | + * Queue 6 | | + * Length | _________ | | + * 4 | i2 |_______| | + * | | i3 | + * 2_______| | + * | i1 | + * |_______________________________| + * Time-> t1 t2 t3 t4 + * + * At each change of state (entry or exit from the queue), + * we add the elapsed time (since the previous state change) + * to the active time if the queue length was non-zero during + * that interval; and we add the product of the elapsed time + * times the queue length to the running length*time sum. + * + * This method is generalizable to measuring residency + * in any defined system: instead of queue lengths, think + * of "outstanding RPC calls to server X". + * + * A large number of I/O subsystems have at least two basic + * "lists" of transactions they manage: one for transactions + * that have been accepted for processing but for which processing + * has yet to begin, and one for transactions which are actively + * being processed (but not done). For this reason, two cumulative + * time statistics are defined here: wait (pre-service) time, + * and run (service) time. + * + * All times are 64-bit nanoseconds (hrtime_t), as returned by + * gethrtime(). + * + * The units of cumulative busy time are accumulated nanoseconds. + * The units of cumulative length*time products are elapsed time + * times queue length. + * + * Updates to the fields below are performed implicitly by calls to + * these five functions: + * + * kstat_waitq_enter() + * kstat_waitq_exit() + * kstat_runq_enter() + * kstat_runq_exit() + * + * kstat_waitq_to_runq() (see below) + * kstat_runq_back_to_waitq() (see below) + * + * Since kstat_waitq_exit() is typically followed immediately + * by kstat_runq_enter(), there is a single kstat_waitq_to_runq() + * function which performs both operations. This is a performance + * win since only one timestamp is required. + * + * In some instances, it may be necessary to move a request from + * the run queue back to the wait queue, e.g. for write throttling. + * For these situations, call kstat_runq_back_to_waitq(). + * + * These fields should never be updated by any other means. + */ + + hrtime_t wtime; /* cumulative wait (pre-service) time */ + hrtime_t wlentime; /* cumulative wait length*time product */ + hrtime_t wlastupdate; /* last time wait queue changed */ + hrtime_t rtime; /* cumulative run (service) time */ + hrtime_t rlentime; /* cumulative run length*time product */ + hrtime_t rlastupdate; /* last time run queue changed */ + + uint_t wcnt; /* count of elements in wait state */ + uint_t rcnt; /* count of elements in run state */ + +} kstat_io_t; + +#define KSTAT_IO_PTR(kptr) ((kstat_io_t *)(kptr)->ks_data) + +/* + * Event timer statistics - cumulative elapsed time and number of events. + * + * Updates to these fields are performed implicitly by calls to + * kstat_timer_start() and kstat_timer_stop(). + */ + +typedef struct kstat_timer { + char name[KSTAT_STRLEN]; /* event name */ + uchar_t resv; /* reserved */ + u_longlong_t num_events; /* number of events */ + hrtime_t elapsed_time; /* cumulative elapsed time */ + hrtime_t min_time; /* shortest event duration */ + hrtime_t max_time; /* longest event duration */ + hrtime_t start_time; /* previous event start time */ + hrtime_t stop_time; /* previous event stop time */ +} kstat_timer_t; + +#define KSTAT_TIMER_PTR(kptr) ((kstat_timer_t *)(kptr)->ks_data) + +#if defined(_KERNEL) + +#include + +extern kid_t kstat_chain_id; /* bumped at each state change */ +extern void kstat_init(void); /* initialize kstat framework */ + +/* + * Adding and deleting kstats. + * + * The typical sequence to add a kstat is: + * + * ksp = kstat_create(module, instance, name, class, type, ndata, flags); + * if (ksp) { + * ... provider initialization, if necessary + * kstat_install(ksp); + * } + * + * There are three logically distinct steps here: + * + * Step 1: System Initialization (kstat_create) + * + * kstat_create() performs system initialization. kstat_create() + * allocates memory for the entire kstat (header plus data), initializes + * all header fields, initializes the data section to all zeroes, assigns + * a unique KID, and puts the kstat onto the system's kstat chain. + * The returned kstat is marked invalid (KSTAT_FLAG_INVALID is set), + * because the provider (caller) has not yet had a chance to initialize + * the data section. + * + * By default, kstats are exported to all zones on the system. A kstat may be + * created via kstat_create_zone() to specify a zone to which the statistics + * should be exported. kstat_zone_add() may be used to specify additional + * zones to which the statistics are to be exported. + * + * Step 2: Provider Initialization + * + * The provider performs any necessary initialization of the data section, + * e.g. setting the name fields in a KSTAT_TYPE_NAMED. Virtual kstats set + * the ks_data field at this time. The provider may also set the ks_update, + * ks_snapshot, ks_private, and ks_lock fields if necessary. + * + * Step 3: Installation (kstat_install) + * + * Once the kstat is completely initialized, kstat_install() clears the + * INVALID flag, thus making the kstat accessible to the outside world. + * kstat_install() also clears the DORMANT flag for persistent kstats. + * + * Removing a kstat from the system + * + * kstat_delete(ksp) removes ksp from the kstat chain and frees all + * associated system resources. NOTE: When you call kstat_delete(), + * you must NOT be holding that kstat's ks_lock. Otherwise, you may + * deadlock with a kstat reader. + * + * Persistent kstats + * + * From the provider's point of view, persistence is transparent. The only + * difference between ephemeral (normal) kstats and persistent kstats + * is that you pass KSTAT_FLAG_PERSISTENT to kstat_create(). Magically, + * this has the effect of making your data visible even when you're + * not home. Persistence is important to tools like iostat, which want + * to get a meaningful picture of disk activity. Without persistence, + * raw disk i/o statistics could never accumulate: they would come and + * go with each open/close of the raw device. + * + * The magic of persistence works by slightly altering the behavior of + * kstat_create() and kstat_delete(). The first call to kstat_create() + * creates a new kstat, as usual. However, kstat_delete() does not + * actually delete the kstat: it performs one final update of the data + * (i.e., calls the ks_update routine), marks the kstat as dormant, and + * sets the ks_lock, ks_update, ks_private, and ks_snapshot fields back + * to their default values (since they might otherwise point to garbage, + * e.g. if the provider is going away). kstat clients can still access + * the dormant kstat just like a live kstat; they just continue to see + * the final data values as long as the kstat remains dormant. + * All subsequent kstat_create() calls simply find the already-existing, + * dormant kstat and return a pointer to it, without altering any fields. + * The provider then performs its usual initialization sequence, and + * calls kstat_install(). kstat_install() uses the old data values to + * initialize the native data (i.e., ks_update is called with KSTAT_WRITE), + * thus making it seem like you were never gone. + */ + +extern kstat_t *kstat_create(const char *, int, const char *, const char *, + uchar_t, uint_t, uchar_t); +extern kstat_t *kstat_create_zone(const char *, int, const char *, + const char *, uchar_t, uint_t, uchar_t, zoneid_t); +extern void kstat_install(kstat_t *); +extern void kstat_delete(kstat_t *); +extern void kstat_named_setstr(kstat_named_t *knp, const char *src); +extern void kstat_set_string(char *, const char *); +extern void kstat_delete_byname(const char *, int, const char *); +extern void kstat_delete_byname_zone(const char *, int, const char *, zoneid_t); +extern void kstat_named_init(kstat_named_t *, const char *, uchar_t); +extern void kstat_timer_init(kstat_timer_t *, const char *); +extern void kstat_waitq_enter(kstat_io_t *); +extern void kstat_waitq_exit(kstat_io_t *); +extern void kstat_runq_enter(kstat_io_t *); +extern void kstat_runq_exit(kstat_io_t *); +extern void kstat_waitq_to_runq(kstat_io_t *); +extern void kstat_runq_back_to_waitq(kstat_io_t *); +extern void kstat_timer_start(kstat_timer_t *); +extern void kstat_timer_stop(kstat_timer_t *); + +extern void kstat_zone_add(kstat_t *, zoneid_t); +extern void kstat_zone_remove(kstat_t *, zoneid_t); +extern int kstat_zone_find(kstat_t *, zoneid_t); + +extern kstat_t *kstat_hold_bykid(kid_t kid, zoneid_t); +extern kstat_t *kstat_hold_byname(const char *, int, const char *, zoneid_t); +extern void kstat_rele(kstat_t *); + +#endif /* defined(_KERNEL) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_KSTAT_H */ diff --git a/zfs/lib/libspl/include/sys/note.h b/zfs/lib/libspl/include/sys/note.h new file mode 100644 index 0000000000..88e0eabcd0 --- /dev/null +++ b/zfs/lib/libspl/include/sys/note.h @@ -0,0 +1,56 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1994 by Sun Microsystems, Inc. + */ + +/* + * sys/note.h: interface for annotating source with info for tools + * + * This is the underlying interface; NOTE (/usr/include/note.h) is the + * preferred interface, but all exported header files should include this + * file directly and use _NOTE so as not to take "NOTE" from the user's + * namespace. For consistency, *all* kernel source should use _NOTE. + * + * By default, annotations expand to nothing. This file implements + * that. Tools using annotations will interpose a different version + * of this file that will expand annotations as needed. + */ + +#ifndef _SYS_NOTE_H +#define _SYS_NOTE_H + + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _NOTE +#define _NOTE(s) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_NOTE_H */ diff --git a/zfs/lib/libspl/include/sys/processor.h b/zfs/lib/libspl/include/sys/processor.h new file mode 100644 index 0000000000..b00c1eb821 --- /dev/null +++ b/zfs/lib/libspl/include/sys/processor.h @@ -0,0 +1,32 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SOL_SYS_PROCESSOR_H +#define _SOL_SYS_PROCESSOR_H + +#define getcpuid() (-1) + +#endif diff --git a/zfs/lib/libspl/include/sys/sdt.h b/zfs/lib/libspl/include/sys/sdt.h new file mode 100644 index 0000000000..e194402a27 --- /dev/null +++ b/zfs/lib/libspl/include/sys/sdt.h @@ -0,0 +1,35 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SOL_SYS_SDT_H +#define _SOL_SYS_SDT_H + +#define DTRACE_PROBE1(a,b,c) ((void) 0) +#define DTRACE_PROBE2(a,b,c,d,e) ((void) 0) +#define DTRACE_PROBE3(a,b,c,d,e,f,g) ((void) 0) +#define DTRACE_PROBE4(a,b,c,d,e,f,g,h,i) ((void) 0) + +#endif diff --git a/zfs/lib/libspl/include/sys/sysevent.h b/zfs/lib/libspl/include/sys/sysevent.h new file mode 100644 index 0000000000..c28ee1b0a5 --- /dev/null +++ b/zfs/lib/libspl/include/sys/sysevent.h @@ -0,0 +1,30 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SOL_SYS_SYSEVENT_H +#define _SOL_SYS_SYSEVENT_H + +#endif diff --git a/zfs/lib/libspl/include/sys/u8_textprep.h b/zfs/lib/libspl/include/sys/u8_textprep.h new file mode 100644 index 0000000000..041ef611ca --- /dev/null +++ b/zfs/lib/libspl/include/sys/u8_textprep.h @@ -0,0 +1,119 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include "zfs_config.h" + +#ifdef HAVE_UNICODE +#include_next +#else + +#ifndef _SYS_U8_TEXTPREP_H +#define _SYS_U8_TEXTPREP_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Unicode encoding conversion functions and their macros. + */ +#define UCONV_IN_BIG_ENDIAN 0x0001 +#define UCONV_OUT_BIG_ENDIAN 0x0002 +#define UCONV_IN_SYSTEM_ENDIAN 0x0004 +#define UCONV_OUT_SYSTEM_ENDIAN 0x0008 +#define UCONV_IN_LITTLE_ENDIAN 0x0010 +#define UCONV_OUT_LITTLE_ENDIAN 0x0020 +#define UCONV_IGNORE_NULL 0x0040 +#define UCONV_IN_ACCEPT_BOM 0x0080 +#define UCONV_OUT_EMIT_BOM 0x0100 + +extern int uconv_u16tou32(const uint16_t *, size_t *, uint32_t *, size_t *, + int); +extern int uconv_u16tou8(const uint16_t *, size_t *, uchar_t *, size_t *, int); +extern int uconv_u32tou16(const uint32_t *, size_t *, uint16_t *, size_t *, + int); +extern int uconv_u32tou8(const uint32_t *, size_t *, uchar_t *, size_t *, int); +extern int uconv_u8tou16(const uchar_t *, size_t *, uint16_t *, size_t *, int); +extern int uconv_u8tou32(const uchar_t *, size_t *, uint32_t *, size_t *, int); + +/* + * UTF-8 text preparation functions and their macros. + * + * Among the macros defined, U8_CANON_DECOMP, U8_COMPAT_DECOMP, and + * U8_CANON_COMP are not public interfaces and must not be used directly + * at the flag input argument. + */ +#define U8_STRCMP_CS (0x00000001) +#define U8_STRCMP_CI_UPPER (0x00000002) +#define U8_STRCMP_CI_LOWER (0x00000004) + +#define U8_CANON_DECOMP (0x00000010) +#define U8_COMPAT_DECOMP (0x00000020) +#define U8_CANON_COMP (0x00000040) + +#define U8_STRCMP_NFD (U8_CANON_DECOMP) +#define U8_STRCMP_NFC (U8_CANON_DECOMP | U8_CANON_COMP) +#define U8_STRCMP_NFKD (U8_COMPAT_DECOMP) +#define U8_STRCMP_NFKC (U8_COMPAT_DECOMP | U8_CANON_COMP) + +#define U8_TEXTPREP_TOUPPER (U8_STRCMP_CI_UPPER) +#define U8_TEXTPREP_TOLOWER (U8_STRCMP_CI_LOWER) + +#define U8_TEXTPREP_NFD (U8_STRCMP_NFD) +#define U8_TEXTPREP_NFC (U8_STRCMP_NFC) +#define U8_TEXTPREP_NFKD (U8_STRCMP_NFKD) +#define U8_TEXTPREP_NFKC (U8_STRCMP_NFKC) + +#define U8_TEXTPREP_IGNORE_NULL (0x00010000) +#define U8_TEXTPREP_IGNORE_INVALID (0x00020000) +#define U8_TEXTPREP_NOWAIT (0x00040000) + +#define U8_UNICODE_320 (0) +#define U8_UNICODE_500 (1) +#define U8_UNICODE_LATEST (U8_UNICODE_500) + +#define U8_VALIDATE_ENTIRE (0x00100000) +#define U8_VALIDATE_CHECK_ADDITIONAL (0x00200000) +#define U8_VALIDATE_UCS2_RANGE (0x00400000) + +#define U8_ILLEGAL_CHAR (-1) +#define U8_OUT_OF_RANGE_CHAR (-2) + +extern int u8_validate(char *, size_t, char **, int, int *); +extern int u8_strcmp(const char *, const char *, size_t, int, size_t, int *); +extern size_t u8_textprep_str(char *, size_t *, char *, size_t *, int, size_t, + int *); + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_UNICODE */ + +#endif /* _SYS_U8_TEXTPREP_H */ diff --git a/zfs/lib/libspl/kernel.c b/zfs/lib/libspl/kernel.c index ad2e0ff0fe..fe18b414bd 100644 --- a/zfs/lib/libspl/kernel.c +++ b/zfs/lib/libspl/kernel.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include