svn commit: r191931 - in head/sys: cddl/contrib/opensolaris/common/acl cddl/contrib/opensolaris/common/atomic/amd64 cddl/contrib/opensolaris/common/atomic/i386 cddl/contrib/opensolaris/common/atomi...

Kip Macy kmacy at FreeBSD.org
Sat May 9 01:45:56 UTC 2009


Author: kmacy
Date: Sat May  9 01:45:55 2009
New Revision: 191931
URL: http://svn.freebsd.org/changeset/base/191931

Log:
  - rename atomic.S and crc32.c to avoid collisions when linking zfs in to the kernel
  - update Makefile
  - ifdef out acl_{alloc, free}, they aren't used by zfs and conflict with existing in-kernel routines

Added:
  head/sys/cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S   (props changed)
     - copied unchanged from r191903, head/sys/cddl/contrib/opensolaris/common/atomic/amd64/atomic.S
  head/sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S   (props changed)
     - copied unchanged from r191903, head/sys/cddl/contrib/opensolaris/common/atomic/i386/atomic.S
  head/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S   (props changed)
     - copied unchanged from r191903, head/sys/cddl/contrib/opensolaris/common/atomic/ia64/atomic.S
  head/sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S   (props changed)
     - copied unchanged from r191903, head/sys/cddl/contrib/opensolaris/common/atomic/sparc64/atomic.S
  head/sys/cddl/contrib/opensolaris/uts/common/zmod/opensolaris_crc32.c   (props changed)
     - copied unchanged from r191903, head/sys/cddl/contrib/opensolaris/uts/common/zmod/crc32.c
Deleted:
  head/sys/cddl/contrib/opensolaris/common/atomic/amd64/atomic.S
  head/sys/cddl/contrib/opensolaris/common/atomic/i386/atomic.S
  head/sys/cddl/contrib/opensolaris/common/atomic/ia64/atomic.S
  head/sys/cddl/contrib/opensolaris/common/atomic/sparc64/atomic.S
  head/sys/cddl/contrib/opensolaris/uts/common/zmod/crc32.c
Modified:
  head/sys/cddl/contrib/opensolaris/common/acl/acl_common.c
  head/sys/modules/zfs/Makefile

Modified: head/sys/cddl/contrib/opensolaris/common/acl/acl_common.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/common/acl/acl_common.c	Sat May  9 01:35:27 2009	(r191930)
+++ head/sys/cddl/contrib/opensolaris/common/acl/acl_common.c	Sat May  9 01:45:55 2009	(r191931)
@@ -424,6 +424,7 @@ cacl_free(void *ptr, size_t size)
 #endif
 }
 
+#ifndef __FreeBSD__
 acl_t *
 acl_alloc(enum acl_type type)
 {
@@ -469,6 +470,7 @@ acl_free(acl_t *aclp)
 
 	cacl_free(aclp, sizeof (acl_t));
 }
+#endif
 
 static uint32_t
 access_mask_set(int haswriteperm, int hasreadperm, int isowner, int isallow)

