usr/src/uts/common/fs/zfs/zle.c
author Joshua M. Clulow <jmc@joyent.com>
Mon, 04 Mar 2013 23:52:56 +0000
changeset 14188 afe390b9f1e0
parent 10922 e2081f502306
permissions -rw-r--r--
4020 Make ldi_ev_remove_callbacks safe to use in LDI callbacks Reviewed by: Robert Mustacchi <[email protected]> Approved by: Dan McDonald <[email protected]>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
     1
/*
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
     2
 * CDDL HEADER START
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
     3
 *
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
     5
 * Common Development and Distribution License (the "License").
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
     6
 * You may not use this file except in compliance with the License.
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
     7
 *
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    11
 * and limitations under the License.
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    12
 *
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    18
 *
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    19
 * CDDL HEADER END
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    20
 */
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    21
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    22
/*
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    23
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    24
 * Use is subject to license terms.
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    25
 */
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    26
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    27
/*
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    28
 * Zero-length encoding.  This is a fast and simple algorithm to eliminate
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    29
 * runs of zeroes.  Each chunk of compressed data begins with a length byte, b.
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    30
 * If b < n (where n is the compression parameter) then the next b + 1 bytes
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    31
 * are literal values.  If b >= n then the next (256 - b + 1) bytes are zero.
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    32
 */
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    33
#include <sys/types.h>
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    34
#include <sys/sysmacros.h>
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    35
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    36
size_t
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    37
zle_compress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    38
{
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    39
	uchar_t *src = s_start;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    40
	uchar_t *dst = d_start;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    41
	uchar_t *s_end = src + s_len;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    42
	uchar_t *d_end = dst + d_len;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    43
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    44
	while (src < s_end && dst < d_end - 1) {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    45
		uchar_t *first = src;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    46
		uchar_t *len = dst++;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    47
		if (src[0] == 0) {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    48
			uchar_t *last = src + (256 - n);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    49
			while (src < MIN(last, s_end) && src[0] == 0)
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    50
				src++;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    51
			*len = src - first - 1 + n;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    52
		} else {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    53
			uchar_t *last = src + n;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    54
			if (d_end - dst < n)
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    55
				break;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    56
			while (src < MIN(last, s_end) - 1 && (src[0] | src[1]))
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    57
				*dst++ = *src++;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    58
			if (src[0])
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    59
				*dst++ = *src++;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    60
			*len = src - first - 1;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    61
		}
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    62
	}
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    63
	return (src == s_end ? dst - (uchar_t *)d_start : s_len);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    64
}
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    65
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    66
int
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    67
zle_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    68
{
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    69
	uchar_t *src = s_start;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    70
	uchar_t *dst = d_start;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    71
	uchar_t *s_end = src + s_len;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    72
	uchar_t *d_end = dst + d_len;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    73
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    74
	while (src < s_end && dst < d_end) {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    75
		int len = 1 + *src++;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    76
		if (len <= n) {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    77
			while (len-- != 0)
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    78
				*dst++ = *src++;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    79
		} else {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    80
			len -= n;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    81
			while (len-- != 0)
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    82
				*dst++ = 0;
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    83
		}
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    84
	}
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    85
	return (dst == d_end ? 0 : -1);
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
diff changeset
    86
}