1 789 ahrens /* 2 789 ahrens * CDDL HEADER START 3 789 ahrens * 4 789 ahrens * The contents of this file are subject to the terms of the 5 1544 eschrock * Common Development and Distribution License (the "License"). 6 1544 eschrock * You may not use this file except in compliance with the License. 7 789 ahrens * 8 789 ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 789 ahrens * or http://www.opensolaris.org/os/licensing. 10 789 ahrens * See the License for the specific language governing permissions 11 789 ahrens * and limitations under the License. 12 789 ahrens * 13 789 ahrens * When distributing Covered Code, include this CDDL HEADER in each 14 789 ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 789 ahrens * If applicable, add the following below this CDDL HEADER, with the 16 789 ahrens * fields enclosed by brackets "[]" replaced with your own identifying 17 789 ahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18 789 ahrens * 19 789 ahrens * CDDL HEADER END 20 789 ahrens */ 21 789 ahrens /* 22 10614 Jonathan * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 789 ahrens * Use is subject to license terms. 24 789 ahrens */ 25 789 ahrens 26 789 ahrens #include <sys/zfs_context.h> 27 789 ahrens #include <sys/spa.h> 28 789 ahrens #include <sys/zio.h> 29 789 ahrens #include <sys/zio_checksum.h> 30 789 ahrens 31 789 ahrens /* 32 789 ahrens * Checksum vectors. 33 789 ahrens * 34 789 ahrens * In the SPA, everything is checksummed. We support checksum vectors 35 789 ahrens * for three distinct reasons: 36 789 ahrens * 37 789 ahrens * 1. Different kinds of data need different levels of protection. 38 789 ahrens * For SPA metadata, we always want a very strong checksum. 39 789 ahrens * For user data, we let users make the trade-off between speed 40 789 ahrens * and checksum strength. 41 789 ahrens * 42 789 ahrens * 2. Cryptographic hash and MAC algorithms are an area of active research. 43 789 ahrens * It is likely that in future hash functions will be at least as strong 44 789 ahrens * as current best-of-breed, and may be substantially faster as well. 45 789 ahrens * We want the ability to take advantage of these new hashes as soon as 46 789 ahrens * they become available. 47 789 ahrens * 48 789 ahrens * 3. If someone develops hardware that can compute a strong hash quickly, 49 789 ahrens * we want the ability to take advantage of that hardware. 50 789 ahrens * 51 789 ahrens * Of course, we don't want a checksum upgrade to invalidate existing 52 10922 Jeff * data, so we store the checksum *function* in eight bits of the bp. 53 10922 Jeff * This gives us room for up to 256 different checksum functions. 54 789 ahrens * 55 789 ahrens * When writing a block, we always checksum it with the latest-and-greatest 56 789 ahrens * checksum function of the appropriate strength. When reading a block, 57 789 ahrens * we compare the expected checksum against the actual checksum, which we 58 10922 Jeff * compute via the checksum function specified by BP_GET_CHECKSUM(bp). 59 789 ahrens */ 60 789 ahrens 61 789 ahrens /*ARGSUSED*/ 62 789 ahrens static void 63 789 ahrens zio_checksum_off(const void *buf, uint64_t size, zio_cksum_t *zcp) 64 789 ahrens { 65 789 ahrens ZIO_SET_CHECKSUM(zcp, 0, 0, 0, 0); 66 789 ahrens } 67 789 ahrens 68 789 ahrens zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { 69 10922 Jeff {{NULL, NULL}, 0, 0, 0, "inherit"}, 70 10922 Jeff {{NULL, NULL}, 0, 0, 0, "on"}, 71 10922 Jeff {{zio_checksum_off, zio_checksum_off}, 0, 0, 0, "off"}, 72 10922 Jeff {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 1, 0, "label"}, 73 10922 Jeff {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 1, 0, "gang_header"}, 74 10922 Jeff {{fletcher_2_native, fletcher_2_byteswap}, 0, 1, 0, "zilog"}, 75 10922 Jeff {{fletcher_2_native, fletcher_2_byteswap}, 0, 0, 0, "fletcher2"}, 76 10922 Jeff {{fletcher_4_native, fletcher_4_byteswap}, 1, 0, 0, "fletcher4"}, 77 10922 Jeff {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 0, 1, "sha256"}, 78 789 ahrens }; 79 789 ahrens 80 10922 Jeff enum zio_checksum 81 10922 Jeff zio_checksum_select(enum zio_checksum child, enum zio_checksum parent) 82 789 ahrens { 83 789 ahrens ASSERT(child < ZIO_CHECKSUM_FUNCTIONS); 84 789 ahrens ASSERT(parent < ZIO_CHECKSUM_FUNCTIONS); 85 789 ahrens ASSERT(parent != ZIO_CHECKSUM_INHERIT && parent != ZIO_CHECKSUM_ON); 86 789 ahrens 87 789 ahrens if (child == ZIO_CHECKSUM_INHERIT) 88 789 ahrens return (parent); 89 789 ahrens 90 789 ahrens if (child == ZIO_CHECKSUM_ON) 91 789 ahrens return (ZIO_CHECKSUM_ON_VALUE); 92 789 ahrens 93 789 ahrens return (child); 94 789 ahrens } 95 789 ahrens 96 10922 Jeff enum zio_checksum 97 10922 Jeff zio_checksum_dedup_select(spa_t *spa, enum zio_checksum child, 98 10922 Jeff enum zio_checksum parent) 99 10922 Jeff { 100 10922 Jeff ASSERT((child & ZIO_CHECKSUM_MASK) < ZIO_CHECKSUM_FUNCTIONS); 101 10922 Jeff ASSERT((parent & ZIO_CHECKSUM_MASK) < ZIO_CHECKSUM_FUNCTIONS); 102 10922 Jeff ASSERT(parent != ZIO_CHECKSUM_INHERIT && parent != ZIO_CHECKSUM_ON); 103 10922 Jeff 104 10922 Jeff if (child == ZIO_CHECKSUM_INHERIT) 105 10922 Jeff return (parent); 106 10922 Jeff 107 10922 Jeff if (child == ZIO_CHECKSUM_ON) 108 10922 Jeff return (spa_dedup_checksum(spa)); 109 10922 Jeff 110 10922 Jeff if (child == (ZIO_CHECKSUM_ON | ZIO_CHECKSUM_VERIFY)) 111 10922 Jeff return (spa_dedup_checksum(spa) | ZIO_CHECKSUM_VERIFY); 112 10922 Jeff 113 10922 Jeff ASSERT(zio_checksum_table[child & ZIO_CHECKSUM_MASK].ci_dedup || 114 10922 Jeff (child & ZIO_CHECKSUM_VERIFY) || child == ZIO_CHECKSUM_OFF); 115 10922 Jeff 116 10922 Jeff return (child); 117 10922 Jeff } 118 10922 Jeff 119 789 ahrens /* 120 7754 Jeff * Set the external verifier for a gang block based on <vdev, offset, txg>, 121 7754 Jeff * a tuple which is guaranteed to be unique for the life of the pool. 122 7754 Jeff */ 123 7754 Jeff static void 124 7754 Jeff zio_checksum_gang_verifier(zio_cksum_t *zcp, blkptr_t *bp) 125 7754 Jeff { 126 7754 Jeff dva_t *dva = BP_IDENTITY(bp); 127 10922 Jeff uint64_t txg = BP_PHYSICAL_BIRTH(bp); 128 7754 Jeff 129 7754 Jeff ASSERT(BP_IS_GANG(bp)); 130 7754 Jeff 131 7754 Jeff ZIO_SET_CHECKSUM(zcp, DVA_GET_VDEV(dva), DVA_GET_OFFSET(dva), txg, 0); 132 7754 Jeff } 133 7754 Jeff 134 7754 Jeff /* 135 7754 Jeff * Set the external verifier for a label block based on its offset. 136 7754 Jeff * The vdev is implicit, and the txg is unknowable at pool open time -- 137 7754 Jeff * hence the logic in vdev_uberblock_load() to find the most recent copy. 138 7754 Jeff */ 139 7754 Jeff static void 140 7754 Jeff zio_checksum_label_verifier(zio_cksum_t *zcp, uint64_t offset) 141 7754 Jeff { 142 7754 Jeff ZIO_SET_CHECKSUM(zcp, offset, 0, 0, 0); 143 7754 Jeff } 144 7754 Jeff 145 7754 Jeff /* 146 789 ahrens * Generate the checksum. 147 789 ahrens */ 148 789 ahrens void 149 7754 Jeff zio_checksum_compute(zio_t *zio, enum zio_checksum checksum, 150 7754 Jeff void *data, uint64_t size) 151 789 ahrens { 152 7754 Jeff blkptr_t *bp = zio->io_bp; 153 7754 Jeff uint64_t offset = zio->io_offset; 154 789 ahrens zio_block_tail_t *zbt = (zio_block_tail_t *)((char *)data + size) - 1; 155 789 ahrens zio_checksum_info_t *ci = &zio_checksum_table[checksum]; 156 789 ahrens zio_cksum_t zbt_cksum; 157 789 ahrens 158 7754 Jeff ASSERT((uint_t)checksum < ZIO_CHECKSUM_FUNCTIONS); 159 789 ahrens ASSERT(ci->ci_func[0] != NULL); 160 789 ahrens 161 789 ahrens if (ci->ci_zbt) { 162 7754 Jeff if (checksum == ZIO_CHECKSUM_GANG_HEADER) 163 7754 Jeff zio_checksum_gang_verifier(&zbt->zbt_cksum, bp); 164 7754 Jeff else if (checksum == ZIO_CHECKSUM_LABEL) 165 7754 Jeff zio_checksum_label_verifier(&zbt->zbt_cksum, offset); 166 7754 Jeff else 167 7754 Jeff bp->blk_cksum = zbt->zbt_cksum; 168 789 ahrens zbt->zbt_magic = ZBT_MAGIC; 169 789 ahrens ci->ci_func[0](data, size, &zbt_cksum); 170 789 ahrens zbt->zbt_cksum = zbt_cksum; 171 789 ahrens } else { 172 7754 Jeff ci->ci_func[0](data, size, &bp->blk_cksum); 173 789 ahrens } 174 789 ahrens } 175 789 ahrens 176 789 ahrens int 177 10614 Jonathan zio_checksum_error(zio_t *zio, zio_bad_cksum_t *info) 178 789 ahrens { 179 789 ahrens blkptr_t *bp = zio->io_bp; 180 7754 Jeff uint_t checksum = (bp == NULL ? zio->io_prop.zp_checksum : 181 7754 Jeff (BP_IS_GANG(bp) ? ZIO_CHECKSUM_GANG_HEADER : BP_GET_CHECKSUM(bp))); 182 7754 Jeff int byteswap; 183 10614 Jonathan int error; 184 7754 Jeff uint64_t size = (bp == NULL ? zio->io_size : 185 7754 Jeff (BP_IS_GANG(bp) ? SPA_GANGBLOCKSIZE : BP_GET_PSIZE(bp))); 186 7754 Jeff uint64_t offset = zio->io_offset; 187 10614 Jonathan void *data = zio->io_data; 188 789 ahrens zio_block_tail_t *zbt = (zio_block_tail_t *)((char *)data + size) - 1; 189 789 ahrens zio_checksum_info_t *ci = &zio_checksum_table[checksum]; 190 7754 Jeff zio_cksum_t actual_cksum, expected_cksum, verifier; 191 789 ahrens 192 789 ahrens if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func[0] == NULL) 193 789 ahrens return (EINVAL); 194 789 ahrens 195 789 ahrens if (ci->ci_zbt) { 196 789 ahrens if (checksum == ZIO_CHECKSUM_GANG_HEADER) 197 7754 Jeff zio_checksum_gang_verifier(&verifier, bp); 198 7754 Jeff else if (checksum == ZIO_CHECKSUM_LABEL) 199 7754 Jeff zio_checksum_label_verifier(&verifier, offset); 200 7754 Jeff else 201 7754 Jeff verifier = bp->blk_cksum; 202 789 ahrens 203 7754 Jeff byteswap = (zbt->zbt_magic == BSWAP_64(ZBT_MAGIC)); 204 7754 Jeff 205 7754 Jeff if (byteswap) 206 7754 Jeff byteswap_uint64_array(&verifier, sizeof (zio_cksum_t)); 207 7754 Jeff 208 7754 Jeff expected_cksum = zbt->zbt_cksum; 209 7754 Jeff zbt->zbt_cksum = verifier; 210 7754 Jeff ci->ci_func[byteswap](data, size, &actual_cksum); 211 7754 Jeff zbt->zbt_cksum = expected_cksum; 212 7754 Jeff 213 7754 Jeff if (byteswap) 214 789 ahrens byteswap_uint64_array(&expected_cksum, 215 789 ahrens sizeof (zio_cksum_t)); 216 789 ahrens } else { 217 1775 billm ASSERT(!BP_IS_GANG(bp)); 218 7754 Jeff byteswap = BP_SHOULD_BYTESWAP(bp); 219 7754 Jeff expected_cksum = bp->blk_cksum; 220 789 ahrens ci->ci_func[byteswap](data, size, &actual_cksum); 221 789 ahrens } 222 789 ahrens 223 10614 Jonathan info->zbc_expected = expected_cksum; 224 10614 Jonathan info->zbc_actual = actual_cksum; 225 10614 Jonathan info->zbc_checksum_name = ci->ci_name; 226 10614 Jonathan info->zbc_byteswapped = byteswap; 227 10614 Jonathan info->zbc_injected = 0; 228 10614 Jonathan info->zbc_has_cksum = 1; 229 10614 Jonathan 230 7754 Jeff if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum)) 231 789 ahrens return (ECKSUM); 232 789 ahrens 233 10614 Jonathan if (zio_injection_enabled && !zio->io_error && 234 10614 Jonathan (error = zio_handle_fault_injection(zio, ECKSUM)) != 0) { 235 10614 Jonathan 236 10614 Jonathan info->zbc_injected = 1; 237 10614 Jonathan return (error); 238 10614 Jonathan } 239 1544 eschrock 240 789 ahrens return (0); 241 789 ahrens } 242