Copied: head/sys/cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S (from r191903, head/sys/cddl/contrib/opensolaris/common/atomic/amd64/atomic.S)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S	Sat May  9 01:45:55 2009	(r191931, copy of r191903, head/sys/cddl/contrib/opensolaris/common/atomic/amd64/atomic.S)
@@ -0,0 +1,66 @@
+/*
+ * 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 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+	.file	"atomic.s"
+
+#define	_ASM
+#include <sys/asm_linkage.h>
+
+	ENTRY(atomic_add_64_nv)
+	movq	(%rdi), %rax
+1:
+	movq	%rsi, %rcx
+	addq	%rax, %rcx
+	lock
+	cmpxchgq %rcx, (%rdi)
+	jne	1b
+	movq	%rcx, %rax
+	ret
+	SET_SIZE(atomic_add_64_nv)
+
+	ENTRY(atomic_or_8_nv)
+	movb	(%rdi), %al	// %al = old value
+1:
+	movb	%sil, %cl
+	orb	%al, %cl	// %cl = new value
+	lock
+	cmpxchgb %cl, (%rdi)	// try to stick it in
+	jne	1b
+	movzbl	%cl, %eax	// return new value
+	ret
+	SET_SIZE(atomic_or_8_nv)
+
+	ENTRY(atomic_cas_64)
+	movq	%rsi, %rax
+	lock
+	cmpxchgq %rdx, (%rdi)
+	ret
+	SET_SIZE(atomic_cas_64)
+
+	ENTRY(membar_producer)
+	sfence
+	ret
+	SET_SIZE(membar_producer)

Copied: head/sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S (from r191903, head/sys/cddl/contrib/opensolaris/common/atomic/i386/atomic.S)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S	Sat May  9 01:45:55 2009	(r191931, copy of r191903, head/sys/cddl/contrib/opensolaris/common/atomic/i386/atomic.S)
@@ -0,0 +1,133 @@
+/*
+ * 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 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+	.file	"atomic.s"
+
+#define	_ASM
+#include <sys/asm_linkage.h>
+
+	/*
+	 * NOTE: If atomic_dec_64 and atomic_dec_64_nv are ever
+	 * separated, it is important to edit the libc i386 platform
+	 * specific mapfile and remove the NODYNSORT attribute
+	 * from atomic_dec_64_nv.
+	 */
+	ENTRY(atomic_dec_64)
+	ALTENTRY(atomic_dec_64_nv)
+	pushl	%edi
+	pushl	%ebx
+	movl	12(%esp), %edi	// %edi = target address
+	movl	(%edi), %eax
+	movl	4(%edi), %edx	// %edx:%eax = old value
+1:
+	xorl	%ebx, %ebx
+	xorl	%ecx, %ecx
+	not	%ecx
+	not	%ebx		// %ecx:%ebx = -1
+	addl	%eax, %ebx
+	adcl	%edx, %ecx	// add in the carry from inc
+	lock
+	cmpxchg8b (%edi)	// try to stick it in
+	jne	1b
+	movl	%ebx, %eax
+	movl	%ecx, %edx	// return new value
+	popl	%ebx
+	popl	%edi
+	ret
+	SET_SIZE(atomic_dec_64_nv)
+	SET_SIZE(atomic_dec_64)
+
+	/*
+	 * NOTE: If atomic_add_64 and atomic_add_64_nv are ever
+	 * separated, it is important to edit the libc i386 platform
+	 * specific mapfile and remove the NODYNSORT attribute
+	 * from atomic_add_64_nv.
+	 */
+	ENTRY(atomic_add_64)
+	ALTENTRY(atomic_add_64_nv)
+	pushl	%edi
+	pushl	%ebx
+	movl	12(%esp), %edi	// %edi = target address
+	movl	(%edi), %eax
+	movl	4(%edi), %edx	// %edx:%eax = old value
+1:
+	movl	16(%esp), %ebx
+	movl	20(%esp), %ecx	// %ecx:%ebx = delta
+	addl	%eax, %ebx
+	adcl	%edx, %ecx	// %ecx:%ebx = new value
+	lock
+	cmpxchg8b (%edi)	// try to stick it in
+	jne	1b
+	movl	%ebx, %eax
+	movl	%ecx, %edx	// return new value
+	popl	%ebx
+	popl	%edi
+	ret
+	SET_SIZE(atomic_add_64_nv)
+	SET_SIZE(atomic_add_64)
+
+	ENTRY(atomic_or_8_nv)
+	movl	4(%esp), %edx	// %edx = target address
+	movb	(%edx), %al	// %al = old value
+1:
+	movl	8(%esp), %ecx	// %ecx = delta
+	orb	%al, %cl	// %cl = new value
+	lock
+	cmpxchgb %cl, (%edx)	// try to stick it in
+	jne	1b
+	movzbl	%cl, %eax	// return new value
+	ret
+	SET_SIZE(atomic_or_8_nv)
+
+	ENTRY(atomic_cas_ptr)
+	movl	4(%esp), %edx
+	movl	8(%esp), %eax
+	movl	12(%esp), %ecx
+	lock
+	cmpxchgl %ecx, (%edx)
+	ret
+	SET_SIZE(atomic_cas_ptr)
+
+	ENTRY(atomic_cas_64)
+	pushl	%ebx
+	pushl	%esi
+	movl	12(%esp), %esi
+	movl	16(%esp), %eax
+	movl	20(%esp), %edx
+	movl	24(%esp), %ebx
+	movl	28(%esp), %ecx
+	lock
+	cmpxchg8b (%esi)
+	popl	%esi
+	popl	%ebx
+	ret
+	SET_SIZE(atomic_cas_64)
+
+	ENTRY(membar_producer)
+	lock
+	xorl	$0, (%esp)
+	ret
+	SET_SIZE(membar_producer)

