Print this page
4185 New hash algorithm support


   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 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */



  25 
  26 /*
  27  * Fletcher Checksums
  28  * ------------------
  29  *
  30  * ZFS's 2nd and 4th order Fletcher checksums are defined by the following
  31  * recurrence relations:
  32  *
  33  *      a  = a    + f
  34  *       i    i-1    i-1
  35  *
  36  *      b  = b    + a
  37  *       i    i-1    i
  38  *
  39  *      c  = c    + b           (fletcher-4 only)
  40  *       i    i-1    i
  41  *
  42  *      d  = d    + c           (fletcher-4 only)
  43  *       i    i-1    i
  44  *


 114  * Even though fletcher-4 is slower than fletcher-2, it is still a pretty
 115  * efficient pass over the data.
 116  *
 117  * In normal operation, the data which is being checksummed is in a buffer
 118  * which has been filled either by:
 119  *
 120  *      1. a compression step, which will be mostly cached, or
 121  *      2. a bcopy() or copyin(), which will be uncached (because the
 122  *         copy is cache-bypassing).
 123  *
 124  * For both cached and uncached data, both fletcher checksums are much faster
 125  * than sha-256, and slower than 'off', which doesn't touch the data at all.
 126  */
 127 
 128 #include <sys/types.h>
 129 #include <sys/sysmacros.h>
 130 #include <sys/byteorder.h>
 131 #include <sys/zio.h>
 132 #include <sys/spa.h>
 133 

 134 void
 135 fletcher_2_native(const void *buf, uint64_t size, zio_cksum_t *zcp)

 136 {
 137         const uint64_t *ip = buf;
 138         const uint64_t *ipend = ip + (size / sizeof (uint64_t));
 139         uint64_t a0, b0, a1, b1;
 140 
 141         for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
 142                 a0 += ip[0];
 143                 a1 += ip[1];
 144                 b0 += a0;
 145                 b1 += a1;
 146         }
 147 
 148         ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
 149 }
 150 

 151 void
 152 fletcher_2_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)

 153 {
 154         const uint64_t *ip = buf;
 155         const uint64_t *ipend = ip + (size / sizeof (uint64_t));
 156         uint64_t a0, b0, a1, b1;
 157 
 158         for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
 159                 a0 += BSWAP_64(ip[0]);
 160                 a1 += BSWAP_64(ip[1]);
 161                 b0 += a0;
 162                 b1 += a1;
 163         }
 164 
 165         ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
 166 }
 167 

 168 void
 169 fletcher_4_native(const void *buf, uint64_t size, zio_cksum_t *zcp)

 170 {
 171         const uint32_t *ip = buf;
 172         const uint32_t *ipend = ip + (size / sizeof (uint32_t));
 173         uint64_t a, b, c, d;
 174 
 175         for (a = b = c = d = 0; ip < ipend; ip++) {
 176                 a += ip[0];
 177                 b += a;
 178                 c += b;
 179                 d += c;
 180         }
 181 
 182         ZIO_SET_CHECKSUM(zcp, a, b, c, d);
 183 }
 184 

 185 void
 186 fletcher_4_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)

 187 {
 188         const uint32_t *ip = buf;
 189         const uint32_t *ipend = ip + (size / sizeof (uint32_t));
 190         uint64_t a, b, c, d;
 191 
 192         for (a = b = c = d = 0; ip < ipend; ip++) {
 193                 a += BSWAP_32(ip[0]);
 194                 b += a;
 195                 c += b;
 196                 d += c;
 197         }
 198 
 199         ZIO_SET_CHECKSUM(zcp, a, b, c, d);
 200 }
 201 
 202 void
 203 fletcher_4_incremental_native(const void *buf, uint64_t size,
 204     zio_cksum_t *zcp)
 205 {
 206         const uint32_t *ip = buf;




   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 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2013 Saso Kiselkov. All rights reserved.
  27  */
  28 
  29 /*
  30  * Fletcher Checksums
  31  * ------------------
  32  *
  33  * ZFS's 2nd and 4th order Fletcher checksums are defined by the following
  34  * recurrence relations:
  35  *
  36  *      a  = a    + f
  37  *       i    i-1    i-1
  38  *
  39  *      b  = b    + a
  40  *       i    i-1    i
  41  *
  42  *      c  = c    + b           (fletcher-4 only)
  43  *       i    i-1    i
  44  *
  45  *      d  = d    + c           (fletcher-4 only)
  46  *       i    i-1    i
  47  *


 117  * Even though fletcher-4 is slower than fletcher-2, it is still a pretty
 118  * efficient pass over the data.
 119  *
 120  * In normal operation, the data which is being checksummed is in a buffer
 121  * which has been filled either by:
 122  *
 123  *      1. a compression step, which will be mostly cached, or
 124  *      2. a bcopy() or copyin(), which will be uncached (because the
 125  *         copy is cache-bypassing).
 126  *
 127  * For both cached and uncached data, both fletcher checksums are much faster
 128  * than sha-256, and slower than 'off', which doesn't touch the data at all.
 129  */
 130 
 131 #include <sys/types.h>
 132 #include <sys/sysmacros.h>
 133 #include <sys/byteorder.h>
 134 #include <sys/zio.h>
 135 #include <sys/spa.h>
 136 
 137 /*ARGSUSED*/
 138 void
 139 fletcher_2_native(const void *buf, uint64_t size, const zio_cksum_salt_t *salt,
 140     const void *ctx_template, zio_cksum_t *zcp)
 141 {
 142         const uint64_t *ip = buf;
 143         const uint64_t *ipend = ip + (size / sizeof (uint64_t));
 144         uint64_t a0, b0, a1, b1;
 145 
 146         for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
 147                 a0 += ip[0];
 148                 a1 += ip[1];
 149                 b0 += a0;
 150                 b1 += a1;
 151         }
 152 
 153         ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
 154 }
 155 
 156 /*ARGSUSED*/
 157 void
 158 fletcher_2_byteswap(const void *buf, uint64_t size,
 159     const zio_cksum_salt_t *salt, const void *ctx_template, zio_cksum_t *zcp)
 160 {
 161         const uint64_t *ip = buf;
 162         const uint64_t *ipend = ip + (size / sizeof (uint64_t));
 163         uint64_t a0, b0, a1, b1;
 164 
 165         for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
 166                 a0 += BSWAP_64(ip[0]);
 167                 a1 += BSWAP_64(ip[1]);
 168                 b0 += a0;
 169                 b1 += a1;
 170         }
 171 
 172         ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
 173 }
 174 
 175 /*ARGSUSED*/
 176 void
 177 fletcher_4_native(const void *buf, uint64_t size, const zio_cksum_salt_t *salt,
 178     const void *ctx_template, zio_cksum_t *zcp)
 179 {
 180         const uint32_t *ip = buf;
 181         const uint32_t *ipend = ip + (size / sizeof (uint32_t));
 182         uint64_t a, b, c, d;
 183 
 184         for (a = b = c = d = 0; ip < ipend; ip++) {
 185                 a += ip[0];
 186                 b += a;
 187                 c += b;
 188                 d += c;
 189         }
 190 
 191         ZIO_SET_CHECKSUM(zcp, a, b, c, d);
 192 }
 193 
 194 /*ARGSUSED*/
 195 void
 196 fletcher_4_byteswap(const void *buf, uint64_t size,
 197     const zio_cksum_salt_t *salt, const void *ctx_template, zio_cksum_t *zcp)
 198 {
 199         const uint32_t *ip = buf;
 200         const uint32_t *ipend = ip + (size / sizeof (uint32_t));
 201         uint64_t a, b, c, d;
 202 
 203         for (a = b = c = d = 0; ip < ipend; ip++) {
 204                 a += BSWAP_32(ip[0]);
 205                 b += a;
 206                 c += b;
 207                 d += c;
 208         }
 209 
 210         ZIO_SET_CHECKSUM(zcp, a, b, c, d);
 211 }
 212 
 213 void
 214 fletcher_4_incremental_native(const void *buf, uint64_t size,
 215     zio_cksum_t *zcp)
 216 {
 217         const uint32_t *ip = buf;