usr/src/uts/common/fs/zfs/lzjb.c
author eschrock
Fri, 03 Mar 2006 20:08:16 -0800
changeset 1544 938876158511
parent 789 b348f31ed315
child 2597 21c0f93f2513
permissions -rw-r--r--
PSARC 2006/077 zpool clear PSARC 2006/139 FMA for ZFS 6284889 arc should replace the znode cache 6333006 DMU & DSL should not panic upon I/O error 6333092 concurrent reads to a file not scaling with number of readers 6338081 ZFS/FMA phase 1 6338386 need persistent error log 6341326 i/o error causes arc buf hash table corruption 6341639 zfs backup/restore should compute/verify checksum of backup stream 6348002 out of space due to changing properties 6354724 inaccurate error message from zfs restore 6354872 dmu_sync() blows predictive accounting 6355416 zpool scrubbing consumes all memory, system hung 6363995 df should only load libzfs when it encounters a ZFS filesystem 6366320 zfs backup/restore doesn't like signals 6368892 mount -m support needed for legacy mounts 6368902 boot archive fstat support needed for ZFS Mountroot 6369424 BFU complains when bfu'ing a ZFS root filesystem 6374062 mountroot support needed for ZFS 6376356 dirtying dbuf obj=43 lvl=0 blkid=0 but not tx_held 6378391 unused members of dmu_objset_stats_t 6378392 clean up zfs_cmd_t structure 6378685 buf_init should allocate its hash table more carefully 6378976 ziltest should be a first class citizen 6381086 zdb segfaults if there is a spa deferred-free bplist 6381203 deadlock due to i/o while assigning (tc_lock held) 6381209 freed space is not immediately available 6381344 'zpool clear' 6381345 FAULTED devices should really be UNAVAIL 6381346 import should mark devices as persistently unavailable 6383272 recursive mutex_enter() during log replay with zfs root 6386326 origin property is not displayed 6386354 libzfs does too much in its _init section, calls exit(1) 6386624 zpool should not complain about non-existent devices from libdiskmgt 6386910 spa needs to be i/o error hardened 6387735 need a mechanism to inject faults into ZFS 6387736 internal ZFS utilities should be placed in an ON-private package 6389928 libzfs should ship a lint library 6390609 malformed vdev config panics on zpool_create() 6390677 version number checking makes upgrades challenging 6390713 ztest hangs in zil_suspend() 6391873 metadata compression should be turned back on 6392113 ztest sometimes reports leaked blocks because ZIL isn't resilvered 6393004 minor memory leak in unique_insert()
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 * with the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    22
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
 * This is stolen from common/os/compress.c and will be removed once
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
 * our changes have made it into the on10 source base.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
 * In particular, we are adding the "feature" that compress() can
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
 * take a destination buffer size and return -1 if the data will not
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
 * compress to d_len or less.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <sys/types.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#define	MATCH_BITS	6
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#define	MATCH_MIN	3
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
#define	MATCH_MAX	((1 << MATCH_BITS) + (MATCH_MIN - 1))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
#define	OFFSET_MASK	((1 << (16 - MATCH_BITS)) - 1)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#define	LEMPEL_SIZE	256
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
size_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
lzjb_compress(void *s_start, void *d_start, size_t s_len, size_t d_len)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
	uchar_t *src = s_start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
	uchar_t *dst = d_start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
	uchar_t *cpy, *copymap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
	int copymask = 1 << (NBBY - 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
	int mlen, offset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
	uint16_t *hp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	uint16_t lempel[LEMPEL_SIZE];	/* uninitialized; see above */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
	while (src < (uchar_t *)s_start + s_len) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
		if ((copymask <<= 1) == (1 << NBBY)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
			if (dst >= (uchar_t *)d_start + d_len - 1 - 2 * NBBY) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
				if (d_len != s_len)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
					return (s_len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
				mlen = s_len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
				for (src = s_start, dst = d_start; mlen; mlen--)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
					*dst++ = *src++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
				return (s_len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
			copymask = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
			copymap = dst;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
			*dst++ = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
		if (src > (uchar_t *)s_start + s_len - MATCH_MAX) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
			*dst++ = *src++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
		hp = &lempel[((src[0] + 13) ^ (src[1] - 13) ^ src[2]) &
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
		    (LEMPEL_SIZE - 1)];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
		offset = (intptr_t)(src - *hp) & OFFSET_MASK;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
		*hp = (uint16_t)(uintptr_t)src;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
		cpy = src - offset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
		if (cpy >= (uchar_t *)s_start && cpy != src &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
		    src[0] == cpy[0] && src[1] == cpy[1] && src[2] == cpy[2]) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
			*copymap |= copymask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
			for (mlen = MATCH_MIN; mlen < MATCH_MAX; mlen++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
				if (src[mlen] != cpy[mlen])
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
					break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
			*dst++ = ((mlen - MATCH_MIN) << (NBBY - MATCH_BITS)) |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
			    (offset >> NBBY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
			*dst++ = (uchar_t)offset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
			src += mlen;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
			*dst++ = *src++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	return (dst - (uchar_t *)d_start);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
lzjb_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
	uchar_t *src = s_start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
	uchar_t *dst = d_start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
	uchar_t *d_end = (uchar_t *)d_start + d_len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
	uchar_t *cpy, copymap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
	int copymask = 1 << (NBBY - 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
	while (dst < d_end) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
		if ((copymask <<= 1) == (1 << NBBY)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
			copymask = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
			copymap = *src++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
		if (copymap & copymask) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
			int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
			int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
			src += 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
			if ((cpy = dst - offset) < (uchar_t *)d_start)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
				return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
			while (--mlen >= 0 && dst < d_end)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
				*dst++ = *cpy++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
			*dst++ = *src++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
}