Copied: head/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S (from r191903, head/sys/cddl/contrib/opensolaris/common/atomic/ia64/atomic.S)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S	Sat May  9 01:45:55 2009	(r191931, copy of r191903, head/sys/cddl/contrib/opensolaris/common/atomic/ia64/atomic.S)
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2007 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asm.h>
+
+	.text
+
+/*
+ * uint64_t atomic_cas_64(volatile uint64_t *p, uint64_t cmp, uint64_t v)
+ */
+ENTRY(atomic_cas_64, 3)
+	mov             ar.ccv = r33
+	;;
+	cmpxchg8.acq    r8 = [r32], r34, ar.ccv
+	;;
+	br.ret.sptk     rp
+END(atomic_cas_64)
+
+/*
+ * uint64_t atomic_add_64_nv(volatile uint64_t *p, uint64_t v)
+ */
+ENTRY(atomic_add_64_nv, 2)
+1:
+	ld8		r16 = [r32]
+	;;
+	mov		ar.ccv = r16
+	add		r8 = r16, r33
+	;;
+	cmpxchg8.acq	r17 = [r32], r8, ar.ccv
+	;;
+	cmp.eq		p6, p7 = r16, r17
+(p6)	br.ret.sptk	rp
+(p7)	br.cond.spnt	1b
+END(atomic_add_64_nv)
+
+/*
+ * uint8_t atomic_or_8_nv(volatile uint8_t *p, uint8_t v)
+ */
+ENTRY(atomic_or_8_nv, 2)
+1:
+	ld8		r16 = [r32]
+	;;
+	mov		ar.ccv = r16
+	or		r8 = r16, r33
+	;;
+	cmpxchg1.acq	r17 = [r32], r8, ar.ccv
+	;;
+	cmp.eq		p6, p7 = r16, r17
+(p6)	br.ret.sptk	rp
+(p7)	br.cond.spnt	1b
+END(atomic_or_8_nv)
+
+ENTRY(membar_producer, 0)
+	mf.a
+	;;
+	br.ret.sptk	rp
+END(membar_producer)

Copied: head/sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S (from r191903, head/sys/cddl/contrib/opensolaris/common/atomic/sparc64/atomic.S)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S	Sat May  9 01:45:55 2009	(r191931, copy of r191903, head/sys/cddl/contrib/opensolaris/common/atomic/sparc64/atomic.S)
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+	.ident	"%Z%%M%	%I%	%E% SMI"
+
+	.file	"%M%"
+
+#define	_ASM
+#include <sys/asm_linkage.h>
+
+#include <machine/asi.h>
+
+/* Userland needs different ASIs. */
+#ifdef _KERNEL
+#define	__ASI_ATOMIC	ASI_N
+#else
+#define	__ASI_ATOMIC	ASI_P
+#endif
+
+	/*
+	 * NOTE: If atomic_add_64 and atomic_add_64_nv are ever
+	 * separated, you need to also edit the libc sparcv9 platform
+	 * specific mapfile and remove the NODYNSORT attribute
+	 * from atomic_add_64_nv.
+	 */
+	ENTRY(atomic_add_64)
+	ALTENTRY(atomic_add_64_nv)
+	ALTENTRY(atomic_add_ptr)
+	ALTENTRY(atomic_add_ptr_nv)
+	ALTENTRY(atomic_add_long)
+	ALTENTRY(atomic_add_long_nv)
+add_64:
+	ldx	[%o0], %o2
+1:
+	add	%o2, %o1, %o3
+	casxa	[%o0] __ASI_ATOMIC, %o2, %o3
+	cmp	%o2, %o3
+	bne,a,pn %xcc, 1b
+	  mov	%o3, %o2
+	retl
+	add	%o2, %o1, %o0		! return new value
+	SET_SIZE(atomic_add_long_nv)
+	SET_SIZE(atomic_add_long)
+	SET_SIZE(atomic_add_ptr_nv)
+	SET_SIZE(atomic_add_ptr)
+	SET_SIZE(atomic_add_64_nv)
+	SET_SIZE(atomic_add_64)
+
+	/*
+	 * NOTE: If atomic_or_8 and atomic_or_8_nv are ever
+	 * separated, you need to also edit the libc sparcv9 platform
+	 * specific mapfile and remove the NODYNSORT attribute
+	 * from atomic_or_8_nv.
+	 */
+	ENTRY(atomic_or_8)
+	ALTENTRY(atomic_or_8_nv)
+	ALTENTRY(atomic_or_uchar)
+	ALTENTRY(atomic_or_uchar_nv)
+	and	%o0, 0x3, %o4		! %o4 = byte offset, left-to-right
+	xor	%o4, 0x3, %g1		! %g1 = byte offset, right-to-left
+	sll	%g1, 3, %g1		! %g1 = bit offset, right-to-left
+	set	0xff, %o3		! %o3 = mask
+	sll	%o3, %g1, %o3		! %o3 = shifted to bit offset
+	sll	%o1, %g1, %o1		! %o1 = shifted to bit offset
+	and	%o1, %o3, %o1		! %o1 = single byte value
+	andn	%o0, 0x3, %o0		! %o0 = word address
+	ld	[%o0], %o2		! read old value
+1:
+	or	%o2, %o1, %o5		! or in the new value
+	casa	[%o0] __ASI_ATOMIC, %o2, %o5
+	cmp	%o2, %o5
+	bne,a,pn %icc, 1b
+	  mov	%o5, %o2		! %o2 = old value
+	or	%o2, %o1, %o5
+	and	%o5, %o3, %o5
+	retl
+	srl	%o5, %g1, %o0		! %o0 = new value
+	SET_SIZE(atomic_or_uchar_nv)
+	SET_SIZE(atomic_or_uchar)
+	SET_SIZE(atomic_or_8_nv)
+	SET_SIZE(atomic_or_8)
+
+	/*
+	 * Spitfires and Blackbirds have a problem with membars in the
+	 * delay slot (SF_ERRATA_51).  For safety's sake, we assume
+	 * that the whole world needs the workaround.
+	 */
+
+	ENTRY(membar_producer)
+	membar	#StoreStore
+	retl
+	nop
+	SET_SIZE(membar_producer)

