linux/drivers/staging/lustre/lustre/include/obd_cksum.h
<<
>>
Prefs
   1/*
   2 * GPL HEADER START
   3 *
   4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 only,
   8 * as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License version 2 for more details (a copy is included
  14 * in the LICENSE file that accompanied this code).
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * version 2 along with this program; If not, see
  18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  19 *
  20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  21 * CA 95054 USA or visit www.sun.com if you need additional information or
  22 * have any questions.
  23 *
  24 * GPL HEADER END
  25 */
  26/*
  27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  28 * Use is subject to license terms.
  29 */
  30/*
  31 * This file is part of Lustre, http://www.lustre.org/
  32 * Lustre is a trademark of Sun Microsystems, Inc.
  33 */
  34
  35#ifndef __OBD_CKSUM
  36#define __OBD_CKSUM
  37#include "../../include/linux/libcfs/libcfs.h"
  38#include "lustre/lustre_idl.h"
  39
  40static inline unsigned char cksum_obd2cfs(enum cksum_type cksum_type)
  41{
  42        switch (cksum_type) {
  43        case OBD_CKSUM_CRC32:
  44                return CFS_HASH_ALG_CRC32;
  45        case OBD_CKSUM_ADLER:
  46                return CFS_HASH_ALG_ADLER32;
  47        case OBD_CKSUM_CRC32C:
  48                return CFS_HASH_ALG_CRC32C;
  49        default:
  50                CERROR("Unknown checksum type (%x)!!!\n", cksum_type);
  51                LBUG();
  52        }
  53        return 0;
  54}
  55
  56/* The OBD_FL_CKSUM_* flags is packed into 5 bits of o_flags, since there can
  57 * only be a single checksum type per RPC.
  58 *
  59 * The OBD_CHECKSUM_* type bits passed in ocd_cksum_types are a 32-bit bitmask
  60 * since they need to represent the full range of checksum algorithms that
  61 * both the client and server can understand.
  62 *
  63 * In case of an unsupported types/flags we fall back to ADLER
  64 * because that is supported by all clients since 1.8
  65 *
  66 * In case multiple algorithms are supported the best one is used.
  67 */
  68static inline u32 cksum_type_pack(enum cksum_type cksum_type)
  69{
  70        unsigned int    performance = 0, tmp;
  71        u32             flag = OBD_FL_CKSUM_ADLER;
  72
  73        if (cksum_type & OBD_CKSUM_CRC32) {
  74                tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32));
  75                if (tmp > performance) {
  76                        performance = tmp;
  77                        flag = OBD_FL_CKSUM_CRC32;
  78                }
  79        }
  80        if (cksum_type & OBD_CKSUM_CRC32C) {
  81                tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C));
  82                if (tmp > performance) {
  83                        performance = tmp;
  84                        flag = OBD_FL_CKSUM_CRC32C;
  85                }
  86        }
  87        if (cksum_type & OBD_CKSUM_ADLER) {
  88                tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER));
  89                if (tmp > performance) {
  90                        performance = tmp;
  91                        flag = OBD_FL_CKSUM_ADLER;
  92                }
  93        }
  94        if (unlikely(cksum_type && !(cksum_type & (OBD_CKSUM_CRC32C |
  95                                                   OBD_CKSUM_CRC32 |
  96                                                   OBD_CKSUM_ADLER))))
  97                CWARN("unknown cksum type %x\n", cksum_type);
  98
  99        return flag;
 100}
 101
 102static inline enum cksum_type cksum_type_unpack(u32 o_flags)
 103{
 104        switch (o_flags & OBD_FL_CKSUM_ALL) {
 105        case OBD_FL_CKSUM_CRC32C:
 106                return OBD_CKSUM_CRC32C;
 107        case OBD_FL_CKSUM_CRC32:
 108                return OBD_CKSUM_CRC32;
 109        default:
 110                break;
 111        }
 112
 113        return OBD_CKSUM_ADLER;
 114}
 115
 116/* Return a bitmask of the checksum types supported on this system.
 117 * 1.8 supported ADLER it is base and not depend on hw
 118 * Client uses all available local algos
 119 */
 120static inline enum cksum_type cksum_types_supported_client(void)
 121{
 122        enum cksum_type ret = OBD_CKSUM_ADLER;
 123
 124        CDEBUG(D_INFO, "Crypto hash speed: crc %d, crc32c %d, adler %d\n",
 125               cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)),
 126               cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)),
 127               cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER)));
 128
 129        if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)) > 0)
 130                ret |= OBD_CKSUM_CRC32C;
 131        if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)) > 0)
 132                ret |= OBD_CKSUM_CRC32;
 133
 134        return ret;
 135}
 136
 137/* Select the best checksum algorithm among those supplied in the cksum_types
 138 * input.
 139 *
 140 * Currently, calling cksum_type_pack() with a mask will return the fastest
 141 * checksum type due to its benchmarking at libcfs module load.
 142 * Caution is advised, however, since what is fastest on a single client may
 143 * not be the fastest or most efficient algorithm on the server.
 144 */
 145static inline enum cksum_type cksum_type_select(enum cksum_type cksum_types)
 146{
 147        return cksum_type_unpack(cksum_type_pack(cksum_types));
 148}
 149
 150/* Checksum algorithm names. Must be defined in the same order as the
 151 * OBD_CKSUM_* flags.
 152 */
 153#define DECLARE_CKSUM_NAME char *cksum_name[] = {"crc32", "adler", "crc32c"}
 154
 155#endif /* __OBD_H */
 156