xref: /freebsd/sys/cddl/boot/zfs/zfssubr.c (revision 39beb93c)
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 
29 static uint64_t zfs_crc64_table[256];
30 
31 static void
32 zfs_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 
49 static void
50 zio_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  */
58 typedef void zio_checksum_t(const void *data, uint64_t size, zio_cksum_t *zcp);
59 
60 /*
61  * Information about each checksum function.
62  */
63 typedef 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 
73 static 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  */
88 typedef size_t zio_compress_func_t(void *src, void *dst,
89     size_t s_len, size_t d_len, int);
90 typedef 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  */
96 typedef 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  */
108 static 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 
125 static int
126 zio_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 
157 static int
158 zio_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 %u\n", cpfunc);
166 		return (EIO);
167 	}
168 
169 	return (ci->ci_decompress(src, dest, srcsize, destsize, ci->ci_level));
170 }
171 
172 static uint64_t
173 zap_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