Copied: head/sys/cddl/contrib/opensolaris/uts/common/zmod/opensolaris_crc32.c (from r191903, head/sys/cddl/contrib/opensolaris/uts/common/zmod/crc32.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/cddl/contrib/opensolaris/uts/common/zmod/opensolaris_crc32.c	Sat May  9 01:45:55 2009	(r191931, copy of r191903, head/sys/cddl/contrib/opensolaris/uts/common/zmod/crc32.c)
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64 at csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors.  This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+  protection on the static variables used to control the first-use generation
+  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+  first call get_crc_table() to initialize the tables before allowing more than
+  one thread to use crc32().
+ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+#  ifdef STDC           /* need ANSI C limits.h to determine sizes */
+#    include <limits.h>
+#    define BYFOUR
+#    if (UINT_MAX == 0xffffffffUL)
+       typedef unsigned int u4;
+#    else
+#      if (ULONG_MAX == 0xffffffffUL)
+         typedef unsigned long u4;
+#      else
+#        if (USHRT_MAX == 0xffffffffUL)
+           typedef unsigned short u4;
+#        else
+#          undef BYFOUR     /* can't find a four-byte integer type! */
+#        endif
+#      endif
+#    endif
+#  endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+#  define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
+                (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+   local unsigned long crc32_little OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+   local unsigned long crc32_big OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+#  define TBLS 8
+#else
+#  define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+                                         unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The first table is simply the CRC of all possible eight bit values.  This is
+  all the information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.  The remaining tables
+  allow for word-at-a-time CRC calculation for both big-endian and little-
+  endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+    unsigned long c;
+    int n, k;
+    unsigned long poly;                 /* polynomial exclusive-or pattern */
+    /* terms of polynomial defining this crc (except x^32): */
+    static volatile int first = 1;      /* flag to limit concurrent making */
+    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+    /* See if another task is already doing this (not thread-safe, but better
+       than nothing -- significantly reduces duration of vulnerability in
+       case the advice about DYNAMIC_CRC_TABLE is ignored) */
+    if (first) {
+        first = 0;
+
+        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+        poly = 0UL;
+        for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+            poly |= 1UL << (31 - p[n]);
+
+        /* generate a crc for every 8-bit value */
+        for (n = 0; n < 256; n++) {
+            c = (unsigned long)n;
+            for (k = 0; k < 8; k++)
+                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+            crc_table[0][n] = c;
+        }
+
+#ifdef BYFOUR
+        /* generate crc for each value followed by one, two, and three zeros,
+           and then the byte reversal of those as well as the first table */
+        for (n = 0; n < 256; n++) {
+            c = crc_table[0][n];
+            crc_table[4][n] = REV(c);
+            for (k = 1; k < 4; k++) {
+                c = crc_table[0][c & 0xff] ^ (c >> 8);
+                crc_table[k][n] = c;
+                crc_table[k + 4][n] = REV(c);
+            }
+        }
+#endif /* BYFOUR */
+
+        crc_table_empty = 0;
+    }
+    else {      /* not first */
+        /* wait for the other guy to finish (not efficient, but rare) */
+        while (crc_table_empty)
+            ;
+    }
+
+#ifdef MAKECRCH
+    /* write out CRC tables to crc32.h */
+    {
+        FILE *out;
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+        fprintf(out, "local const unsigned long FAR ");
+        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
+        write_table(out, crc_table[0]);
+#  ifdef BYFOUR
+        fprintf(out, "#ifdef BYFOUR\n");
+        for (k = 1; k < 8; k++) {
+            fprintf(out, "  },\n  {\n");
+            write_table(out, crc_table[k]);
+        }
+        fprintf(out, "#endif\n");
+#  endif /* BYFOUR */
+        fprintf(out, "  }\n};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+    FILE *out;
+    const unsigned long FAR *table;
+{
+    int n;
+
+    for (n = 0; n < 256; n++)
+        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n],
+                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+    return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+        u4 endian;
+
+        endian = 1;
+        if (*((unsigned char *)(&endian)))
+            return crc32_little(crc, buf, len);
+        else
+            return crc32_big(crc, buf, len);
+    }
+#endif /* BYFOUR */
+    crc = crc ^ 0xffffffffUL;
+    while (len >= 8) {
+        DO8;
+        len -= 8;
+    }
+    if (len) do {
+        DO1;
+    } while (--len);
+    return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = (u4)crc;
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
+    while (len >= 32) {
+        DOLIT32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOLIT4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = REV((u4)crc);
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
+    buf4--;
+    while (len >= 32) {
+        DOBIG32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOBIG4;
+        len -= 4;
+    }
+    buf4++;
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+    unsigned long *mat;
+    unsigned long vec;
+{
+    unsigned long sum;
+
+    sum = 0;
+    while (vec) {
+        if (vec & 1)
+            sum ^= *mat;
+        vec >>= 1;
+        mat++;
+    }
+    return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+    unsigned long *square;
+    unsigned long *mat;
+{
+    int n;
+
+    for (n = 0; n < GF2_DIM; n++)
+        square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off_t len2;
+{
+    int n;
+    unsigned long row;
+    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
+    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
+
+    /* degenerate case */
+    if (len2 == 0)
+        return crc1;
+
+    /* put operator for one zero bit in odd */
+    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
+    row = 1;
+    for (n = 1; n < GF2_DIM; n++) {
+        odd[n] = row;
+        row <<= 1;
+    }
+
+    /* put operator for two zero bits in even */
+    gf2_matrix_square(even, odd);
+
+    /* put operator for four zero bits in odd */
+    gf2_matrix_square(odd, even);
+
+    /* apply len2 zeros to crc1 (first square will put the operator for one
+       zero byte, eight zero bits, in even) */
+    do {
+        /* apply zeros operator for this bit of len2 */
+        gf2_matrix_square(even, odd);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(even, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+        if (len2 == 0)
+            break;
+
+        /* another iteration of the loop with odd and even swapped */
+        gf2_matrix_square(odd, even);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(odd, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+    } while (len2 != 0);
+
+    /* return combined crc */
+    crc1 ^= crc2;
+    return crc1;
+}

Modified: head/sys/modules/zfs/Makefile
==============================================================================
--- head/sys/modules/zfs/Makefile	Sat May  9 01:35:27 2009	(r191930)
+++ head/sys/modules/zfs/Makefile	Sat May  9 01:45:55 2009	(r191931)
@@ -28,7 +28,7 @@ SRCS+=	opensolaris_zone.c
 
 .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64" || ${MACHINE_ARCH} == "sparc64"
 .PATH:	${SUNW}/common/atomic/${MACHINE_ARCH}
-SRCS+=	atomic.S
+SRCS+=	opensolaris_atomic.S
 .else
 .PATH:	${.CURDIR}/../../cddl/compat/opensolaris/kern
 SRCS+=	opensolaris_atomic.c
@@ -51,7 +51,7 @@ SRCS+=	xdr_mem.c
 
 .PATH:	${SUNW}/uts/common/zmod
 SRCS+=	adler32.c
-SRCS+=	crc32.c
+SRCS+=	opensolaris_crc32.c
 SRCS+=	deflate.c
 SRCS+=	inffast.c
 SRCS+=	inflate.c


More information about the svn-src-all mailing list