])
])
-# LIBCFS_DIGEST_SETKEY_FLAGS
-# digest_alg.dia_setkey takes 4 args (2.6.18)
-#
-AC_DEFUN([LIBCFS_DIGEST_SETKEY_FLAGS],
-[AC_MSG_CHECKING([if kernel dia_setkey takes 4 args])
-LB_LINUX_TRY_COMPILE([
- #include <linux/err.h>
- #include <linux/crypto.h>
-
- static int foo(struct crypto_tfm *tfm, const u8 *key, unsigned int l, u32* f)
- {
- return 1;
- }
-],[
- struct digest_alg alg = {.dia_setkey=foo};
-],[
- AC_MSG_RESULT([yes])
- AC_DEFINE(HAVE_DIGEST_SETKEY_FLAGS, 1, [kernel dia_setkey takes 4 args])
-],[
- AC_MSG_RESULT([no])
-])
-])
-
-
# 2.6.19 API changes
# kmem_cache_destroy(cachep) return void instead of
# int
])
])
-
# 2.6.20 API change INIT_WORK use 2 args and not
# store data inside
AC_DEFUN([LIBCFS_3ARGS_INIT_WORK],
])
])
-# LIBCFS_STRUCT_SHASH_ALG
-# struct shash_alg was introduced in 2.6.29
-#
-AC_DEFUN([LIBCFS_STRUCT_SHASH_ALG],
-[AC_MSG_CHECKING([if kernel has struct shash_alg])
-LB_LINUX_TRY_COMPILE([
- #include <linux/err.h>
- #include <crypto/internal/hash.h>
-],[
- struct shash_alg foo;
-],[
- AC_MSG_RESULT([yes])
- AC_DEFINE(HAVE_STRUCT_SHASH_ALG, 1, [kernel has struct shash_alg])
-],[
- AC_MSG_RESULT([no])
-])
-])
-
-
#
# LIBCFS_FUNC_UNSHARE_FS_STRUCT
#
# 2.6.18
LIBCFS_TASKLIST_LOCK
LIBCFS_HAVE_IS_COMPAT_TASK
-LIBCFS_DIGEST_SETKEY_FLAGS
# 2.6.19
LIBCFS_KMEM_CACHE_DESTROY_INT
# 2.6.20
# 2.6.29
LIBCFS_STRUCT_CRED_IN_TASK
LIBCFS_CPU_TOPOLOGY
-LIBCFS_STRUCT_SHASH_ALG
# 2.6.30
LIBCFS_FUNC_UNSHARE_FS_STRUCT
LIBCFS_SOCK_MAP_FD_2ARG
libcfs_debug.h libcfsutil.h libcfs_ioctl.h \
libcfs_pack.h libcfs_unpack.h libcfs_string.h \
libcfs_kernelcomm.h libcfs_workitem.h lucache.h \
- libcfs_fail.h params_tree.h libcfs_crypto.h
+ libcfs_fail.h params_tree.h
#include <libcfs/libcfs_hash.h>
#include <libcfs/libcfs_fail.h>
#include <libcfs/params_tree.h>
-#include <libcfs/libcfs_crypto.h>
/* container_of depends on "likely" which is defined in libcfs_private.h */
static inline void *__container_of(void *ptr, unsigned long shift)
+++ /dev/null
-/* GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
-/*
- * Copyright 2012 Xyratex Technology Limited
- */
-
-#ifndef _LIBCFS_CRYPTO_H
-#define _LIBCFS_CRYPTO_H
-
-struct cfs_crypto_hash_type {
- char *cht_name; /**< hash algorithm name, equal to
- * format name for crypto api */
- unsigned int cht_key; /**< init key by default (vaild for
- * 4 bytes context like crc32, adler */
- unsigned int cht_size; /**< hash digest size */
-};
-
-enum cfs_crypto_hash_alg {
- CFS_HASH_ALG_NULL = 0,
- CFS_HASH_ALG_ADLER32,
- CFS_HASH_ALG_CRC32,
- CFS_HASH_ALG_MD5,
- CFS_HASH_ALG_SHA1,
- CFS_HASH_ALG_SHA256,
- CFS_HASH_ALG_SHA384,
- CFS_HASH_ALG_SHA512,
- CFS_HASH_ALG_CRC32C,
- CFS_HASH_ALG_MAX
-};
-
-static struct cfs_crypto_hash_type hash_types[] = {
- [CFS_HASH_ALG_NULL] = { "null", 0, 0 },
- [CFS_HASH_ALG_ADLER32] = { "adler32", 1, 4 },
- [CFS_HASH_ALG_CRC32] = { "crc32", ~0, 4 },
- [CFS_HASH_ALG_CRC32C] = { "crc32c", ~0, 4 },
- [CFS_HASH_ALG_MD5] = { "md5", 0, 16 },
- [CFS_HASH_ALG_SHA1] = { "sha1", 0, 20 },
- [CFS_HASH_ALG_SHA256] = { "sha256", 0, 32 },
- [CFS_HASH_ALG_SHA384] = { "sha384", 0, 48 },
- [CFS_HASH_ALG_SHA512] = { "sha512", 0, 64 },
-};
-
-/** Return pointer to type of hash for valid hash algorithm identifier */
-static inline const struct cfs_crypto_hash_type *
- cfs_crypto_hash_type(unsigned char hash_alg)
-{
- struct cfs_crypto_hash_type *ht;
-
- if (hash_alg < CFS_HASH_ALG_MAX) {
- ht = &hash_types[hash_alg];
- if (ht->cht_name)
- return ht;
- }
- return NULL;
-}
-
-/** Return hash name for valid hash algorithm identifier or "unknown" */
-static inline const char *cfs_crypto_hash_name(unsigned char hash_alg)
-{
- const struct cfs_crypto_hash_type *ht;
-
- ht = cfs_crypto_hash_type(hash_alg);
- if (ht)
- return ht->cht_name;
- else
- return "unknown";
-}
-
-/** Return digest size for valid algorithm identifier or 0 */
-static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg)
-{
- const struct cfs_crypto_hash_type *ht;
-
- ht = cfs_crypto_hash_type(hash_alg);
- if (ht)
- return ht->cht_size;
- else
- return 0;
-}
-
-/** Return hash identifier for valid hash algorithm name or 0xFF */
-static inline unsigned char cfs_crypto_hash_alg(const char *algname)
-{
- unsigned char i;
-
- for (i = 0; i < CFS_HASH_ALG_MAX; i++)
- if (!strcmp(hash_types[i].cht_name, algname))
- break;
- return (i == CFS_HASH_ALG_MAX ? 0xFF : i);
-}
-
-/** Calculate hash digest for buffer.
- * @param alg id of hash algorithm
- * @param buf buffer of data
- * @param buf_len buffer len
- * @param key initial value for algorithm, if it is NULL,
- * default initial value should be used.
- * @param key_len len of initial value
- * @param hash [out] pointer to hash, if it is NULL, hash_len is
- * set to valid digest size in bytes, retval -ENOSPC.
- * @param hash_len [in,out] size of hash buffer
- * @returns status of operation
- * @retval -EINVAL if buf, buf_len, hash_len or alg_id is invalid
- * @retval -ENODEV if this algorithm is unsupported
- * @retval -ENOSPC if pointer to hash is NULL, or hash_len less than
- * digest size
- * @retval 0 for success
- * @retval < 0 other errors from lower layers.
- */
-int cfs_crypto_hash_digest(unsigned char alg,
- const void *buf, unsigned int buf_len,
- unsigned char *key, unsigned int key_len,
- unsigned char *hash, unsigned int *hash_len);
-
-/* cfs crypto hash descriptor */
-struct cfs_crypto_hash_desc;
-
-/** Allocate and initialize desriptor for hash algorithm.
- * @param alg algorithm id
- * @param key initial value for algorithm, if it is NULL,
- * default initial value should be used.
- * @param key_len len of initial value
- * @returns pointer to descriptor of hash instance
- * @retval ERR_PTR(error) when errors occured.
- */
-struct cfs_crypto_hash_desc*
- cfs_crypto_hash_init(unsigned char alg,
- unsigned char *key, unsigned int key_len);
-
-/** Update digest by part of data.
- * @param desc hash descriptor
- * @param page data page
- * @param offset data offset
- * @param len data len
- * @returns status of operation
- * @retval 0 for success.
- */
-int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
- cfs_page_t *page, unsigned int offset,
- unsigned int len);
-
-/** Update digest by part of data.
- * @param desc hash descriptor
- * @param buf pointer to data buffer
- * @param buf_len size of data at buffer
- * @returns status of operation
- * @retval 0 for success.
- */
-int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
- unsigned int buf_len);
-
-/** Finalize hash calculation, copy hash digest to buffer, destroy hash
- * descriptor.
- * @param desc hash descriptor
- * @param hash buffer pointer to store hash digest
- * @param hash_len pointer to hash buffer size, if NULL
- * destory hash descriptor
- * @returns status of operation
- * @retval -ENOSPC if hash is NULL, or *hash_len less than
- * digest size
- * @retval 0 for success
- * @retval < 0 other errors from lower layers.
- */
-int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
- unsigned char *hash, unsigned int *hash_len);
-/**
- * Register crypto hash algorithms
- */
-int cfs_crypto_register(void);
-
-/**
- * Unregister
- */
-void cfs_crypto_unregister(void);
-
-/** Return hash speed in Mbytes per second for valid hash algorithm
- * identifier. If test was unsuccessfull -1 would be return.
- */
-int cfs_crypto_hash_speed(unsigned char hash_alg);
-#endif
EXTRA_DIST := kp30.h libcfs.h linux-fs.h linux-lock.h linux-mem.h \
linux-prim.h linux-time.h linux-tcpip.h lltrace.h linux-cpu.h \
- portals_compat25.h linux-bitops.h linux-types.h linux-crypto.h
+ portals_compat25.h linux-bitops.h linux-types.h
+++ /dev/null
- /*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
-/*
- * Copyright 2012 Xyratex Technology Limited
- */
-
-/**
- * Linux crypto hash specific functions.
- */
-
-/**
- * Functions for start/stop shash CRC32 algorithm.
- */
-int cfs_crypto_crc32_register(void);
-void cfs_crypto_crc32_unregister(void);
-
-/**
- * Functions for start/stop shash adler32 algorithm.
- */
-int cfs_crypto_adler32_register(void);
-void cfs_crypto_adler32_unregister(void);
libcfsposix_HEADERS = posix-types.h
endif
-EXTRA_DIST := libcfs.h posix-wordsize.h posix-types.h posix-crypto.h
+EXTRA_DIST := libcfs.h posix-wordsize.h posix-types.h
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
-/*
- * Copyright 2012 Xyratex Technology Limited
- */
-
-/**
- * User crypto hash specific functions.
- */
-
-/**
- * CRC32 functions.
- */
-int crc32init_le(void);
-unsigned int crc32_le(unsigned int crc, unsigned char const *p, size_t len);
-
-/**
- * Adler32 functions.
- */
-unsigned long zlib_adler32(unsigned long adler,
- const unsigned char *buf,
- unsigned int len);
libcfs-linux-objs += linux-fs.o linux-sync.o linux-tcpip.o
libcfs-linux-objs += linux-lwt.o linux-proc.o linux-curproc.o
libcfs-linux-objs += linux-utils.o linux-module.o
-libcfs-linux-objs += linux-crypto.o linux-crypto-crc32.o
-libcfs-linux-objs += linux-crypto-adler.o
default: all
noinst_LIBRARIES= libcfs.a
libcfs_a_SOURCES= posix/posix-debug.c user-prim.c user-lock.c user-tcpip.c \
prng.c user-bitops.c user-mem.c hash.c kernel_user_comm.c \
- workitem.c fail.c libcfs_cpu.c libcfs_mem.c libcfs_lock.c \
- user-crypto.c posix/posix-crc32.c posix/posix-adler.c
+ workitem.c fail.c libcfs_cpu.c libcfs_mem.c libcfs_lock.c
libcfs_a_CPPFLAGS = $(LLCPPFLAGS)
libcfs_a_CFLAGS = $(LLCFLAGS)
endif
EXTRA_DIST := linux-debug.c linux-lwt.c linux-prim.c linux-tracefile.c \
linux-fs.c linux-mem.c linux-proc.c linux-utils.c linux-lock.c \
- linux-module.c linux-sync.c linux-curproc.c linux-tcpip.c \
- linux-cpu.c linux-crypto.c linux-crypto-crc32.c linux-crypto-adler.c
-
+ linux-module.c linux-sync.c linux-curproc.c linux-tcpip.c linux-cpu.c
+++ /dev/null
-/* GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
-/*
- * Copyright 2012 Xyratex Technology Limited
- */
-
-/*
- * This is crypto api shash wrappers to zlib_adler32.
- */
-
-#include <linux/zutil.h>
-#ifdef HAVE_STRUCT_SHASH_ALG
-#include <crypto/internal/hash.h>
-#else
-#include <linux/crypto.h>
-#endif
-
-
-#define CHKSUM_BLOCK_SIZE 1
-#define CHKSUM_DIGEST_SIZE 4
-
-
-static u32 __adler32(u32 cksum, unsigned char const *p, size_t len)
-{
- return zlib_adler32(cksum, p, len);
-}
-
-static int adler32_cra_init(struct crypto_tfm *tfm)
-{
- u32 *key = crypto_tfm_ctx(tfm);
-
- *key = 1;
-
- return 0;
-}
-
-#ifdef HAVE_STRUCT_SHASH_ALG
-static int adler32_setkey(struct crypto_shash *hash, const u8 *key,
- unsigned int keylen)
-{
- u32 *mctx = crypto_shash_ctx(hash);
-
- if (keylen != sizeof(u32)) {
- crypto_shash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN);
- return -EINVAL;
- }
- *mctx = *(u32 *)key;
- return 0;
-}
-
-static int adler32_init(struct shash_desc *desc)
-{
- u32 *mctx = crypto_shash_ctx(desc->tfm);
- u32 *cksump = shash_desc_ctx(desc);
-
- *cksump = *mctx;
-
- return 0;
-}
-
-static int adler32_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
-{
- u32 *cksump = shash_desc_ctx(desc);
-
- *cksump = __adler32(*cksump, data, len);
- return 0;
-}
-static int __adler32_finup(u32 *cksump, const u8 *data, unsigned int len,
- u8 *out)
-{
- *(u32 *)out = __adler32(*cksump, data, len);
- return 0;
-}
-
-static int adler32_finup(struct shash_desc *desc, const u8 *data,
- unsigned int len, u8 *out)
-{
- return __adler32_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int adler32_final(struct shash_desc *desc, u8 *out)
-{
- u32 *cksump = shash_desc_ctx(desc);
-
- *(u32 *)out = *cksump;
- return 0;
-}
-
-static int adler32_digest(struct shash_desc *desc, const u8 *data,
- unsigned int len, u8 *out)
-{
- return __adler32_finup(crypto_shash_ctx(desc->tfm), data, len,
- out);
-}
-static struct shash_alg alg = {
- .setkey = adler32_setkey,
- .init = adler32_init,
- .update = adler32_update,
- .final = adler32_final,
- .finup = adler32_finup,
- .digest = adler32_digest,
- .descsize = sizeof(u32),
- .digestsize = CHKSUM_DIGEST_SIZE,
- .base = {
- .cra_name = "adler32",
- .cra_driver_name = "adler32-zlib",
- .cra_priority = 100,
- .cra_blocksize = CHKSUM_BLOCK_SIZE,
- .cra_ctxsize = sizeof(u32),
- .cra_module = THIS_MODULE,
- .cra_init = adler32_cra_init,
- }
-};
-#else /* HAVE_STRUCT_SHASH_ALG */
-#ifdef HAVE_DIGEST_SETKEY_FLAGS
-static int adler32_digest_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen, u32 *flags)
-#else
-static int adler32_digest_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen)
-#endif
-{
- u32 *mctx = crypto_tfm_ctx(tfm);
-
- if (keylen != sizeof(u32)) {
- tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
- return -EINVAL;
- }
- *mctx = le32_to_cpup((__le32 *)key);
- return 0;
-}
-
-static void adler32_digest_init(struct crypto_tfm *tfm)
-{
- u32 *mctx = crypto_tfm_ctx(tfm);
-
- *mctx = 0;
-
-}
-static void adler32_digest_update(struct crypto_tfm *tfm, const u8 *data,
- unsigned int len)
-{
- u32 *crcp = crypto_tfm_ctx(tfm);
-
- *crcp = __adler32(*crcp, data, len);
-}
-
-static void adler32_digest_final(struct crypto_tfm *tfm, u8 *out)
-{
- u32 *chksum = crypto_tfm_ctx(tfm);
-
- *(__le32 *)out = cpu_to_le32p(chksum);
-}
-
-static struct crypto_alg alg = {
- .cra_name = "adler32",
- .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
- .cra_driver_name = "adler32-zlib",
- .cra_priority = 100,
- .cra_blocksize = CHKSUM_BLOCK_SIZE,
- .cra_ctxsize = sizeof(u32),
- .cra_module = THIS_MODULE,
- .cra_init = adler32_cra_init,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
- .cra_u = {
- .digest = {
- .dia_digestsize = CHKSUM_DIGEST_SIZE,
- .dia_setkey = adler32_digest_setkey,
- .dia_init = adler32_digest_init,
- .dia_update = adler32_digest_update,
- .dia_final = adler32_digest_final
- }
- }
-};
-#endif /* HAVE_STRUCT_SHASH_ALG */
-
-
-int cfs_crypto_adler32_register(void)
-{
-#ifdef HAVE_STRUCT_SHASH_ALG
- return crypto_register_shash(&alg);
-#else
- return crypto_register_alg(&alg);
-#endif
-}
-EXPORT_SYMBOL(cfs_crypto_adler32_register);
-
-void cfs_crypto_adler32_unregister(void)
-{
-#ifdef HAVE_STRUCT_SHASH_ALG
- crypto_unregister_shash(&alg);
-#else
- crypto_unregister_alg(&alg);
-#endif
-}
-EXPORT_SYMBOL(cfs_crypto_adler32_unregister);
+++ /dev/null
-/* GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
-/*
- * Copyright 2012 Xyratex Technology Limited
- */
-
-/*
- * This is crypto api shash wrappers to crc32_le.
- */
-
-#include <linux/crc32.h>
-#ifdef HAVE_STRUCT_SHASH_ALG
-#include <crypto/internal/hash.h>
-#else
-#include <linux/crypto.h>
-#endif
-
-#define CHKSUM_BLOCK_SIZE 1
-#define CHKSUM_DIGEST_SIZE 4
-
-static u32 __crc32_le(u32 crc, unsigned char const *p, size_t len)
-{
- return crc32_le(crc, p, len);
-}
-
-/** No default init with ~0 */
-static int crc32_cra_init(struct crypto_tfm *tfm)
-{
- u32 *key = crypto_tfm_ctx(tfm);
-
- *key = 0;
-
- return 0;
-}
-
-
-#ifdef HAVE_STRUCT_SHASH_ALG
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set
- * the seed.
- */
-static int crc32_setkey(struct crypto_shash *hash, const u8 *key,
- unsigned int keylen)
-{
- u32 *mctx = crypto_shash_ctx(hash);
-
- if (keylen != sizeof(u32)) {
- crypto_shash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN);
- return -EINVAL;
- }
- *mctx = le32_to_cpup((__le32 *)key);
- return 0;
-}
-
-static int crc32_init(struct shash_desc *desc)
-{
- u32 *mctx = crypto_shash_ctx(desc->tfm);
- u32 *crcp = shash_desc_ctx(desc);
-
- *crcp = *mctx;
-
- return 0;
-}
-
-static int crc32_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
-{
- u32 *crcp = shash_desc_ctx(desc);
-
- *crcp = __crc32_le(*crcp, data, len);
- return 0;
-}
-/* No final XOR 0xFFFFFFFF, like crc32_le */
-static int __crc32_finup(u32 *crcp, const u8 *data, unsigned int len,
- u8 *out)
-{
- *(__le32 *)out = cpu_to_le32(__crc32_le(*crcp, data, len));
- return 0;
-}
-
-static int crc32_finup(struct shash_desc *desc, const u8 *data,
- unsigned int len, u8 *out)
-{
- return __crc32_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32_final(struct shash_desc *desc, u8 *out)
-{
- u32 *crcp = shash_desc_ctx(desc);
-
- *(__le32 *)out = cpu_to_le32p(crcp);
- return 0;
-}
-
-static int crc32_digest(struct shash_desc *desc, const u8 *data,
- unsigned int len, u8 *out)
-{
- return __crc32_finup(crypto_shash_ctx(desc->tfm), data, len,
- out);
-}
-static struct shash_alg alg = {
- .setkey = crc32_setkey,
- .init = crc32_init,
- .update = crc32_update,
- .final = crc32_final,
- .finup = crc32_finup,
- .digest = crc32_digest,
- .descsize = sizeof(u32),
- .digestsize = CHKSUM_DIGEST_SIZE,
- .base = {
- .cra_name = "crc32",
- .cra_driver_name = "crc32-table",
- .cra_priority = 100,
- .cra_blocksize = CHKSUM_BLOCK_SIZE,
- .cra_ctxsize = sizeof(u32),
- .cra_module = THIS_MODULE,
- .cra_init = crc32_cra_init,
- }
-};
-#else /* HAVE_STRUCT_SHASH_ALG */
-#ifdef HAVE_DIGEST_SETKEY_FLAGS
-static int crc32_digest_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen, unsigned int *flags)
-#else
-static int crc32_digest_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen)
-#endif
-{
- u32 *mctx = crypto_tfm_ctx(tfm);
-
- if (keylen != sizeof(u32)) {
- tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
- return -EINVAL;
- }
- *mctx = le32_to_cpup((__le32 *)key);
- return 0;
-}
-
-static void crc32_digest_init(struct crypto_tfm *tfm)
-{
- u32 *mctx = crypto_tfm_ctx(tfm);
-
- *mctx = 0;
-
-}
-static void crc32_digest_update(struct crypto_tfm *tfm, const u8 *data,
- unsigned int len)
-{
- u32 *crcp = crypto_tfm_ctx(tfm);
-
- *crcp = __crc32_le(*crcp, data, len);
-}
-
-static void crc32_digest_final(struct crypto_tfm *tfm, u8 *out)
-{
- u32 *crcp = crypto_tfm_ctx(tfm);
-
- *(__le32 *)out = cpu_to_le32p(crcp);
-}
-
-static struct crypto_alg alg = {
- .cra_name = "crc32",
- .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
- .cra_driver_name = "crc32-table",
- .cra_priority = 100,
- .cra_blocksize = CHKSUM_BLOCK_SIZE,
- .cra_ctxsize = sizeof(u32),
- .cra_module = THIS_MODULE,
- .cra_init = crc32_cra_init,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
- .cra_u = {
- .digest = {
- .dia_digestsize = CHKSUM_DIGEST_SIZE,
- .dia_setkey = crc32_digest_setkey,
- .dia_init = crc32_digest_init,
- .dia_update = crc32_digest_update,
- .dia_final = crc32_digest_final
- }
- }
-};
-#endif /* HAVE_STRUCT_SHASH_ALG */
-
-int cfs_crypto_crc32_register(void)
-{
-#ifdef HAVE_STRUCT_SHASH_ALG
- return crypto_register_shash(&alg);
-#else
- return crypto_register_alg(&alg);
-#endif
-}
-EXPORT_SYMBOL(cfs_crypto_crc32_register);
-
-void cfs_crypto_crc32_unregister(void)
-{
-#ifdef HAVE_STRUCT_SHASH_ALG
- crypto_unregister_shash(&alg);
-#else
- crypto_unregister_alg(&alg);
-#endif
-}
-EXPORT_SYMBOL(cfs_crypto_crc32_unregister);
+++ /dev/null
-/* GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
-/*
- * Copyright 2012 Xyratex Technology Limited
- */
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <libcfs/libcfs.h>
-#include <libcfs/linux/linux-crypto.h>
-/**
- * Array of hash algorithm speed in MByte per second
- */
-static int cfs_crypto_hash_speeds[CFS_HASH_ALG_MAX];
-
-
-#ifndef HAVE_STRUCT_HASH_DESC
-/** 2.6.18 kernel have no crypto_hash function
- * this part was copied from lustre_compat25.h */
-#define crypto_hash crypto_tfm
-struct hash_desc {
- struct crypto_hash *tfm;
- unsigned int flags;
-};
-
-static inline
-struct crypto_hash *crypto_alloc_hash(const char *alg, unsigned int type,
- unsigned int mask)
-{
- return crypto_alloc_tfm(alg, 0);
-}
-
-static inline void crypto_free_hash(struct crypto_hash *tfm)
-{
- crypto_free_tfm(tfm);
-}
-
-static inline int crypto_hash_init(struct hash_desc *desc)
-{
- crypto_digest_init(desc->tfm);
- return 0;
-}
-
-static inline int crypto_hash_update(struct hash_desc *desc,
- struct scatterlist *sg,
- unsigned int nbytes)
-{
- if (desc->tfm->crt_digest.dit_update == NULL)
- return -1;
-
- LASSERT(nbytes == sg->length);
- crypto_digest_update(desc->tfm, sg, 1);
-
- return 0;
-}
-
-static inline int crypto_hash_digest(struct hash_desc *desc,
- struct scatterlist *sg,
- unsigned int nbytes, unsigned char *out)
-{
- crypto_hash_update(desc, sg, nbytes);
- crypto_digest_final(desc->tfm, out);
- return 0;
-}
-
-static inline int crypto_hash_final(struct hash_desc *desc, unsigned char *out)
-{
- crypto_digest_final(desc->tfm, out);
- return 0;
-}
-
-static inline struct crypto_tfm *crypto_hash_tfm(struct crypto_hash *tfm)
-{
- return tfm;
-}
-
-#define crypto_hash_setkey(tfm, key, keylen) \
- crypto_digest_setkey(tfm, key, keylen)
-#define crypto_hash_digestsize(tfm) crypto_tfm_alg_digestsize(tfm)
-#define crypto_hash_blocksize(tfm) crypto_tfm_alg_blocksize(tfm)
-#endif
-
-static int cfs_crypto_hash_alloc(unsigned char alg_id,
- const struct cfs_crypto_hash_type **type,
- struct hash_desc *desc, unsigned char *key,
- unsigned int key_len)
-{
- int err = 0;
-
- *type = cfs_crypto_hash_type(alg_id);
-
- if (*type == NULL) {
- CWARN("Unsupported hash algorithm id = %d, max id is %d\n",
- alg_id, CFS_HASH_ALG_MAX);
- return -EINVAL;
- }
- desc->tfm = crypto_alloc_hash((*type)->cht_name, 0, 0);
-
- if (desc->tfm == NULL)
- return -EINVAL;
-
- if (IS_ERR(desc->tfm)) {
- CDEBUG(D_INFO, "Failed to alloc crypto hash %s\n",
- (*type)->cht_name);
- return PTR_ERR(desc->tfm);
- }
-
- desc->flags = 0;
-
- /** Shash have different logic for initialization then digest
- * shash: crypto_hash_setkey, crypto_hash_init
- * digest: crypto_digest_init, crypto_digest_setkey
- * Skip this function for digest, because we use shash logic at
- * cfs_crypto_hash_alloc.
- */
-#ifndef HAVE_STRUCT_SHASH_ALG
- crypto_hash_init(desc);
-#endif
- if (key != NULL) {
- err = crypto_hash_setkey(desc->tfm, key, key_len);
- } else if ((*type)->cht_key != 0) {
- err = crypto_hash_setkey(desc->tfm,
- (unsigned char *)&((*type)->cht_key),
- (*type)->cht_size);
- }
-
- if (err != 0) {
- crypto_free_hash(desc->tfm);
- return err;
- }
-
- CDEBUG(D_INFO, "Using crypto hash: %s (%s) speed %d MB/s\n",
- crypto_tfm_alg_name(crypto_hash_tfm(desc->tfm)),
- crypto_tfm_alg_driver_name(crypto_hash_tfm(desc->tfm)),
- cfs_crypto_hash_speeds[alg_id]);
-
-#ifdef HAVE_STRUCT_SHASH_ALG
- return crypto_hash_init(desc);
-#else
- return 0;
-#endif
-}
-
-int cfs_crypto_hash_digest(unsigned char alg_id,
- const void *buf, unsigned int buf_len,
- unsigned char *key, unsigned int key_len,
- unsigned char *hash, unsigned int *hash_len)
-{
- struct scatterlist sl = {0};
- struct hash_desc hdesc;
- int err;
- const struct cfs_crypto_hash_type *type;
-
- if (buf == NULL || buf_len == 0 || hash_len == NULL)
- return -EINVAL;
-
- err = cfs_crypto_hash_alloc(alg_id, &type, &hdesc, key, key_len);
- if (err != 0)
- return err;
-
- if (hash == NULL || *hash_len < type->cht_size) {
- *hash_len = type->cht_size;
- crypto_free_hash(hdesc.tfm);
- return -ENOSPC;
- }
- sg_set_buf(&sl, (void *)buf, buf_len);
-
- hdesc.flags = 0;
- err = crypto_hash_digest(&hdesc, &sl, sl.length, hash);
- crypto_free_hash(hdesc.tfm);
-
- return err;
-}
-EXPORT_SYMBOL(cfs_crypto_hash_digest);
-
-struct cfs_crypto_hash_desc *
- cfs_crypto_hash_init(unsigned char alg_id,
- unsigned char *key, unsigned int key_len)
-{
-
- struct hash_desc *hdesc;
- int err;
- const struct cfs_crypto_hash_type *type;
-
- hdesc = cfs_alloc(sizeof(*hdesc), 0);
- if (hdesc == NULL)
- return ERR_PTR(-ENOMEM);
-
- err = cfs_crypto_hash_alloc(alg_id, &type, hdesc, key, key_len);
-
- if (err) {
- cfs_free(hdesc);
- return ERR_PTR(err);
- }
- return (struct cfs_crypto_hash_desc *)hdesc;
-}
-EXPORT_SYMBOL(cfs_crypto_hash_init);
-
-int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *hdesc,
- cfs_page_t *page, unsigned int offset,
- unsigned int len)
-{
- struct scatterlist sl = {0};
-
- sg_set_page(&sl, page, len, offset & ~CFS_PAGE_MASK);
-
- return crypto_hash_update((struct hash_desc *)hdesc, &sl, sl.length);
-}
-EXPORT_SYMBOL(cfs_crypto_hash_update_page);
-
-int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *hdesc,
- const void *buf, unsigned int buf_len)
-{
- struct scatterlist sl = {0};
-
- sg_set_buf(&sl, (void *)buf, buf_len);
-
- return crypto_hash_update((struct hash_desc *)hdesc, &sl, sl.length);
-}
-EXPORT_SYMBOL(cfs_crypto_hash_update);
-
-/* If hash_len pointer is NULL - destroy descriptor. */
-int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc,
- unsigned char *hash, unsigned int *hash_len)
-{
- int err;
- int size = crypto_hash_digestsize(((struct hash_desc *)hdesc)->tfm);
-
- if (hash_len == NULL) {
- crypto_free_hash(((struct hash_desc *)hdesc)->tfm);
- return 0;
- }
- if (hash == NULL || *hash_len < size) {
- *hash_len = size;
- return -ENOSPC;
- }
- err = crypto_hash_final((struct hash_desc *) hdesc, hash);
-
- if (err < 0) {
- /* May be caller can fix error */
- return err;
- }
- crypto_free_hash(((struct hash_desc *)hdesc)->tfm);
- return err;
-}
-EXPORT_SYMBOL(cfs_crypto_hash_final);
-
-static void cfs_crypto_performance_test(unsigned char alg_id,
- const unsigned char *buf,
- unsigned int buf_len)
-{
- unsigned long start, end;
- int bcount, err = 0;
- int sec = 1; /* do test only 1 sec */
- unsigned char hash[64];
- unsigned int hash_len = 64;
-
- for (start = jiffies, end = start + sec * HZ, bcount = 0;
- time_before(jiffies, end); bcount++) {
- err = cfs_crypto_hash_digest(alg_id, buf, buf_len, NULL, 0,
- hash, &hash_len);
- if (err)
- break;
-
- }
- end = jiffies;
-
- if (err) {
- cfs_crypto_hash_speeds[alg_id] = -1;
- CDEBUG(D_INFO, "Crypto hash algorithm %s, err = %d\n",
- cfs_crypto_hash_name(alg_id), err);
- } else {
- unsigned long tmp;
- tmp = ((bcount * buf_len / jiffies_to_msecs(end - start)) *
- 1000) / (1024 * 1024);
- cfs_crypto_hash_speeds[alg_id] = (int)tmp;
- }
- CDEBUG(D_INFO, "Crypto hash algorithm %s speed = %d MB/s\n",
- cfs_crypto_hash_name(alg_id), cfs_crypto_hash_speeds[alg_id]);
-}
-
-int cfs_crypto_hash_speed(unsigned char hash_alg)
-{
- if (hash_alg < CFS_HASH_ALG_MAX)
- return cfs_crypto_hash_speeds[hash_alg];
- else
- return -1;
-}
-EXPORT_SYMBOL(cfs_crypto_hash_speed);
-
-/**
- * Do performance test for all hash algorithms.
- */
-static int cfs_crypto_test_hashes(void)
-{
- unsigned char i;
- unsigned char *data;
- unsigned int j;
- /* Data block size for testing hash. Maximum
- * kmalloc size for 2.6.18 kernel is 128K */
- unsigned int data_len = 1 * 128 * 1024;
-
- data = cfs_alloc(data_len, 0);
- if (data == NULL) {
- CERROR("Failed to allocate mem\n");
- return -ENOMEM;
- }
-
- for (j = 0; j < data_len; j++)
- data[j] = j & 0xff;
-
- for (i = 0; i < CFS_HASH_ALG_MAX; i++)
- cfs_crypto_performance_test(i, data, data_len);
-
- cfs_free(data);
- return 0;
-}
-
-static int crc32, adler32;
-
-int cfs_crypto_register(void)
-{
- crc32 = cfs_crypto_crc32_register();
- adler32 = cfs_crypto_adler32_register();
-
- /* check all algorithms and do perfermance test */
- cfs_crypto_test_hashes();
- return 0;
-}
-void cfs_crypto_unregister(void)
-{
- if (crc32 == 0)
- cfs_crypto_crc32_unregister();
- if (adler32 == 0)
- cfs_crypto_adler32_unregister();
- return;
-}
#define DEBUG_SUBSYSTEM S_LNET
#include <libcfs/libcfs.h>
-#include <libcfs/libcfs_crypto.h>
#include <lnet/lib-lnet.h>
#include <lnet/lnet.h>
#include "tracefile.h"
static int init_libcfs_module(void)
{
- int rc;
-
- libcfs_arch_init();
- libcfs_init_nidstrings();
- cfs_init_rwsem(&cfs_tracefile_sem);
- cfs_mutex_init(&cfs_trace_thread_mutex);
- cfs_init_rwsem(&ioctl_list_sem);
- CFS_INIT_LIST_HEAD(&ioctl_list);
- cfs_waitq_init(&cfs_race_waitq);
-
- rc = libcfs_debug_init(5 * 1024 * 1024);
- if (rc < 0) {
- printk(CFS_KERN_ERR "LustreError: libcfs_debug_init: %d\n", rc);
- return rc;
- }
+ int rc;
+
+ libcfs_arch_init();
+ libcfs_init_nidstrings();
+ cfs_init_rwsem(&cfs_tracefile_sem);
+ cfs_mutex_init(&cfs_trace_thread_mutex);
+ cfs_init_rwsem(&ioctl_list_sem);
+ CFS_INIT_LIST_HEAD(&ioctl_list);
+ cfs_waitq_init(&cfs_race_waitq);
+
+ rc = libcfs_debug_init(5 * 1024 * 1024);
+ if (rc < 0) {
+ printk(CFS_KERN_ERR "LustreError: libcfs_debug_init: %d\n", rc);
+ return (rc);
+ }
rc = cfs_cpu_init();
if (rc != 0)
goto cleanup_debug;
#if LWT_SUPPORT
- rc = lwt_init();
- if (rc != 0) {
- CERROR("lwt_init: error %d\n", rc);
- goto cleanup_debug;
- }
+ rc = lwt_init();
+ if (rc != 0) {
+ CERROR("lwt_init: error %d\n", rc);
+ goto cleanup_debug;
+ }
#endif
- rc = cfs_psdev_register(&libcfs_dev);
- if (rc) {
- CERROR("misc_register: error %d\n", rc);
- goto cleanup_lwt;
- }
-
- rc = cfs_wi_startup();
- if (rc) {
- CERROR("startup workitem: error %d\n", rc);
- goto cleanup_deregister;
- }
-
- rc = cfs_crypto_register();
- if (rc) {
- CERROR("cfs_crypto_regster: error %d\n", rc);
- goto cleanup_wi;
- }
-
- rc = insert_proc();
- if (rc) {
- CERROR("insert_proc: error %d\n", rc);
- goto cleanup_crypto;
- }
-
- CDEBUG(D_OTHER, "libcfs setup OK\n");
-
- return 0;
- cleanup_crypto:
- cfs_crypto_unregister();
+ rc = cfs_psdev_register(&libcfs_dev);
+ if (rc) {
+ CERROR("misc_register: error %d\n", rc);
+ goto cleanup_lwt;
+ }
+
+ rc = cfs_wi_startup();
+ if (rc) {
+ CERROR("startup workitem: error %d\n", rc);
+ goto cleanup_deregister;
+ }
+
+ rc = insert_proc();
+ if (rc) {
+ CERROR("insert_proc: error %d\n", rc);
+ goto cleanup_wi;
+ }
+
+ CDEBUG (D_OTHER, "portals setup OK\n");
+ return (0);
+
cleanup_wi:
- cfs_wi_shutdown();
+ cfs_wi_shutdown();
cleanup_deregister:
- cfs_psdev_deregister(&libcfs_dev);
+ cfs_psdev_deregister(&libcfs_dev);
cleanup_lwt:
#if LWT_SUPPORT
- lwt_fini();
+ lwt_fini();
#endif
cleanup_debug:
- libcfs_debug_cleanup();
- return rc;
+ libcfs_debug_cleanup();
+ return rc;
}
static void exit_libcfs_module(void)
{
- int rc;
+ int rc;
- remove_proc();
+ remove_proc();
- CDEBUG(D_MALLOC, "before Portals cleanup: kmem %d\n",
- cfs_atomic_read(&libcfs_kmemory));
+ CDEBUG(D_MALLOC, "before Portals cleanup: kmem %d\n",
+ cfs_atomic_read(&libcfs_kmemory));
- cfs_crypto_unregister();
- cfs_wi_shutdown();
- rc = cfs_psdev_deregister(&libcfs_dev);
- if (rc)
- CERROR("misc_deregister error %d\n", rc);
+ cfs_wi_shutdown();
+ rc = cfs_psdev_deregister(&libcfs_dev);
+ if (rc)
+ CERROR("misc_deregister error %d\n", rc);
#if LWT_SUPPORT
- lwt_fini();
+ lwt_fini();
#endif
cfs_cpu_fini();
- if (cfs_atomic_read(&libcfs_kmemory) != 0)
- CERROR("Portals memory leaked: %d bytes\n",
- cfs_atomic_read(&libcfs_kmemory));
+ if (cfs_atomic_read(&libcfs_kmemory) != 0)
+ CERROR("Portals memory leaked: %d bytes\n",
+ cfs_atomic_read(&libcfs_kmemory));
- rc = libcfs_debug_cleanup();
- if (rc)
- printk(CFS_KERN_ERR "LustreError: libcfs_debug_cleanup: %d\n",
- rc);
+ rc = libcfs_debug_cleanup();
+ if (rc)
+ printk(CFS_KERN_ERR "LustreError: libcfs_debug_cleanup: %d\n",
+ rc);
- cfs_fini_rwsem(&ioctl_list_sem);
- cfs_fini_rwsem(&cfs_tracefile_sem);
+ cfs_fini_rwsem(&ioctl_list_sem);
+ cfs_fini_rwsem(&cfs_tracefile_sem);
- libcfs_arch_cleanup();
+ libcfs_arch_cleanup();
}
cfs_module(libcfs, "1.0.0", init_libcfs_module, exit_libcfs_module);
+++ /dev/null
-/* Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-#include <libcfs/libcfs.h>
-
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf, i) {s1 += buf[i]; s2 += s1; }
-#define DO2(buf, i) DO1(buf, i); DO1(buf, i + 1);
-#define DO4(buf, i) DO2(buf, i); DO2(buf, i + 2);
-#define DO8(buf, i) DO4(buf, i); DO4(buf, i + 4);
-#define DO16(buf) DO8(buf, 0); DO8(buf, 8);
-
-/* ========================================================================= */
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-unsigned long zlib_adler32(unsigned long adler,
- const unsigned char *buf,
- unsigned int len)
-{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
-
- if (buf == NULL)
- return 1L;
-
- while (len > 0) {
- k = len < NMAX ? len : NMAX;
- len -= k;
- while (k >= 16) {
- DO16(buf);
- buf += 16;
- k -= 16;
- }
- if (k != 0)
- do {
- s1 += *buf++;
- s2 += s1;
- } while (--k);
- s1 %= BASE;
- s2 %= BASE;
- }
- return (s2 << 16) | s1;
-}
+++ /dev/null
-/*
- * This file contains part of linux kernel implementation of crc32
- * kernel version 2.6.32
- */
-#include <libcfs/libcfs.h>
-#define CRCPOLY_LE 0xedb88320
-#define CRC_LE_BITS 8
-#define LE_TABLE_SIZE (1 << CRC_LE_BITS)
-
-static unsigned int crc32table_le[LE_TABLE_SIZE];
-/**
- * crc32init_le() - allocate and initialize LE table data
- *
- * crc is the crc of the byte i; other entries are filled in based on the
- * fact that crctable[i^j] = crctable[i] ^ crctable[j].
- *
- */
-void crc32init_le(void)
-{
- unsigned i, j;
- unsigned int crc = 1;
-
- crc32table_le[0] = 0;
-
- for (i = 1 << (CRC_LE_BITS - 1); i; i >>= 1) {
- crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
- for (j = 0; j < LE_TABLE_SIZE; j += 2 * i)
- crc32table_le[i + j] = crc ^ crc32table_le[j];
- }
-}
-
-unsigned int crc32_le(unsigned int crc, unsigned char const *p, size_t len)
-{
- const unsigned int *b = (unsigned int *)p;
- const unsigned int *tab = crc32table_le;
-
-# ifdef __LITTLE_ENDIAN
-# define DO_CRC(x) crc = tab[(crc ^ (x)) & 255] ^ (crc>>8)
-# else
-# define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
-# endif
-
- crc = cpu_to_le32(crc);
- /* Align it */
- if (unlikely(((long)b) & 3 && len)) {
- do {
- unsigned char *p = (unsigned char *)b;
- DO_CRC(*p++);
- b = (void *)p;
- } while ((--len) && ((long)b) & 3);
- }
- if (likely(len >= 4)) {
- /* load data 32 bits wide, xor data 32 bits wide. */
- size_t save_len = len & 3;
- len = len >> 2;
- --b; /* use pre increment below(*++b) for speed */
- do {
- crc ^= *++b;
- DO_CRC(0);
- DO_CRC(0);
- DO_CRC(0);
- DO_CRC(0);
- } while (--len);
- b++; /* point to next byte(s) */
- len = save_len;
- }
- /* And the last few bytes */
- if (len) {
- do {
- unsigned char *p = (unsigned char *)b;
- DO_CRC(*p++);
- b = (void *)p;
- } while (--len);
- }
-
- return le32_to_cpu(crc);
-#undef DO_CRC
-}
+++ /dev/null
-/* GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
-/*
- * Copyright 2012 Xyratex Technology Limited
- */
-
-/*
- * Libcfs crypto hash interfaces for user mode.
- */
-
-#include <libcfs/libcfs.h>
-#include <libcfs/posix/posix-crypto.h>
-
-static int cfs_crypto_hash_speeds[CFS_HASH_ALG_MAX];
-
-struct __hash_alg {
- /**
- * Initialization of algorithm
- */
- int (*init)(void);
- /**
- * Start function for the hash instance
- */
- int (*start)(void *ctx, unsigned char *p, unsigned int len);
- /**
- * Partial update checksum
- */
- int (*update)(void *ctx, const unsigned char *p, unsigned int len);
- /**
- * Final function for the instance destroy context and copy digest
- */
- int (*final)(void *ctx, unsigned char *p, unsigned int len);
- /**
- * Destroy algorithm
- */
- void (*fini)(void);
- unsigned int ha_ctx_size; /**< size of context */
- unsigned int ha_priority; /**< implementation priority
- defined by developer
- to get one from equal algorithm */
- unsigned char ha_id; /**< algorithm identifier */
-};
-
-struct hash_desc {
- const struct __hash_alg *hd_hash;
- unsigned char hd_ctx[0];
-};
-
-static int crc32_update_wrapper(void *ctx, const unsigned char *p,
- unsigned int len)
-{
- unsigned int crc = *(unsigned int *)ctx;
-
- crc = crc32_le(crc, p, len);
-
- *(unsigned int *)ctx = crc;
- return 0;
-}
-
-static int adler_wrapper(void *ctx, const unsigned char *p,
- unsigned int len)
-{
- unsigned int cksum = *(unsigned int *)ctx;
-
- cksum = zlib_adler32(cksum, p, len);
-
- *(unsigned int *)ctx = cksum;
- return 0;
-}
-
-static int start_generic(void *ctx, unsigned char *key,
- unsigned int key_len)
-{
- const struct cfs_crypto_hash_type *type;
- struct hash_desc *hd = container_of(ctx, struct hash_desc,
- hd_ctx);
- type = cfs_crypto_hash_type(hd->hd_hash->ha_id);
- LASSERT(type != NULL);
-
- /* copy key to context */
- if (key && key_len == hd->hd_hash->ha_ctx_size) {
- memcpy(ctx, key, key_len);
- } else if (type->cht_key != 0) {
- memcpy(ctx, &type->cht_key, type->cht_size);
- } else {
- CWARN("Invalid key or key_len, zero context\n");
- memset(ctx, 0, hd->hd_hash->ha_ctx_size);
- }
- return 0;
-}
-
-static int final_generic(void *ctx, unsigned char *hash,
- unsigned int hash_len)
-{
- const struct cfs_crypto_hash_type *type;
- struct hash_desc *hd = container_of(ctx, struct hash_desc,
- hd_ctx);
- type = cfs_crypto_hash_type(hd->hd_hash->ha_id);
- LASSERT(type != NULL);
- /* copy context to out hash */
- LASSERT(hd->hd_hash->ha_ctx_size == type->cht_size);
- memcpy(hash, ctx, hd->hd_hash->ha_ctx_size);
-
-
- return 0;
-}
-
-static struct __hash_alg crypto_hash[] = {
- {.ha_id = CFS_HASH_ALG_CRC32,
- .ha_ctx_size = sizeof(unsigned int),
- .ha_priority = 10,
- .init = crc32init_le,
- .update = crc32_update_wrapper,
- .start = start_generic,
- .final = final_generic,
- .fini = NULL},
- {.ha_id = CFS_HASH_ALG_ADLER32,
- .ha_ctx_size = sizeof(unsigned int),
- .ha_priority = 10,
- .init = NULL,
- .update = adler_wrapper,
- .start = start_generic,
- .final = final_generic,
- .fini = NULL} };
-
-/**
- * Go through hashes to find the hash with max priority
- * for the alg_id algorithm. This is done for different implementation
- * of the same algorithm. Priotity is staticaly defined by developer, and
- * can be zeroed if initialization of algo is unsuccessfull.
- */
-static const struct __hash_alg *cfs_crypto_hash_best_alg(unsigned char alg_id)
-{
- int max_priority = 0;
- const struct __hash_alg *alg = NULL;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(crypto_hash); i++) {
- if (alg_id == crypto_hash[i].ha_id &&
- max_priority < crypto_hash[i].ha_priority) {
- max_priority = crypto_hash[i].ha_priority;
- alg = &crypto_hash[i];
- }
- }
-
- return alg;
-}
-
-struct cfs_crypto_hash_desc
- *cfs_crypto_hash_init(unsigned char alg,
- unsigned char *key, unsigned int key_len)
-{
- struct hash_desc *hdesc = NULL;
- const struct cfs_crypto_hash_type *type;
- const struct __hash_alg *ha = NULL;
- int err;
-
- type = cfs_crypto_hash_type(alg);
- if (type == NULL) {
- CWARN("Unsupported hash algorithm id = %d, max id is %d\n",
- alg, CFS_HASH_ALG_MAX);
- return ERR_PTR(-EINVAL);
- }
-
- ha = cfs_crypto_hash_best_alg(alg);
- if (ha == NULL) {
- CERROR("Failed to get hash algorithm\n");
- return ERR_PTR(-ENODEV);
- }
-
- hdesc = cfs_alloc(sizeof(*hdesc) + ha->ha_ctx_size, 0);
- if (hdesc == NULL)
- return ERR_PTR(-ENOMEM);
-
- hdesc->hd_hash = ha;
-
- if (ha->start != NULL) {
- err = ha->start(hdesc->hd_ctx, key, key_len);
- if (err == 0) {
- return (struct cfs_crypto_hash_desc *) hdesc;
- } else {
- cfs_free(hdesc);
- return ERR_PTR(err);
- }
- }
-
- return (struct cfs_crypto_hash_desc *) hdesc;
-}
-
-int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
- unsigned int buf_len)
-{
- struct hash_desc *d = (struct hash_desc *)desc;
- return d->hd_hash->update(d->hd_ctx, buf, buf_len);
-}
-
-int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
- cfs_page_t *page, unsigned int offset,
- unsigned int len)
-{
- const void *p = page->addr + offset;
-
- return cfs_crypto_hash_update(desc, p, len);
-}
-
-/**
- * To get final hash and destroy cfs_crypto_hash_desc, caller
- * should use valid hash buffer with enougth len for hash.
- * If hash_len pointer is NULL - destroy descriptor.
- */
-int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
- unsigned char *hash, unsigned int *hash_len)
-{
- struct hash_desc *d = (struct hash_desc *)desc;
- int size = (cfs_crypto_hash_type(d->hd_hash->ha_id))->cht_size;
- int err;
-
- if (hash_len == NULL) {
- cfs_free(d);
- return 0;
- }
- if (hash == NULL || *hash_len < size) {
- *hash_len = d->hd_hash->ha_ctx_size;
- return -ENOMEM;
- }
-
- LASSERT(d->hd_hash->final != NULL);
- err = d->hd_hash->final(d->hd_ctx, hash, *hash_len);
- if (err == 0) {
- /* If get final digest success free hash descriptor */
- cfs_free(d);
- }
-
- return err;
-}
-
-int cfs_crypto_hash_digest(unsigned char alg,
- const void *buf, unsigned int buf_len,
- unsigned char *key, unsigned int key_len,
- unsigned char *hash, unsigned int *hash_len)
-{
- struct cfs_crypto_hash_desc *desc;
- int err;
-
- desc = cfs_crypto_hash_init(alg, key, key_len);
-
- if (IS_ERR(desc))
- return PTR_ERR(desc);
-
- err = cfs_crypto_hash_update(desc, buf, buf_len);
- if (err) {
- cfs_crypto_hash_final(desc, NULL, NULL);
- return err;
- }
- err = cfs_crypto_hash_final(desc, hash, hash_len);
- if (err != 0)
- cfs_crypto_hash_final(desc, NULL, NULL);
- return err;
-}
-
-
-static void cfs_crypto_start_timer(struct timeval *start)
-{
- gettimeofday(start, NULL);
- return;
-}
-
-/** return usec */
-static long cfs_crypto_get_sec(struct timeval *start)
-{
- struct timeval end;
-
- gettimeofday(&end, NULL);
-
- return cfs_timeval_sub(&end, start, NULL);
-}
-
-static void cfs_crypto_performance_test(unsigned char alg_id,
- const unsigned char *buf,
- unsigned int buf_len)
-{
- struct timeval start;
- int bcount, err, msec;
- int iteration = 400; /* do test 400 times */
- unsigned char hash[64];
- unsigned int hash_len = 64;
-
- cfs_crypto_start_timer(&start);
- for (bcount = 0; bcount < iteration; bcount++) {
- err = cfs_crypto_hash_digest(alg_id, buf, buf_len, NULL, 0,
- hash, &hash_len);
- if (err)
- break;
-
- }
-
- msec = (int)(cfs_crypto_get_sec(&start) / 1000.0);
- if (err) {
- cfs_crypto_hash_speeds[alg_id] = -1;
- CDEBUG(D_INFO, "Crypto hash algorithm err = %d\n", err);
- } else {
- long tmp;
- tmp = ((bcount * buf_len / msec) * 1000) / (1024 * 1024);
- cfs_crypto_hash_speeds[alg_id] = (int)tmp;
- }
- CDEBUG(D_INFO, "Crypto hash algorithm %s speed = %d MB/s\n",
- cfs_crypto_hash_name(alg_id), cfs_crypto_hash_speeds[alg_id]);
-}
-
-int cfs_crypto_hash_speed(unsigned char hash_alg)
-{
- if (hash_alg < CFS_HASH_ALG_MAX)
- return cfs_crypto_hash_speeds[hash_alg];
- else
- return -1;
-}
-
-/**
- * Do performance test for all hash algorithms.
- */
-static int cfs_crypto_test_hashes(void)
-{
- unsigned char i;
- unsigned char *data;
- unsigned int j, data_len = 1024 * 1024;
-
- data = cfs_alloc(data_len, 0);
- if (data == NULL) {
- CERROR("Failed to allocate mem\n");
- return -ENOMEM;
- }
- for (j = 0; j < data_len; j++)
- data[j] = j & 0xff;
-
- for (i = 0; i < CFS_HASH_ALG_MAX; i++)
- cfs_crypto_performance_test(i, data, data_len);
-
- cfs_free(data);
- return 0;
-}
-
-/**
- * Register crypto hash algorithms
- */
-int cfs_crypto_register(void)
-{
- int i, err;
- for (i = 0; i < ARRAY_SIZE(crypto_hash); i++) {
- if (crypto_hash[i].init == NULL)
- continue;
- err = crypto_hash[i].init();
- if (err < 0) {
- crypto_hash[i].ha_priority = 0;
- CWARN("Failed to initialize hash %s, error %d\n",
- cfs_crypto_hash_name(crypto_hash[i].ha_id), err);
- }
- }
-
- cfs_crypto_test_hashes();
- return 0;
-}
-
-/**
- * Unregister
- */
-void cfs_crypto_unregister(void)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(crypto_hash); i++) {
- if (crypto_hash[i].fini == NULL)
- continue;
- if (crypto_hash[i].ha_priority > 0)
- crypto_hash[i].fini();
- }
-}
endif
EXTRA_DIST = lprocfs_status.h lustre_acl.h lustre_debug.h lustre_lib.h \
- lustre_dlm.h lustre_handles.h lustre_net.h obd_class.h obd_support.h \
- lustre_log.h lustre_compat25.h lustre_fsfilt.h lustre_mds.h \
- obd.h lvfs.h lvfs_linux.h lustre_lite.h lustre_quota.h \
- lustre_user.h lustre_patchless_compat.h lustre_intent.h
+ lustre_dlm.h lustre_handles.h lustre_net.h obd_class.h obd_support.h \
+ lustre_log.h lustre_compat25.h lustre_fsfilt.h lustre_mds.h \
+ obd.h lvfs.h lvfs_linux.h lustre_lite.h lustre_quota.h \
+ lustre_user.h lustre_patchless_compat.h lustre_intent.h \
+ obd_cksum.h
--- /dev/null
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Whamcloud, Inc.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LINUX_OBD_CKSUM
+#define __LINUX_OBD_CKSUM
+
+#ifndef __OBD_CKSUM
+#error Do not #include this file directly. #include <obd_chsum.h> instead
+#endif
+
+#include <libcfs/libcfs.h>
+
+/* Prefer the kernel's version, if it exports it, because it might be
+ * optimized for this CPU. */
+#if defined(__KERNEL__) && (defined(CONFIG_CRC32) || defined(CONFIG_CRC32_MODULE))
+# include <linux/crc32.h>
+# define HAVE_ARCH_CRC32
+#endif
+
+#ifdef __KERNEL__
+# include <linux/zutil.h>
+# ifndef HAVE_ADLER
+# define HAVE_ADLER
+# endif
+# define adler32(a,b,l) zlib_adler32(a,b,l)
+#else /* __KERNEL__ */
+# ifdef HAVE_ADLER
+# include <zlib.h>
+# endif
+#endif /*! __KERNEL__ */
+
+#endif
BULK_HASH_ALG_MAX
};
+struct sptlrpc_hash_type {
+ char *sht_name;
+ char *sht_tfm_name;
+ unsigned int sht_size;
+};
+
+const struct sptlrpc_hash_type *sptlrpc_get_hash_type(__u8 hash_alg);
const char * sptlrpc_get_hash_name(__u8 hash_alg);
__u8 sptlrpc_get_hash_alg(const char *algname);
#ifndef __OBD_CKSUM
#define __OBD_CKSUM
-#include <libcfs/libcfs.h>
+
+#if defined(__linux__)
+#include <linux/obd_cksum.h>
+#elif defined(__APPLE__)
+#include <darwin/obd_chksum.h>
+#elif defined(__WINNT__)
+#include <winnt/obd_cksum.h>
+#else
+#error Unsupported operating system.
+#endif
+
#include <lustre/lustre_idl.h>
-static inline unsigned char cksum_obd2cfs(cksum_type_t cksum_type)
+/*
+ * Checksums
+ */
+
+#ifndef HAVE_ARCH_CRC32
+/* crc32_le lifted from the Linux kernel, which had the following to say:
+ *
+ * This code is in the public domain; copyright abandoned.
+ * Liability for non-performance of this code is limited to the amount
+ * you paid for it. Since it is distributed for free, your refund will
+ * be very very small. If it breaks, you get to keep both pieces.
+ */
+#define CRCPOLY_LE 0xedb88320
+/**
+ * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
+ * \param crc seed value for computation. ~0 for Ethernet, sometimes 0 for
+ * other uses, or the previous crc32 value if computing incrementally.
+ * \param p - pointer to buffer over which CRC is run
+ * \param len- length of buffer \a p
+ */
+static inline __u32 crc32_le(__u32 crc, unsigned char const *p, size_t len)
+{
+ int i;
+ while (len--) {
+ crc ^= *p++;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+ }
+ return crc;
+}
+#endif
+
+#ifdef HAVE_ADLER
+/* Adler-32 is supported */
+#define CHECKSUM_ADLER OBD_CKSUM_ADLER
+#else
+#define CHECKSUM_ADLER 0
+#endif
+
+#ifdef X86_FEATURE_XMM4_2
+/* Call Nehalem+ CRC32C harware acceleration instruction on individual bytes. */
+static inline __u32 crc32c_hw_byte(__u32 crc, unsigned char const *p,
+ size_t bytes)
{
- switch (cksum_type) {
- case OBD_CKSUM_CRC32:
- return CFS_HASH_ALG_CRC32;
- case OBD_CKSUM_ADLER:
- return CFS_HASH_ALG_ADLER32;
- case OBD_CKSUM_CRC32C:
- return CFS_HASH_ALG_CRC32C;
- default:
- CERROR("Unknown checksum type (%x)!!!\n", cksum_type);
- LBUG();
- }
- return 0;
+ while (bytes--) {
+ __asm__ __volatile__ (
+ ".byte 0xf2, 0xf, 0x38, 0xf0, 0xf1"
+ : "=S"(crc)
+ : "0"(crc), "c"(*p)
+ );
+ p++;
+ }
+
+ return crc;
+}
+
+#if BITS_PER_LONG > 32
+#define WORD_SHIFT 3
+#define WORD_MASK 7
+#define REX "0x48, "
+#else
+#define WORD_SHIFT 2
+#define WORD_MASK 3
+#define REX ""
+#endif
+
+/* Do we need to worry about unaligned input data here? */
+static inline __u32 crc32c_hw(__u32 crc, unsigned char const *p, size_t len)
+{
+ unsigned int words = len >> WORD_SHIFT;
+ unsigned int bytes = len & WORD_MASK;
+ long *ptmp = (long *)p;
+
+ while (words--) {
+ __asm__ __volatile__(
+ ".byte 0xf2, " REX "0xf, 0x38, 0xf1, 0xf1;"
+ : "=S"(crc)
+ : "0"(crc), "c"(*ptmp)
+ );
+ ptmp++;
+ }
+
+ if (bytes)
+ crc = crc32c_hw_byte(crc, (unsigned char *)ptmp, bytes);
+
+ return crc;
+}
+#else
+/* We should never call this unless the CPU has previously been detected to
+ * support this instruction in the SSE4.2 feature set. b=23549 */
+static inline __u32 crc32c_hw(__u32 crc, unsigned char const *p,size_t len)
+{
+ LBUG();
+}
+#endif
+
+static inline __u32 init_checksum(cksum_type_t cksum_type)
+{
+ switch(cksum_type) {
+ case OBD_CKSUM_CRC32C:
+ return ~0U;
+#ifdef HAVE_ADLER
+ case OBD_CKSUM_ADLER:
+ return 1U;
+#endif
+ case OBD_CKSUM_CRC32:
+ return ~0U;
+ default:
+ CERROR("Unknown checksum type (%x)!!!\n", cksum_type);
+ LBUG();
+ }
+ return 0;
+}
+
+static inline __u32 fini_checksum(__u32 cksum, cksum_type_t cksum_type)
+{
+ if (cksum_type == OBD_CKSUM_CRC32C)
+ return ~cksum;
+ return cksum;
+}
+
+static inline __u32 compute_checksum(__u32 cksum, unsigned char const *p,
+ size_t len, cksum_type_t cksum_type)
+{
+ switch(cksum_type) {
+ case OBD_CKSUM_CRC32C:
+ return crc32c_hw(cksum, p, len);
+#ifdef HAVE_ADLER
+ case OBD_CKSUM_ADLER:
+ return adler32(cksum, p, len);
+#endif
+ case OBD_CKSUM_CRC32:
+ return crc32_le(cksum, p, len);
+ default:
+ CERROR("Unknown checksum type (%x)!!!\n", cksum_type);
+ LBUG();
+ }
+ return 0;
}
/* The OBD_FL_CKSUM_* flags is packed into 5 bits of o_flags, since there can
* since they need to represent the full range of checksum algorithms that
* both the client and server can understand.
*
- * In case of an unsupported types/flags we fall back to ADLER
- * because that is supported by all clients since 1.8
+ * In case of an unsupported types/flags we fall back to CRC32 (even though
+ * it isn't very fast) because that is supported by all clients
+ * checksums, since 1.6.5 (or earlier via patches).
*
- * In case multiple algorithms are supported the best one is used. */
+ * These flags should be listed in order of descending performance, so that
+ * in case multiple algorithms are supported the best one is used. */
static inline obd_flag cksum_type_pack(cksum_type_t cksum_type)
{
- unsigned int performance = 0, tmp;
- obd_flag flag = OBD_FL_CKSUM_ADLER;
-
- if (cksum_type & OBD_CKSUM_CRC32) {
- tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32));
- if (tmp > performance) {
- performance = tmp;
- flag = OBD_FL_CKSUM_CRC32;
- }
- }
- if (cksum_type & OBD_CKSUM_CRC32C) {
- tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C));
- if (tmp > performance) {
- performance = tmp;
- flag = OBD_FL_CKSUM_CRC32C;
- }
- }
- if (cksum_type & OBD_CKSUM_ADLER) {
- tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER));
- if (tmp > performance) {
- performance = tmp;
- flag = OBD_FL_CKSUM_ADLER;
- }
- }
- if (unlikely(cksum_type && !(cksum_type & (OBD_CKSUM_CRC32C |
- OBD_CKSUM_CRC32 |
- OBD_CKSUM_ADLER))))
- CWARN("unknown cksum type %x\n", cksum_type);
-
- return flag;
-}
+ if (cksum_type & OBD_CKSUM_CRC32C)
+ return OBD_FL_CKSUM_CRC32C;
+#ifdef HAVE_ADLER
+ if (cksum_type & OBD_CKSUM_ADLER)
+ return OBD_FL_CKSUM_ADLER;
+#endif
+ if (unlikely(cksum_type && !(cksum_type & OBD_CKSUM_CRC32)))
+ CWARN("unknown cksum type %x\n", cksum_type);
-static inline cksum_type_t cksum_type_unpack(obd_flag o_flags)
-{
- switch (o_flags & OBD_FL_CKSUM_ALL) {
- case OBD_FL_CKSUM_CRC32C:
- return OBD_CKSUM_CRC32C;
- case OBD_FL_CKSUM_CRC32:
- return OBD_CKSUM_CRC32;
- default:
- break;
- }
-
- return OBD_CKSUM_ADLER;
+ return OBD_FL_CKSUM_CRC32;
}
-/* Return a bitmask of the checksum types supported on this system.
- * 1.8 supported ADLER it is base and not depend on hw
- * Client uses all available local algos
- */
-static inline cksum_type_t cksum_types_supported_client(void)
+static inline cksum_type_t cksum_type_unpack(obd_flag o_flags)
{
- cksum_type_t ret = OBD_CKSUM_ADLER;
-
- CDEBUG(D_INFO, "Crypto hash speed: crc %d, crc32c %d, adler %d\n",
- cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)),
- cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)),
- cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER)));
+ switch (o_flags & OBD_FL_CKSUM_ALL) {
+ case OBD_FL_CKSUM_CRC32C:
+ return OBD_CKSUM_CRC32C;
+ case OBD_FL_CKSUM_ADLER:
+#ifdef HAVE_ADLER
+ return OBD_CKSUM_ADLER;
+#else
+ CWARN("checksum type is set to adler32, but adler32 is not "
+ "supported (%x)\n", o_flags);
+ break;
+#endif
+ default:
+ break;
+ }
- if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)) > 0)
- ret |= OBD_CKSUM_CRC32C;
- if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)) > 0)
- ret |= OBD_CKSUM_CRC32;
-
- return ret;
+ /* 1.6.4- only supported CRC32 and didn't set o_flags */
+ return OBD_CKSUM_CRC32;
}
-/* Server uses algos that perform at 50% or better of the Adler */
-static inline cksum_type_t cksum_types_supported_server(void)
+/* Return a bitmask of the checksum types supported on this system.
+ *
+ * CRC32 is a required for compatibility (starting with 1.6.5),
+ * after which we could move to Adler as the base checksum type.
+ *
+ * If hardware crc32c support is not available, it is slower than Adler,
+ * so don't include it, even if it could be emulated in software. b=23549 */
+static inline cksum_type_t cksum_types_supported(void)
{
- int base_speed;
- cksum_type_t ret = OBD_CKSUM_ADLER;
-
- CDEBUG(D_INFO, "Crypto hash speed: crc %d, crc32c %d, adler %d\n",
- cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)),
- cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)),
- cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER)));
-
- base_speed = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER)) / 2;
+ cksum_type_t ret = OBD_CKSUM_CRC32;
- if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)) >=
- base_speed)
- ret |= OBD_CKSUM_CRC32C;
- if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)) >=
- base_speed)
- ret |= OBD_CKSUM_CRC32;
-
- return ret;
+#ifdef X86_FEATURE_XMM4_2
+ if (cpu_has_xmm4_2)
+ ret |= OBD_CKSUM_CRC32C;
+#endif
+#ifdef HAVE_ADLER
+ ret |= OBD_CKSUM_ADLER;
+#endif
+ return ret;
}
-
/* Select the best checksum algorithm among those supplied in the cksum_types
* input.
*
* Currently, calling cksum_type_pack() with a mask will return the fastest
- * checksum type due to its benchmarking at libcfs module load.
+ * checksum type due to its ordering, but in the future we might want to
+ * determine this based on benchmarking the different algorithms quickly.
* Caution is advised, however, since what is fastest on a single client may
* not be the fastest or most efficient algorithm on the server. */
static inline cksum_type_t cksum_type_select(cksum_type_t cksum_types)
{
- return cksum_type_unpack(cksum_type_pack(cksum_types));
+ return cksum_type_unpack(cksum_type_pack(cksum_types));
}
/* Checksum algorithm names. Must be defined in the same order as the
* agreement on the supported algorithms at connect time */
data->ocd_connect_flags |= OBD_CONNECT_CKSUM;
- if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CKSUM_ADLER_ONLY))
- data->ocd_cksum_types = OBD_CKSUM_ADLER;
- else
- data->ocd_cksum_types = cksum_types_supported_client();
+ if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CKSUM_ADLER_ONLY))
+ data->ocd_cksum_types = OBD_CKSUM_ADLER;
+ else
+ data->ocd_cksum_types = cksum_types_supported();
}
#ifdef HAVE_LRU_RESIZE_SUPPORT
/* send max bytes per rpc */
data->ocd_brw_size = PTLRPC_MAX_BRW_PAGES << CFS_PAGE_SHIFT;
/* send the list of supported checksum types */
- data->ocd_cksum_types = cksum_types_supported_client();
+ data->ocd_cksum_types = cksum_types_supported();
/* NB: lov_connect() needs to fill in .ocd_index for each OST */
rc = obd_connect(NULL, &mds->mds_lov_exp, mds->mds_lov_obd, &obd->obd_uuid, data, NULL);
OBD_FREE(data, sizeof(*data));
/* The client set in ocd_cksum_types the checksum types it
* supports. We have to mask off the algorithms that we don't
* support */
- data->ocd_cksum_types &= cksum_types_supported_server();
+ data->ocd_cksum_types &= cksum_types_supported();
- /* 1.6.4 clients are not supported any more */
+ /* 1.6.4- only support CRC32 and didn't set ocd_cksum_types */
+ if (unlikely(data->ocd_cksum_types == 0))
+ data->ocd_cksum_types = OBD_CKSUM_CRC32;
CDEBUG(D_RPCTRACE, "%s: cli %s supports cksum type %x, return "
"%x\n", exp->exp_obd->obd_name,
/* The client set in ocd_cksum_types the checksum types it
* supports. We have to mask off the algorithms that we don't
* support */
- data->ocd_cksum_types &= cksum_types_supported_server();
+ data->ocd_cksum_types &= cksum_types_supported();
if (unlikely(data->ocd_cksum_types == 0)) {
CERROR("%s: Connect with checksum support but no "
}
static obd_count osc_checksum_bulk(int nob, obd_count pg_count,
- struct brw_page **pga, int opc,
- cksum_type_t cksum_type)
-{
- __u32 cksum;
- int i = 0;
- struct cfs_crypto_hash_desc *hdesc;
- unsigned int bufsize;
- int err;
- unsigned char cfs_alg = cksum_obd2cfs(cksum_type);
-
- LASSERT(pg_count > 0);
-
- hdesc = cfs_crypto_hash_init(cfs_alg, NULL, 0);
- if (IS_ERR(hdesc)) {
- CERROR("Unable to initialize checksum hash %s\n",
- cfs_crypto_hash_name(cfs_alg));
- return PTR_ERR(hdesc);
- }
-
- while (nob > 0 && pg_count > 0) {
- int count = pga[i]->count > nob ? nob : pga[i]->count;
-
- /* corrupt the data before we compute the checksum, to
- * simulate an OST->client data error */
- if (i == 0 && opc == OST_READ &&
- OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_RECEIVE)) {
- unsigned char *ptr = cfs_kmap(pga[i]->pg);
- int off = pga[i]->off & ~CFS_PAGE_MASK;
- memcpy(ptr + off, "bad1", min(4, nob));
- cfs_kunmap(pga[i]->pg);
- }
- cfs_crypto_hash_update_page(hdesc, pga[i]->pg,
- pga[i]->off & ~CFS_PAGE_MASK,
- count);
- LL_CDEBUG_PAGE(D_PAGE, pga[i]->pg, "off %d checksum %x\n",
- (int)(pga[i]->off & ~CFS_PAGE_MASK), cksum);
-
- nob -= pga[i]->count;
- pg_count--;
- i++;
- }
-
- bufsize = 4;
- err = cfs_crypto_hash_final(hdesc, (unsigned char *)&cksum, &bufsize);
+ struct brw_page **pga, int opc,
+ cksum_type_t cksum_type)
+{
+ __u32 cksum;
+ int i = 0;
- if (err)
- cfs_crypto_hash_final(hdesc, NULL, NULL);
+ LASSERT (pg_count > 0);
+ cksum = init_checksum(cksum_type);
+ while (nob > 0 && pg_count > 0) {
+ unsigned char *ptr = cfs_kmap(pga[i]->pg);
+ int off = pga[i]->off & ~CFS_PAGE_MASK;
+ int count = pga[i]->count > nob ? nob : pga[i]->count;
+
+ /* corrupt the data before we compute the checksum, to
+ * simulate an OST->client data error */
+ if (i == 0 && opc == OST_READ &&
+ OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_RECEIVE))
+ memcpy(ptr + off, "bad1", min(4, nob));
+ cksum = compute_checksum(cksum, ptr + off, count, cksum_type);
+ cfs_kunmap(pga[i]->pg);
+ LL_CDEBUG_PAGE(D_PAGE, pga[i]->pg, "off %d checksum %x\n",
+ off, cksum);
- /* For sending we only compute the wrong checksum instead
- * of corrupting the data so it is still correct on a redo */
- if (opc == OST_WRITE && OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_SEND))
- cksum++;
+ nob -= pga[i]->count;
+ pg_count--;
+ i++;
+ }
+ /* For sending we only compute the wrong checksum instead
+ * of corrupting the data so it is still correct on a redo */
+ if (opc == OST_WRITE && OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_SEND))
+ cksum++;
- return cksum;
+ return fini_checksum(cksum, cksum_type);
}
static int osc_brw_prep_request(int cmd, struct client_obd *cli,struct obdo *oa,
}
static __u32 ost_checksum_bulk(struct ptlrpc_bulk_desc *desc, int opc,
- cksum_type_t cksum_type)
+ cksum_type_t cksum_type)
{
- struct cfs_crypto_hash_desc *hdesc;
- unsigned int bufsize;
- int i, err;
- unsigned char cfs_alg = cksum_obd2cfs(cksum_type);
- __u32 cksum;
-
- hdesc = cfs_crypto_hash_init(cfs_alg, NULL, 0);
- if (IS_ERR(hdesc)) {
- CERROR("Unable to initialize checksum hash %s\n",
- cfs_crypto_hash_name(cfs_alg));
- return PTR_ERR(hdesc);
- }
- CDEBUG(D_INFO, "Checksum for algo %s\n", cfs_crypto_hash_name(cfs_alg));
- for (i = 0; i < desc->bd_iov_count; i++) {
-
- /* corrupt the data before we compute the checksum, to
- * simulate a client->OST data error */
- if (i == 0 && opc == OST_WRITE &&
- OBD_FAIL_CHECK(OBD_FAIL_OST_CHECKSUM_RECEIVE)) {
- int off = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK;
- int len = desc->bd_iov[i].kiov_len;
- char *ptr = kmap(desc->bd_iov[i].kiov_page) + off;
- memcpy(ptr, "bad3", min(4, len));
- kunmap(desc->bd_iov[i].kiov_page);
- }
- cfs_crypto_hash_update_page(hdesc, desc->bd_iov[i].kiov_page,
- desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK,
- desc->bd_iov[i].kiov_len);
-
- /* corrupt the data after we compute the checksum, to
- * simulate an OST->client data error */
- if (i == 0 && opc == OST_READ &&
- OBD_FAIL_CHECK(OBD_FAIL_OST_CHECKSUM_SEND)) {
- int off = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK;
- int len = desc->bd_iov[i].kiov_len;
- char *ptr = kmap(desc->bd_iov[i].kiov_page) + off;
- memcpy(ptr, "bad4", min(4, len));
- kunmap(desc->bd_iov[i].kiov_page);
- /* nobody should use corrupted page again */
- ClearPageUptodate(desc->bd_iov[i].kiov_page);
- }
- }
+ __u32 cksum;
+ int i;
- bufsize = 4;
- err = cfs_crypto_hash_final(hdesc, (unsigned char *)&cksum, &bufsize);
- if (err)
- cfs_crypto_hash_final(hdesc, NULL, NULL);
+ cksum = init_checksum(cksum_type);
+ for (i = 0; i < desc->bd_iov_count; i++) {
+ struct page *page = desc->bd_iov[i].kiov_page;
+ int off = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK;
+ char *ptr = kmap(page) + off;
+ int len = desc->bd_iov[i].kiov_len;
+
+ /* corrupt the data before we compute the checksum, to
+ * simulate a client->OST data error */
+ if (i == 0 && opc == OST_WRITE &&
+ OBD_FAIL_CHECK(OBD_FAIL_OST_CHECKSUM_RECEIVE))
+ memcpy(ptr, "bad3", min(4, len));
+ cksum = compute_checksum(cksum, ptr, len, cksum_type);
+ /* corrupt the data after we compute the checksum, to
+ * simulate an OST->client data error */
+ if (i == 0 && opc == OST_READ &&
+ OBD_FAIL_CHECK(OBD_FAIL_OST_CHECKSUM_SEND)) {
+ memcpy(ptr, "bad4", min(4, len));
+ /* nobody should use corrupted page again */
+ ClearPageUptodate(page);
+ }
+ kunmap(page);
+ }
- return cksum;
+ return fini_checksum(cksum, cksum_type);
}
static int ost_brw_lock_get(int mode, struct obd_export *exp,
newer : older, LUSTRE_VERSION_STRING);
}
- if (ocd->ocd_connect_flags & OBD_CONNECT_CKSUM) {
- /* We sent to the server ocd_cksum_types with bits set
- * for algorithms we understand. The server masked off
- * the checksum types it doesn't support */
- if ((ocd->ocd_cksum_types &
- cksum_types_supported_client()) == 0) {
- LCONSOLE_WARN("The negotiation of the checksum "
- "alogrithm to use with server %s "
- "failed (%x/%x), disabling "
- "checksums\n",
- obd2cli_tgt(imp->imp_obd),
- ocd->ocd_cksum_types,
- cksum_types_supported_client());
- cli->cl_checksum = 0;
- cli->cl_supp_cksum_types = OBD_CKSUM_ADLER;
- } else {
- cli->cl_supp_cksum_types = ocd->ocd_cksum_types;
- }
- } else {
- /* The server does not support OBD_CONNECT_CKSUM.
- * Enforce ADLER for backward compatibility*/
- cli->cl_supp_cksum_types = OBD_CKSUM_ADLER;
- }
+ if (ocd->ocd_connect_flags & OBD_CONNECT_CKSUM) {
+ /* We sent to the server ocd_cksum_types with bits set
+ * for algorithms we understand. The server masked off
+ * the checksum types it doesn't support */
+ if ((ocd->ocd_cksum_types & cksum_types_supported()) == 0) {
+ LCONSOLE_WARN("The negotiation of the checksum "
+ "alogrithm to use with server %s "
+ "failed (%x/%x), disabling "
+ "checksums\n",
+ obd2cli_tgt(imp->imp_obd),
+ ocd->ocd_cksum_types,
+ cksum_types_supported());
+ cli->cl_checksum = 0;
+ cli->cl_supp_cksum_types = OBD_CKSUM_CRC32;
+ } else {
+ cli->cl_supp_cksum_types = ocd->ocd_cksum_types;
+ }
+ } else {
+ /* The server does not support OBD_CONNECT_CKSUM.
+ * Enforce CRC32 for backward compatibility*/
+ cli->cl_supp_cksum_types = OBD_CKSUM_CRC32;
+ }
cli->cl_cksum_type =cksum_type_select(cli->cl_supp_cksum_types);
if (ocd->ocd_connect_flags & OBD_CONNECT_BRW_SIZE)
__u32 lustre_msg_calc_cksum(struct lustre_msg *msg)
#endif
{
- switch (msg->lm_magic) {
- case LUSTRE_MSG_MAGIC_V2: {
- struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
+ switch (msg->lm_magic) {
+ case LUSTRE_MSG_MAGIC_V2: {
+ struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 0, 0)
- __u32 crc;
- unsigned int hsize = 4;
- __u32 len = compat18 ? ptlrpc_body_cksum_size_compat18 :
- lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF);
- LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
- cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb,
- len, NULL, 0, (unsigned char *)&crc,
- &hsize);
- return crc;
+ __u32 len = compat18 ? ptlrpc_body_cksum_size_compat18 :
+ lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF);
+ LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
+ return crc32_le(~(__u32)0, (unsigned char *)pb, len);
#else
# warning "remove checksum compatibility support for b1_8"
- __u32 crc;
- unsigned int hsize = 4;
- cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb,
- lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF),
- NULL, 0, (unsigned char *)&crc, &hsize);
- return crc;
+ return crc32_le(~(__u32)0, (unsigned char *)pb,
+ lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF));
#endif
- }
- default:
- CERROR("incorrect message magic: %08x\n", msg->lm_magic);
- return 0;
- }
+ }
+ default:
+ CERROR("incorrect message magic: %08x\n", msg->lm_magic);
+ return 0;
+ }
}
void lustre_msg_set_handle(struct lustre_msg *msg, struct lustre_handle *handle)
}
#endif
-static int cfs_hash_alg_id[] = {
- [BULK_HASH_ALG_NULL] = CFS_HASH_ALG_NULL,
- [BULK_HASH_ALG_ADLER32] = CFS_HASH_ALG_ADLER32,
- [BULK_HASH_ALG_CRC32] = CFS_HASH_ALG_CRC32,
- [BULK_HASH_ALG_MD5] = CFS_HASH_ALG_MD5,
- [BULK_HASH_ALG_SHA1] = CFS_HASH_ALG_SHA1,
- [BULK_HASH_ALG_SHA256] = CFS_HASH_ALG_SHA256,
- [BULK_HASH_ALG_SHA384] = CFS_HASH_ALG_SHA384,
- [BULK_HASH_ALG_SHA512] = CFS_HASH_ALG_SHA512,
+/****************************************
+ * Helpers to assist policy modules to *
+ * implement checksum funcationality *
+ ****************************************/
+
+static struct sptlrpc_hash_type hash_types[] = {
+ [BULK_HASH_ALG_NULL] = { "null", "null", 0 },
+ [BULK_HASH_ALG_ADLER32] = { "adler32", "adler32", 4 },
+ [BULK_HASH_ALG_CRC32] = { "crc32", "crc32", 4 },
+ [BULK_HASH_ALG_MD5] = { "md5", "md5", 16 },
+ [BULK_HASH_ALG_SHA1] = { "sha1", "sha1", 20 },
+ [BULK_HASH_ALG_SHA256] = { "sha256", "sha256", 32 },
+ [BULK_HASH_ALG_SHA384] = { "sha384", "sha384", 48 },
+ [BULK_HASH_ALG_SHA512] = { "sha512", "sha512", 64 },
};
+
+const struct sptlrpc_hash_type *sptlrpc_get_hash_type(__u8 hash_alg)
+{
+ struct sptlrpc_hash_type *ht;
+
+ if (hash_alg < BULK_HASH_ALG_MAX) {
+ ht = &hash_types[hash_alg];
+ if (ht->sht_tfm_name)
+ return ht;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(sptlrpc_get_hash_type);
+
const char * sptlrpc_get_hash_name(__u8 hash_alg)
{
- return cfs_crypto_hash_name(cfs_hash_alg_id[hash_alg]);
+ const struct sptlrpc_hash_type *ht;
+
+ ht = sptlrpc_get_hash_type(hash_alg);
+ if (ht)
+ return ht->sht_name;
+ else
+ return "unknown";
}
EXPORT_SYMBOL(sptlrpc_get_hash_name);
__u8 sptlrpc_get_hash_alg(const char *algname)
{
- return cfs_crypto_hash_alg(algname);
+ int i;
+
+ for (i = 0; i < BULK_HASH_ALG_MAX; i++)
+ if (!strcmp(hash_types[i].sht_name, algname))
+ break;
+ return i;
}
EXPORT_SYMBOL(sptlrpc_get_hash_alg);
}
EXPORT_SYMBOL(bulk_sec_desc_unpack);
-int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg,
- void *buf, int buflen)
+#ifdef __KERNEL__
+
+#ifdef HAVE_ADLER
+static int do_bulk_checksum_adler32(struct ptlrpc_bulk_desc *desc, void *buf)
{
- struct cfs_crypto_hash_desc *hdesc;
- int hashsize;
- char hashbuf[64];
- unsigned int bufsize;
- int i, err;
+ struct page *page;
+ int off;
+ char *ptr;
+ __u32 adler32 = 1;
+ int len, i;
- LASSERT(alg > BULK_HASH_ALG_NULL && alg < BULK_HASH_ALG_MAX);
- LASSERT(buflen >= 4);
+ for (i = 0; i < desc->bd_iov_count; i++) {
+ page = desc->bd_iov[i].kiov_page;
+ off = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK;
+ ptr = cfs_kmap(page) + off;
+ len = desc->bd_iov[i].kiov_len;
- hdesc = cfs_crypto_hash_init(cfs_hash_alg_id[alg], NULL, 0);
- if (IS_ERR(hdesc)) {
- CERROR("Unable to initialize checksum hash %s\n",
- cfs_crypto_hash_name(cfs_hash_alg_id[alg]));
- return PTR_ERR(hdesc);
- }
+ adler32 = adler32(adler32, ptr, len);
- hashsize = cfs_crypto_hash_digestsize(cfs_hash_alg_id[alg]);
+ cfs_kunmap(page);
+ }
- for (i = 0; i < desc->bd_iov_count; i++) {
-#ifdef __KERNEL__
- cfs_crypto_hash_update_page(hdesc, desc->bd_iov[i].kiov_page,
- desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK,
- desc->bd_iov[i].kiov_len);
+ adler32 = cpu_to_le32(adler32);
+ memcpy(buf, &adler32, sizeof(adler32));
+ return 0;
+}
+#endif
+
+static int do_bulk_checksum_crc32(struct ptlrpc_bulk_desc *desc, void *buf)
+{
+ struct page *page;
+ int off;
+ char *ptr;
+ __u32 crc32 = ~0;
+ int len, i;
+
+ for (i = 0; i < desc->bd_iov_count; i++) {
+ page = desc->bd_iov[i].kiov_page;
+ off = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK;
+ ptr = cfs_kmap(page) + off;
+ len = desc->bd_iov[i].kiov_len;
+
+ crc32 = crc32_le(crc32, ptr, len);
+
+ cfs_kunmap(page);
+ }
+
+ crc32 = cpu_to_le32(crc32);
+ memcpy(buf, &crc32, sizeof(crc32));
+ return 0;
+}
+
+int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg,
+ void *buf, int buflen)
+{
+ struct hash_desc hdesc;
+ int hashsize;
+ char hashbuf[64];
+ struct scatterlist sl;
+ int i;
+
+ LASSERT(alg > BULK_HASH_ALG_NULL && alg < BULK_HASH_ALG_MAX);
+ LASSERT(buflen >= 4);
+
+ switch (alg) {
+ case BULK_HASH_ALG_ADLER32:
+#ifdef HAVE_ADLER
+ return do_bulk_checksum_adler32(desc, buf);
#else
- cfs_crypto_hash_update(hdesc, desc->bd_iov[i].iov_base,
- desc->bd_iov[i].iov_len);
+ CERROR("Adler32 not supported\n");
+ return -EINVAL;
#endif
- }
- if (hashsize > buflen) {
- bufsize = sizeof(hashbuf);
- err = cfs_crypto_hash_final(hdesc, (unsigned char *)hashbuf,
- &bufsize);
- memcpy(buf, hashbuf, buflen);
- } else {
- bufsize = buflen;
- err = cfs_crypto_hash_final(hdesc, (unsigned char *)buf,
- &bufsize);
- }
-
- if (err)
- cfs_crypto_hash_final(hdesc, NULL, NULL);
- return err;
+ case BULK_HASH_ALG_CRC32:
+ return do_bulk_checksum_crc32(desc, buf);
+ }
+
+ hdesc.tfm = ll_crypto_alloc_hash(hash_types[alg].sht_tfm_name, 0, 0);
+ if (hdesc.tfm == NULL) {
+ CERROR("Unable to allocate TFM %s\n", hash_types[alg].sht_name);
+ return -ENOMEM;
+ }
+
+ hdesc.flags = 0;
+ ll_crypto_hash_init(&hdesc);
+
+ hashsize = ll_crypto_hash_digestsize(hdesc.tfm);
+
+ for (i = 0; i < desc->bd_iov_count; i++) {
+ sg_set_page(&sl, desc->bd_iov[i].kiov_page,
+ desc->bd_iov[i].kiov_len,
+ desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK);
+ ll_crypto_hash_update(&hdesc, &sl, sl.length);
+ }
+
+ if (hashsize > buflen) {
+ ll_crypto_hash_final(&hdesc, hashbuf);
+ memcpy(buf, hashbuf, buflen);
+ } else {
+ ll_crypto_hash_final(&hdesc, buf);
+ }
+
+ ll_crypto_free_hash(hdesc.tfm);
+ return 0;
}
EXPORT_SYMBOL(sptlrpc_get_bulk_checksum);
+#else /* !__KERNEL__ */
+
+int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg,
+ void *buf, int buflen)
+{
+ __u32 csum32;
+ int i;
+
+ LASSERT(alg == BULK_HASH_ALG_ADLER32 || alg == BULK_HASH_ALG_CRC32);
+
+ if (alg == BULK_HASH_ALG_ADLER32)
+ csum32 = 1;
+ else
+ csum32 = ~0;
+
+ for (i = 0; i < desc->bd_iov_count; i++) {
+ unsigned char *ptr = desc->bd_iov[i].iov_base;
+ int len = desc->bd_iov[i].iov_len;
+
+ switch (alg) {
+ case BULK_HASH_ALG_ADLER32:
+#ifdef HAVE_ADLER
+ csum32 = adler32(csum32, ptr, len);
+#else
+ CERROR("Adler32 not supported\n");
+ return -EINVAL;
+#endif
+ break;
+ case BULK_HASH_ALG_CRC32:
+ csum32 = crc32_le(csum32, ptr, len);
+ break;
+ }
+ }
+
+ csum32 = cpu_to_le32(csum32);
+ memcpy(buf, &csum32, sizeof(csum32));
+ return 0;
+}
+#endif /* __KERNEL__ */
}
if (unlikely(req->rq_early)) {
- unsigned int hsize = 4;
-
- cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32,
- lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0),
- lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF),
- NULL, 0, (unsigned char *)&cksum, &hsize);
- if (cksum != msg->lm_cksum) {
- CDEBUG(D_SEC,
- "early reply checksum mismatch: %08x != %08x\n",
- cpu_to_le32(cksum), msg->lm_cksum);
- RETURN(-EINVAL);
- }
+ cksum = crc32_le(!(__u32) 0,
+ lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0),
+ lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF));
+ if (cksum != msg->lm_cksum) {
+ CDEBUG(D_SEC,
+ "early reply checksum mismatch: %08x != %08x\n",
+ cpu_to_le32(cksum), msg->lm_cksum);
+ RETURN(-EINVAL);
+ }
} else {
/* whether we sent with bulk or not, we expect the same
* in reply, except for early reply */
else
req->rq_reply_off = 0;
} else {
- unsigned int hsize = 4;
-
- cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32,
- lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0),
- lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF),
- NULL, 0, (unsigned char *)&msg->lm_cksum, &hsize);
- req->rq_reply_off = 0;
+ msg->lm_cksum = crc32_le(!(__u32) 0,
+ lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0),
+ lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF));
+ req->rq_reply_off = 0;
}
RETURN(0);
for VALUE in `lctl get_param osc.*osc-[^mM]*.checksum_type`; do
PARAM=`echo ${VALUE[0]} | cut -d "=" -f1`
algo=`lctl get_param -n $PARAM | sed 's/.*\[\(.*\)\].*/\1/g'`
- [ "$algo" = "adler" ] || error "algo set to $algo instead of adler"
+ [ "$algo" = "crc32" ] || error "algo set to $algo instead of crc32"
done
remount_client $MOUNT
}