zfssubr.c revision 185029
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#include <sys/cdefs.h>
27__FBSDID("$FreeBSD$");
28
29static uint64_t zfs_crc64_table[256];
30
31static void
32zfs_init_crc(void)
33{
34	int i, j;
35	uint64_t *ct;
36
37	/*
38	 * Calculate the crc64 table (used for the zap hash
39	 * function).
40	 */
41	if (zfs_crc64_table[128] != ZFS_CRC64_POLY) {
42		memset(zfs_crc64_table, 0, sizeof(zfs_crc64_table));
43		for (i = 0; i < 256; i++)
44			for (ct = zfs_crc64_table + i, *ct = i, j = 8; j > 0; j--)
45				*ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY);
46	}
47}
48
49static void
50zio_checksum_off(const void *buf, uint64_t size, zio_cksum_t *zcp)
51{
52	ZIO_SET_CHECKSUM(zcp, 0, 0, 0, 0);
53}
54
55/*
56 * Signature for checksum functions.
57 */
58typedef void zio_checksum_t(const void *data, uint64_t size, zio_cksum_t *zcp);
59
60/*
61 * Information about each checksum function.
62 */
63typedef struct zio_checksum_info {
64	zio_checksum_t	*ci_func[2]; /* checksum function for each byteorder */
65	int		ci_correctable;	/* number of correctable bits	*/
66	int		ci_zbt;		/* uses zio block tail?	*/
67	const char	*ci_name;	/* descriptive name */
68} zio_checksum_info_t;
69
70#include "fletcher.c"
71#include "sha256.c"
72
73static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
74	{{NULL,			NULL},			0, 0,	"inherit"},
75	{{NULL,			NULL},			0, 0,	"on"},
76	{{zio_checksum_off,	zio_checksum_off},	0, 0,	"off"},
77	{{zio_checksum_SHA256,	NULL},			1, 1,	"label"},
78	{{zio_checksum_SHA256,	NULL},			1, 1,	"gang_header"},
79	{{fletcher_2_native,	NULL},			0, 1,	"zilog"},
80	{{fletcher_2_native,	NULL},			0, 0,	"fletcher2"},
81	{{fletcher_4_native,	NULL},			1, 0,	"fletcher4"},
82	{{zio_checksum_SHA256,	NULL},			1, 0,	"SHA256"},
83};
84
85/*
86 * Common signature for all zio compress/decompress functions.
87 */
88typedef size_t zio_compress_func_t(void *src, void *dst,
89    size_t s_len, size_t d_len, int);
90typedef int zio_decompress_func_t(void *src, void *dst,
91    size_t s_len, size_t d_len, int);
92
93/*
94 * Information about each compression function.
95 */
96typedef struct zio_compress_info {
97	zio_compress_func_t	*ci_compress;	/* compression function */
98	zio_decompress_func_t	*ci_decompress;	/* decompression function */
99	int			ci_level;	/* level parameter */
100	const char		*ci_name;	/* algorithm name */
101} zio_compress_info_t;
102
103#include "lzjb.c"
104
105/*
106 * Compression vectors.
107 */
108static zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = {
109	{NULL,			NULL,			0,	"inherit"},
110	{NULL,			NULL,			0,	"on"},
111	{NULL,			NULL,			0,	"uncompressed"},
112	{NULL,			lzjb_decompress,	0,	"lzjb"},
113	{NULL,			NULL,			0,	"empty"},
114	{NULL,			NULL,			1,	"gzip-1"},
115	{NULL,			NULL,			2,	"gzip-2"},
116	{NULL,			NULL,			3,	"gzip-3"},
117	{NULL,			NULL,			4,	"gzip-4"},
118	{NULL,			NULL,			5,	"gzip-5"},
119	{NULL,			NULL,			6,	"gzip-6"},
120	{NULL,			NULL,			7,	"gzip-7"},
121	{NULL,			NULL,			8,	"gzip-8"},
122	{NULL,			NULL,			9,	"gzip-9"},
123};
124
125static int
126zio_checksum_error(const blkptr_t *bp, void *data)
127{
128	zio_cksum_t zc = bp->blk_cksum;
129	unsigned int checksum = BP_GET_CHECKSUM(bp);
130	uint64_t size = BP_GET_PSIZE(bp);
131	zio_block_tail_t *zbt = (zio_block_tail_t *)((char *)data + size) - 1;
132	zio_checksum_info_t *ci = &zio_checksum_table[checksum];
133	zio_cksum_t actual_cksum, expected_cksum;
134
135	if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func[0] == NULL)
136		return (EINVAL);
137
138	if (ci->ci_zbt) {
139		expected_cksum = zbt->zbt_cksum;
140		zbt->zbt_cksum = zc;
141		ci->ci_func[0](data, size, &actual_cksum);
142		zbt->zbt_cksum = expected_cksum;
143		zc = expected_cksum;
144	} else {
145		/* ASSERT(!BP_IS_GANG(bp)); */
146		ci->ci_func[0](data, size, &actual_cksum);
147	}
148
149	if (!ZIO_CHECKSUM_EQUAL(actual_cksum, zc)) {
150		/*printf("ZFS: read checksum failed\n");*/
151		return (EIO);
152	}
153
154	return (0);
155}
156
157static int
158zio_decompress_data(int cpfunc, void *src, uint64_t srcsize,
159	void *dest, uint64_t destsize)
160{
161	zio_compress_info_t *ci = &zio_compress_table[cpfunc];
162
163	/* ASSERT((uint_t)cpfunc < ZIO_COMPRESS_FUNCTIONS); */
164	if (!ci->ci_decompress) {
165		printf("ZFS: unsupported compression algorithm %d\n", cpfunc);
166		return (EIO);
167	}
168
169	return (ci->ci_decompress(src, dest, srcsize, destsize, ci->ci_level));
170}
171
172static uint64_t
173zap_hash(uint64_t salt, const char *name)
174{
175	const uint8_t *cp;
176	uint8_t c;
177	uint64_t crc = salt;
178
179	/*ASSERT(crc != 0);*/
180	/*ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);*/
181	for (cp = (const uint8_t *)name; (c = *cp) != '\0'; cp++)
182		crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ c) & 0xFF];
183
184	/*
185	 * Only use 28 bits, since we need 4 bits in the cookie for the
186	 * collision differentiator.  We MUST use the high bits, since
187	 * those are the onces that we first pay attention to when
188	 * chosing the bucket.
189	 */
190	crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1);
191
192	return (crc);
193}
194