From 3f90f344ae059b30e7d23e4fe554a985eb827b02 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Mon, 11 Jun 2012 15:45:59 -0400 Subject: [PATCH] Revert "LU-1201 checksum: add libcfs crypto hash" This reverts commit 84a3fd67356c8073a917ea6abd63928055e38156 that broke build for external ofed on rhel5 kernels. Signed-off-by: Oleg Drokin --- libcfs/autoconf/lustre-libcfs.m4 | 46 ---- libcfs/include/libcfs/Makefile.am | 2 +- libcfs/include/libcfs/libcfs.h | 1 - libcfs/include/libcfs/libcfs_crypto.h | 201 --------------- libcfs/include/libcfs/linux/Makefile.am | 2 +- libcfs/include/libcfs/linux/linux-crypto.h | 43 ---- libcfs/include/libcfs/posix/Makefile.am | 2 +- libcfs/include/libcfs/posix/posix-crypto.h | 44 ---- libcfs/libcfs/Makefile.in | 2 - libcfs/libcfs/autoMakefile.am | 3 +- libcfs/libcfs/linux/Makefile.am | 4 +- libcfs/libcfs/linux/linux-crypto-adler.c | 218 ---------------- libcfs/libcfs/linux/linux-crypto-crc32.c | 223 ---------------- libcfs/libcfs/linux/linux-crypto.c | 358 -------------------------- libcfs/libcfs/module.c | 140 +++++----- libcfs/libcfs/posix/posix-adler.c | 83 ------ libcfs/libcfs/posix/posix-crc32.c | 78 ------ libcfs/libcfs/user-crypto.c | 396 ----------------------------- lustre/include/linux/Makefile.am | 9 +- lustre/include/linux/obd_cksum.h | 65 +++++ lustre/include/lustre_sec.h | 7 + lustre/include/obd_cksum.h | 298 ++++++++++++++-------- lustre/llite/llite_lib.c | 8 +- lustre/mds/mds_lov.c | 2 +- lustre/obdfilter/filter.c | 6 +- lustre/ofd/ofd_obd.c | 2 +- lustre/osc/osc_request.c | 81 +++--- lustre/ost/ost_handler.c | 75 ++---- lustre/ptlrpc/import.c | 45 ++-- lustre/ptlrpc/pack_generic.c | 37 +-- lustre/ptlrpc/sec_bulk.c | 225 ++++++++++++---- lustre/ptlrpc/sec_plain.c | 32 +-- lustre/tests/sanity.sh | 2 +- 33 files changed, 639 insertions(+), 2101 deletions(-) delete mode 100644 libcfs/include/libcfs/libcfs_crypto.h delete mode 100644 libcfs/include/libcfs/linux/linux-crypto.h delete mode 100644 libcfs/include/libcfs/posix/posix-crypto.h delete mode 100644 libcfs/libcfs/linux/linux-crypto-adler.c delete mode 100644 libcfs/libcfs/linux/linux-crypto-crc32.c delete mode 100644 libcfs/libcfs/linux/linux-crypto.c delete mode 100644 libcfs/libcfs/posix/posix-adler.c delete mode 100644 libcfs/libcfs/posix/posix-crc32.c delete mode 100644 libcfs/libcfs/user-crypto.c create mode 100644 lustre/include/linux/obd_cksum.h diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index 8ff37b5..dfd9c03 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -93,30 +93,6 @@ AC_DEFINE(HAVE_TASKLIST_LOCK, 1, ]) ]) -# 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 - #include - - 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 @@ -246,7 +222,6 @@ LB_LINUX_TRY_COMPILE([ ]) ]) - # 2.6.20 API change INIT_WORK use 2 args and not # store data inside AC_DEFUN([LIBCFS_3ARGS_INIT_WORK], @@ -515,25 +490,6 @@ LB_LINUX_TRY_COMPILE([ ]) ]) -# 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 - #include -],[ - 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 # @@ -756,7 +712,6 @@ LIBCFS_U64_LONG_LONG_LINUX # 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 @@ -780,7 +735,6 @@ LIBCFS_CPUMASK_SIZE # 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 diff --git a/libcfs/include/libcfs/Makefile.am b/libcfs/include/libcfs/Makefile.am index 89054ee..79f923a 100644 --- a/libcfs/include/libcfs/Makefile.am +++ b/libcfs/include/libcfs/Makefile.am @@ -11,4 +11,4 @@ EXTRA_DIST := curproc.h libcfs_private.h libcfs.h list.h lltrace.h \ 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 diff --git a/libcfs/include/libcfs/libcfs.h b/libcfs/include/libcfs/libcfs.h index be826b4..5fbeed9 100644 --- a/libcfs/include/libcfs/libcfs.h +++ b/libcfs/include/libcfs/libcfs.h @@ -314,7 +314,6 @@ void cfs_get_random_bytes(void *buf, int size); #include #include #include -#include /* container_of depends on "likely" which is defined in libcfs_private.h */ static inline void *__container_of(void *ptr, unsigned long shift) diff --git a/libcfs/include/libcfs/libcfs_crypto.h b/libcfs/include/libcfs/libcfs_crypto.h deleted file mode 100644 index 291191a..0000000 --- a/libcfs/include/libcfs/libcfs_crypto.h +++ /dev/null @@ -1,201 +0,0 @@ -/* 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 diff --git a/libcfs/include/libcfs/linux/Makefile.am b/libcfs/include/libcfs/linux/Makefile.am index 0a5917f..a7ca7cc 100644 --- a/libcfs/include/libcfs/linux/Makefile.am +++ b/libcfs/include/libcfs/linux/Makefile.am @@ -1,3 +1,3 @@ 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 diff --git a/libcfs/include/libcfs/linux/linux-crypto.h b/libcfs/include/libcfs/linux/linux-crypto.h deleted file mode 100644 index c8a4e76..0000000 --- a/libcfs/include/libcfs/linux/linux-crypto.h +++ /dev/null @@ -1,43 +0,0 @@ - /* - * 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); diff --git a/libcfs/include/libcfs/posix/Makefile.am b/libcfs/include/libcfs/posix/Makefile.am index 609bb0c..ca5c0da 100644 --- a/libcfs/include/libcfs/posix/Makefile.am +++ b/libcfs/include/libcfs/posix/Makefile.am @@ -4,4 +4,4 @@ if UTILS 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 diff --git a/libcfs/include/libcfs/posix/posix-crypto.h b/libcfs/include/libcfs/posix/posix-crypto.h deleted file mode 100644 index 72a9fc1..0000000 --- a/libcfs/include/libcfs/posix/posix-crypto.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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); diff --git a/libcfs/libcfs/Makefile.in b/libcfs/libcfs/Makefile.in index 2b040b0..026dcab 100644 --- a/libcfs/libcfs/Makefile.in +++ b/libcfs/libcfs/Makefile.in @@ -5,8 +5,6 @@ libcfs-linux-objs += linux-prim.o linux-mem.o linux-cpu.o 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 diff --git a/libcfs/libcfs/autoMakefile.am b/libcfs/libcfs/autoMakefile.am index e29230d..7ce8133 100644 --- a/libcfs/libcfs/autoMakefile.am +++ b/libcfs/libcfs/autoMakefile.am @@ -44,8 +44,7 @@ if LIBLUSTRE 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 diff --git a/libcfs/libcfs/linux/Makefile.am b/libcfs/libcfs/linux/Makefile.am index 8d206cf..4792d73 100644 --- a/libcfs/libcfs/linux/Makefile.am +++ b/libcfs/libcfs/linux/Makefile.am @@ -1,7 +1,5 @@ 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 diff --git a/libcfs/libcfs/linux/linux-crypto-adler.c b/libcfs/libcfs/linux/linux-crypto-adler.c deleted file mode 100644 index 9eeda9c..0000000 --- a/libcfs/libcfs/linux/linux-crypto-adler.c +++ /dev/null @@ -1,218 +0,0 @@ -/* 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 -#ifdef HAVE_STRUCT_SHASH_ALG -#include -#else -#include -#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); diff --git a/libcfs/libcfs/linux/linux-crypto-crc32.c b/libcfs/libcfs/linux/linux-crypto-crc32.c deleted file mode 100644 index 0c8fc25..0000000 --- a/libcfs/libcfs/linux/linux-crypto-crc32.c +++ /dev/null @@ -1,223 +0,0 @@ -/* 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 -#ifdef HAVE_STRUCT_SHASH_ALG -#include -#else -#include -#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); diff --git a/libcfs/libcfs/linux/linux-crypto.c b/libcfs/libcfs/linux/linux-crypto.c deleted file mode 100644 index a15938a..0000000 --- a/libcfs/libcfs/linux/linux-crypto.c +++ /dev/null @@ -1,358 +0,0 @@ -/* 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 -#include -#include -#include -/** - * 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; -} diff --git a/libcfs/libcfs/module.c b/libcfs/libcfs/module.c index f049378..c9763c7 100644 --- a/libcfs/libcfs/module.c +++ b/libcfs/libcfs/module.c @@ -35,7 +35,6 @@ #define DEBUG_SUBSYSTEM S_LNET #include -#include #include #include #include "tracefile.h" @@ -374,108 +373,99 @@ extern void libcfs_arch_cleanup(void); 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); diff --git a/libcfs/libcfs/posix/posix-adler.c b/libcfs/libcfs/posix/posix-adler.c deleted file mode 100644 index 36931d4..0000000 --- a/libcfs/libcfs/posix/posix-adler.c +++ /dev/null @@ -1,83 +0,0 @@ -/* 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 - - -#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; -} diff --git a/libcfs/libcfs/posix/posix-crc32.c b/libcfs/libcfs/posix/posix-crc32.c deleted file mode 100644 index 972c5ff..0000000 --- a/libcfs/libcfs/posix/posix-crc32.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file contains part of linux kernel implementation of crc32 - * kernel version 2.6.32 - */ -#include -#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 -} diff --git a/libcfs/libcfs/user-crypto.c b/libcfs/libcfs/user-crypto.c deleted file mode 100644 index 66d0bae..0000000 --- a/libcfs/libcfs/user-crypto.c +++ /dev/null @@ -1,396 +0,0 @@ -/* 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 -#include - -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(); - } -} diff --git a/lustre/include/linux/Makefile.am b/lustre/include/linux/Makefile.am index 2dd1aae..690deba 100644 --- a/lustre/include/linux/Makefile.am +++ b/lustre/include/linux/Makefile.am @@ -41,7 +41,8 @@ linux_HEADERS = lustre_user.h 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 diff --git a/lustre/include/linux/obd_cksum.h b/lustre/include/linux/obd_cksum.h new file mode 100644 index 0000000..aedbc23 --- /dev/null +++ b/lustre/include/linux/obd_cksum.h @@ -0,0 +1,65 @@ +/* + * 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 instead +#endif + +#include + +/* 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 +# define HAVE_ARCH_CRC32 +#endif + +#ifdef __KERNEL__ +# include +# ifndef HAVE_ADLER +# define HAVE_ADLER +# endif +# define adler32(a,b,l) zlib_adler32(a,b,l) +#else /* __KERNEL__ */ +# ifdef HAVE_ADLER +# include +# endif +#endif /*! __KERNEL__ */ + +#endif diff --git a/lustre/include/lustre_sec.h b/lustre/include/lustre_sec.h index 6c4207c..fab2299 100644 --- a/lustre/include/lustre_sec.h +++ b/lustre/include/lustre_sec.h @@ -883,6 +883,13 @@ enum sptlrpc_bulk_hash_alg { 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); diff --git a/lustre/include/obd_cksum.h b/lustre/include/obd_cksum.h index d546bb8..7166f7a 100644 --- a/lustre/include/obd_cksum.h +++ b/lustre/include/obd_cksum.h @@ -34,23 +34,157 @@ #ifndef __OBD_CKSUM #define __OBD_CKSUM -#include + +#if defined(__linux__) +#include +#elif defined(__APPLE__) +#include +#elif defined(__WINNT__) +#include +#else +#error Unsupported operating system. +#endif + #include -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 @@ -60,113 +194,79 @@ static inline unsigned char cksum_obd2cfs(cksum_type_t cksum_type) * 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 diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 8c64fba..958cf24 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -399,10 +399,10 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, * 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 diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c index c2b58cb..79d137f 100644 --- a/lustre/mds/mds_lov.c +++ b/lustre/mds/mds_lov.c @@ -730,7 +730,7 @@ int mds_lov_connect(struct obd_device *obd, char * lov_name) /* 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)); diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index f365a2e..71aae20 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -2777,9 +2777,11 @@ static int filter_connect_internal(struct obd_export *exp, /* 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, diff --git a/lustre/ofd/ofd_obd.c b/lustre/ofd/ofd_obd.c index 5eba90b..6135f0f 100644 --- a/lustre/ofd/ofd_obd.c +++ b/lustre/ofd/ofd_obd.c @@ -213,7 +213,7 @@ static int ofd_parse_connect_data(const struct lu_env *env, /* 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 " diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index b8353c5..3aaf175 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -1136,60 +1136,39 @@ static inline int can_merge_pages(struct brw_page *p1, struct brw_page *p2) } 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, diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 714d7e1..dddb4dd 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -521,57 +521,36 @@ static int ost_setattr(struct obd_export *exp, struct ptlrpc_request *req, } 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, diff --git a/lustre/ptlrpc/import.c b/lustre/ptlrpc/import.c index 4ef4afe..7e68efb 100644 --- a/lustre/ptlrpc/import.c +++ b/lustre/ptlrpc/import.c @@ -1024,29 +1024,28 @@ finish: 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) diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 8dc8546..545d767 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -1298,33 +1298,24 @@ __u32 lustre_msg_calc_cksum(struct lustre_msg *msg, int compat18) __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) diff --git a/lustre/ptlrpc/sec_bulk.c b/lustre/ptlrpc/sec_bulk.c index a9eaccb..bfce3e1 100644 --- a/lustre/ptlrpc/sec_bulk.c +++ b/lustre/ptlrpc/sec_bulk.c @@ -803,25 +803,55 @@ void sptlrpc_enc_pool_fini(void) } #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); @@ -863,52 +893,149 @@ int bulk_sec_desc_unpack(struct lustre_msg *msg, int offset, int swabbed) } 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__ */ diff --git a/lustre/ptlrpc/sec_plain.c b/lustre/ptlrpc/sec_plain.c index 10f88fa..d123e30 100644 --- a/lustre/ptlrpc/sec_plain.c +++ b/lustre/ptlrpc/sec_plain.c @@ -270,18 +270,15 @@ int plain_ctx_verify(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) } 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 */ @@ -895,13 +892,10 @@ int plain_authorize(struct ptlrpc_request *req) 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); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 4500346..612f4b0 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -4696,7 +4696,7 @@ test_77i() { # bug 13805 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 } -- 1.8.3.1