X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fsec_bulk.c;h=c6fe4ce1032539e3e49344b7662a54c2aab64896;hb=6fe7c32906f67f43d815c884ed8a902bb2333992;hp=c09cf0ca3b4ebf09b537e1cc3b2bce1d7bac0922;hpb=744f32ac9efb1e2f2837992703c5a5e35f261e60;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/sec_bulk.c b/lustre/ptlrpc/sec_bulk.c index c09cf0ca..c6fe4ce 100644 --- a/lustre/ptlrpc/sec_bulk.c +++ b/lustre/ptlrpc/sec_bulk.c @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -26,8 +24,10 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2011, 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -38,9 +38,6 @@ * Author: Eric Mei */ -#ifndef EXPORT_SYMTAB -#define EXPORT_SYMTAB -#endif #define DEBUG_SUBSYSTEM S_SEC #include @@ -107,7 +104,7 @@ static struct ptlrpc_enc_page_pool { /* * in-pool pages bookkeeping */ - spinlock_t epp_lock; /* protect following fields */ + spinlock_t epp_lock; /* protect following fields */ unsigned long epp_total_pages; /* total pages in pools */ unsigned long epp_free_pages; /* current pages available */ @@ -132,8 +129,8 @@ static struct ptlrpc_enc_page_pool { /* * memory shrinker */ -const int pools_shrinker_seeks = DEFAULT_SEEKS; -static struct shrinker *pools_shrinker = NULL; +const int pools_shrinker_seeks = CFS_DEFAULT_SEEKS; +static struct cfs_shrinker *pools_shrinker = NULL; /* @@ -144,7 +141,7 @@ int sptlrpc_proc_read_enc_pool(char *page, char **start, off_t off, int count, { int rc; - spin_lock(&page_pools.epp_lock); + spin_lock(&page_pools.epp_lock); rc = snprintf(page, count, "physical pages: %lu\n" @@ -166,7 +163,7 @@ int sptlrpc_proc_read_enc_pool(char *page, char **start, off_t off, int count, "max waitqueue depth: %u\n" "max wait time: "CFS_TIME_T"/%u\n" , - num_physpages, + cfs_num_physpages, PAGES_PER_POOL, page_pools.epp_max_pages, page_pools.epp_max_pools, @@ -183,11 +180,11 @@ int sptlrpc_proc_read_enc_pool(char *page, char **start, off_t off, int count, page_pools.epp_st_missings, page_pools.epp_st_lowfree, page_pools.epp_st_max_wqlen, - page_pools.epp_st_max_wait, HZ + page_pools.epp_st_max_wait, CFS_HZ ); - spin_unlock(&page_pools.epp_lock); - return rc; + spin_unlock(&page_pools.epp_lock); + return rc; } static void enc_pools_release_free_pages(long npages) @@ -206,7 +203,7 @@ static void enc_pools_release_free_pages(long npages) page_pools.epp_total_pages -= npages; /* max pool index after the release */ - p_idx_max1 = page_pools.epp_total_pages == 0 ? 0 : + p_idx_max1 = page_pools.epp_total_pages == 0 ? -1 : ((page_pools.epp_total_pages - 1) / PAGES_PER_POOL); p_idx = page_pools.epp_free_pages / PAGES_PER_POOL; @@ -236,50 +233,44 @@ static void enc_pools_release_free_pages(long npages) } /* - * could be called frequently for query (@nr_to_scan == 0) + * could be called frequently for query (@nr_to_scan == 0). + * we try to keep at least PTLRPC_MAX_BRW_PAGES pages in the pool. */ -static int enc_pools_shrink(int nr_to_scan, unsigned int gfp_mask) +static int enc_pools_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask)) { - unsigned long ret; - - spin_lock(&page_pools.epp_lock); - - if (nr_to_scan > page_pools.epp_free_pages) - nr_to_scan = page_pools.epp_free_pages; - - if (nr_to_scan > 0) { - enc_pools_release_free_pages(nr_to_scan); - CDEBUG(D_SEC, "released %d pages, %ld left\n", - nr_to_scan, page_pools.epp_free_pages); - - page_pools.epp_st_shrinks++; - page_pools.epp_last_shrink = cfs_time_current_sec(); - } - - /* - * try to keep at least PTLRPC_MAX_BRW_PAGES pages in the pool - */ - if (page_pools.epp_free_pages <= PTLRPC_MAX_BRW_PAGES) { - ret = 0; - goto out_unlock; - } - - /* - * if no pool access for a long time, we consider it's fully idle - */ - if (cfs_time_current_sec() - page_pools.epp_last_access > - CACHE_QUIESCENT_PERIOD) - page_pools.epp_idle_idx = IDLE_IDX_MAX; - - LASSERT(page_pools.epp_idle_idx <= IDLE_IDX_MAX); - ret = (page_pools.epp_free_pages * page_pools.epp_idle_idx / - IDLE_IDX_MAX); - if (page_pools.epp_free_pages - ret < PTLRPC_MAX_BRW_PAGES) - ret = page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES; - -out_unlock: - spin_unlock(&page_pools.epp_lock); - return ret; + if (unlikely(shrink_param(sc, nr_to_scan) != 0)) { + spin_lock(&page_pools.epp_lock); + shrink_param(sc, nr_to_scan) = min_t(unsigned long, + shrink_param(sc, nr_to_scan), + page_pools.epp_free_pages - + PTLRPC_MAX_BRW_PAGES); + if (shrink_param(sc, nr_to_scan) > 0) { + enc_pools_release_free_pages(shrink_param(sc, + nr_to_scan)); + CDEBUG(D_SEC, "released %ld pages, %ld left\n", + (long)shrink_param(sc, nr_to_scan), + page_pools.epp_free_pages); + + page_pools.epp_st_shrinks++; + page_pools.epp_last_shrink = cfs_time_current_sec(); + } + spin_unlock(&page_pools.epp_lock); + } + + /* + * if no pool access for a long time, we consider it's fully idle. + * a little race here is fine. + */ + if (unlikely(cfs_time_current_sec() - page_pools.epp_last_access > + CACHE_QUIESCENT_PERIOD)) { + spin_lock(&page_pools.epp_lock); + page_pools.epp_idle_idx = IDLE_IDX_MAX; + spin_unlock(&page_pools.epp_lock); + } + + LASSERT(page_pools.epp_idle_idx <= IDLE_IDX_MAX); + return max((int)page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES, 0) * + (IDLE_IDX_MAX - page_pools.epp_idle_idx) / IDLE_IDX_MAX; } static inline @@ -328,8 +319,9 @@ static void enc_pools_insert(cfs_page_t ***pools, int npools, int npages) LASSERT(npages > 0); LASSERT(page_pools.epp_total_pages+npages <= page_pools.epp_max_pages); LASSERT(npages_to_npools(npages) == npools); + LASSERT(page_pools.epp_growing); - spin_lock(&page_pools.epp_lock); + spin_lock(&page_pools.epp_lock); /* * (1) fill all the free slots of current pools. @@ -396,20 +388,20 @@ static void enc_pools_insert(cfs_page_t ***pools, int npools, int npages) CDEBUG(D_SEC, "add %d pages to total %lu\n", npages, page_pools.epp_total_pages); - spin_unlock(&page_pools.epp_lock); + spin_unlock(&page_pools.epp_lock); } static int enc_pools_add_pages(int npages) { - static DECLARE_MUTEX(sem_add_pages); - cfs_page_t ***pools; - int npools, alloced = 0; - int i, j, rc = -ENOMEM; + static DEFINE_MUTEX(add_pages_mutex); + cfs_page_t ***pools; + int npools, alloced = 0; + int i, j, rc = -ENOMEM; - if (npages < PTLRPC_MAX_BRW_PAGES) - npages = PTLRPC_MAX_BRW_PAGES; + if (npages < PTLRPC_MAX_BRW_PAGES) + npages = PTLRPC_MAX_BRW_PAGES; - down(&sem_add_pages); + mutex_lock(&add_pages_mutex); if (npages + page_pools.epp_total_pages > page_pools.epp_max_pages) npages = page_pools.epp_max_pages - page_pools.epp_total_pages; @@ -428,14 +420,15 @@ static int enc_pools_add_pages(int npages) goto out_pools; for (j = 0; j < PAGES_PER_POOL && alloced < npages; j++) { - pools[i][j] = cfs_alloc_page(CFS_ALLOC_IO | - CFS_ALLOC_HIGH); + pools[i][j] = cfs_alloc_page(CFS_ALLOC_IO | + CFS_ALLOC_HIGHMEM); if (pools[i][j] == NULL) goto out_pools; alloced++; } } + LASSERT(alloced == npages); enc_pools_insert(pools, npools, npages); CDEBUG(D_SEC, "added %d pages into pools\n", npages); @@ -450,7 +443,7 @@ out: CERROR("Failed to allocate %d enc pages\n", npages); } - up(&sem_add_pages); + mutex_unlock(&add_pages_mutex); return rc; } @@ -521,7 +514,7 @@ int sptlrpc_enc_pool_get_pages(struct ptlrpc_bulk_desc *desc) if (desc->bd_enc_iov == NULL) return -ENOMEM; - spin_lock(&page_pools.epp_lock); + spin_lock(&page_pools.epp_lock); page_pools.epp_st_access++; again: @@ -537,9 +530,9 @@ again: if (enc_pools_should_grow(desc->bd_iov_count, now)) { page_pools.epp_growing = 1; - spin_unlock(&page_pools.epp_lock); - enc_pools_add_pages(page_pools.epp_pages_short / 2); - spin_lock(&page_pools.epp_lock); + spin_unlock(&page_pools.epp_lock); + enc_pools_add_pages(page_pools.epp_pages_short / 2); + spin_lock(&page_pools.epp_lock); page_pools.epp_growing = 0; @@ -550,15 +543,15 @@ again: page_pools.epp_st_max_wqlen = page_pools.epp_waitqlen; - set_current_state(CFS_TASK_UNINT); + cfs_set_current_state(CFS_TASK_UNINT); cfs_waitlink_init(&waitlink); cfs_waitq_add(&page_pools.epp_waitq, &waitlink); - spin_unlock(&page_pools.epp_lock); - cfs_waitq_wait(&waitlink, CFS_TASK_UNINT); - cfs_waitq_del(&page_pools.epp_waitq, &waitlink); - LASSERT(page_pools.epp_waitqlen > 0); - spin_lock(&page_pools.epp_lock); + spin_unlock(&page_pools.epp_lock); + cfs_waitq_wait(&waitlink, CFS_TASK_UNINT); + cfs_waitq_del(&page_pools.epp_waitq, &waitlink); + LASSERT(page_pools.epp_waitqlen > 0); + spin_lock(&page_pools.epp_lock); page_pools.epp_waitqlen--; } @@ -610,8 +603,8 @@ again: page_pools.epp_last_access = cfs_time_current_sec(); - spin_unlock(&page_pools.epp_lock); - return 0; + spin_unlock(&page_pools.epp_lock); + return 0; } EXPORT_SYMBOL(sptlrpc_enc_pool_get_pages); @@ -625,7 +618,7 @@ void sptlrpc_enc_pool_put_pages(struct ptlrpc_bulk_desc *desc) LASSERT(desc->bd_iov_count > 0); - spin_lock(&page_pools.epp_lock); + spin_lock(&page_pools.epp_lock); p_idx = page_pools.epp_free_pages / PAGES_PER_POOL; g_idx = page_pools.epp_free_pages % PAGES_PER_POOL; @@ -652,11 +645,11 @@ void sptlrpc_enc_pool_put_pages(struct ptlrpc_bulk_desc *desc) enc_pools_wakeup(); - spin_unlock(&page_pools.epp_lock); + spin_unlock(&page_pools.epp_lock); - OBD_FREE(desc->bd_enc_iov, - desc->bd_iov_count * sizeof(*desc->bd_enc_iov)); - desc->bd_enc_iov = NULL; + OBD_FREE(desc->bd_enc_iov, + desc->bd_iov_count * sizeof(*desc->bd_enc_iov)); + desc->bd_enc_iov = NULL; } EXPORT_SYMBOL(sptlrpc_enc_pool_put_pages); @@ -667,25 +660,25 @@ EXPORT_SYMBOL(sptlrpc_enc_pool_put_pages); */ int sptlrpc_enc_pool_add_user(void) { - int need_grow = 0; - - spin_lock(&page_pools.epp_lock); - if (page_pools.epp_growing == 0 && page_pools.epp_total_pages == 0) { - page_pools.epp_growing = 1; - need_grow = 1; - } - spin_unlock(&page_pools.epp_lock); - - if (need_grow) { - enc_pools_add_pages(PTLRPC_MAX_BRW_PAGES + - PTLRPC_MAX_BRW_PAGES); - - spin_lock(&page_pools.epp_lock); - page_pools.epp_growing = 0; - enc_pools_wakeup(); - spin_unlock(&page_pools.epp_lock); - } - return 0; + int need_grow = 0; + + spin_lock(&page_pools.epp_lock); + if (page_pools.epp_growing == 0 && page_pools.epp_total_pages == 0) { + page_pools.epp_growing = 1; + need_grow = 1; + } + spin_unlock(&page_pools.epp_lock); + + if (need_grow) { + enc_pools_add_pages(PTLRPC_MAX_BRW_PAGES + + PTLRPC_MAX_BRW_PAGES); + + spin_lock(&page_pools.epp_lock); + page_pools.epp_growing = 0; + enc_pools_wakeup(); + spin_unlock(&page_pools.epp_lock); + } + return 0; } EXPORT_SYMBOL(sptlrpc_enc_pool_add_user); @@ -698,13 +691,9 @@ EXPORT_SYMBOL(sptlrpc_enc_pool_del_user); static inline void enc_pools_alloc(void) { LASSERT(page_pools.epp_max_pools); - /* - * on system with huge memory but small page size, this might lead to - * high-order allocation. but it's not common, and we suppose memory - * be not too much fragmented at module loading time. - */ - OBD_ALLOC(page_pools.epp_pools, - page_pools.epp_max_pools * sizeof(*page_pools.epp_pools)); + OBD_ALLOC_LARGE(page_pools.epp_pools, + page_pools.epp_max_pools * + sizeof(*page_pools.epp_pools)); } static inline void enc_pools_free(void) @@ -712,8 +701,9 @@ static inline void enc_pools_free(void) LASSERT(page_pools.epp_max_pools); LASSERT(page_pools.epp_pools); - OBD_FREE(page_pools.epp_pools, - page_pools.epp_max_pools * sizeof(*page_pools.epp_pools)); + OBD_FREE_LARGE(page_pools.epp_pools, + page_pools.epp_max_pools * + sizeof(*page_pools.epp_pools)); } int sptlrpc_enc_pool_init(void) @@ -722,7 +712,7 @@ int sptlrpc_enc_pool_init(void) * maximum capacity is 1/8 of total physical memory. * is the 1/8 a good number? */ - page_pools.epp_max_pages = num_physpages / 8; + page_pools.epp_max_pages = cfs_num_physpages / 8; page_pools.epp_max_pools = npages_to_npools(page_pools.epp_max_pages); cfs_waitq_init(&page_pools.epp_waitq); @@ -735,7 +725,7 @@ int sptlrpc_enc_pool_init(void) page_pools.epp_last_shrink = cfs_time_current_sec(); page_pools.epp_last_access = cfs_time_current_sec(); - spin_lock_init(&page_pools.epp_lock); + spin_lock_init(&page_pools.epp_lock); page_pools.epp_total_pages = 0; page_pools.epp_free_pages = 0; @@ -753,7 +743,8 @@ int sptlrpc_enc_pool_init(void) if (page_pools.epp_pools == NULL) return -ENOMEM; - pools_shrinker = set_shrinker(pools_shrinker_seeks, enc_pools_shrink); + pools_shrinker = cfs_set_shrinker(pools_shrinker_seeks, + enc_pools_shrink); if (pools_shrinker == NULL) { enc_pools_free(); return -ENOMEM; @@ -770,7 +761,7 @@ void sptlrpc_enc_pool_fini(void) LASSERT(page_pools.epp_pools); LASSERT(page_pools.epp_total_pages == page_pools.epp_free_pages); - remove_shrinker(pools_shrinker); + cfs_remove_shrinker(pools_shrinker); npools = npages_to_npools(page_pools.epp_total_pages); cleaned = enc_pools_cleanup(page_pools.epp_pools, npools); @@ -779,14 +770,15 @@ void sptlrpc_enc_pool_fini(void) enc_pools_free(); if (page_pools.epp_st_access > 0) { - CWARN("max pages %lu, grows %u, grow fails %u, shrinks %u, " - "access %lu, missing %lu, max qlen %u, max wait " - CFS_TIME_T"/%d\n", - page_pools.epp_st_max_pages, page_pools.epp_st_grows, - page_pools.epp_st_grow_fails, - page_pools.epp_st_shrinks, page_pools.epp_st_access, - page_pools.epp_st_missings, page_pools.epp_st_max_wqlen, - page_pools.epp_st_max_wait, HZ); + CDEBUG(D_SEC, + "max pages %lu, grows %u, grow fails %u, shrinks %u, " + "access %lu, missing %lu, max qlen %u, max wait " + CFS_TIME_T"/%d\n", + page_pools.epp_st_max_pages, page_pools.epp_st_grows, + page_pools.epp_st_grow_fails, + page_pools.epp_st_shrinks, page_pools.epp_st_access, + page_pools.epp_st_missings, page_pools.epp_st_max_wqlen, + page_pools.epp_st_max_wait, CFS_HZ); } } @@ -811,59 +803,29 @@ void sptlrpc_enc_pool_fini(void) } #endif -/**************************************** - * 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 }, +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, }; - -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) { - const struct sptlrpc_hash_type *ht; - - ht = sptlrpc_get_hash_type(hash_alg); - if (ht) - return ht->sht_name; - else - return "unknown"; + return cfs_crypto_hash_name(cfs_hash_alg_id[hash_alg]); } EXPORT_SYMBOL(sptlrpc_get_hash_name); __u8 sptlrpc_get_hash_alg(const char *algname) { - int i; - - for (i = 0; i < BULK_HASH_ALG_MAX; i++) - if (!strcmp(hash_types[i].sht_name, algname)) - break; - return i; + return cfs_crypto_hash_alg(algname); } EXPORT_SYMBOL(sptlrpc_get_hash_alg); -int bulk_sec_desc_unpack(struct lustre_msg *msg, int offset) +int bulk_sec_desc_unpack(struct lustre_msg *msg, int offset, int swabbed) { struct ptlrpc_bulk_sec_desc *bsd; int size = msg->lm_buflens[offset]; @@ -874,7 +836,7 @@ int bulk_sec_desc_unpack(struct lustre_msg *msg, int offset) return -EINVAL; } - if (lustre_msg_swabbed(msg)) { + if (swabbed) { __swab32s(&bsd->bsd_nob); } @@ -901,149 +863,52 @@ int bulk_sec_desc_unpack(struct lustre_msg *msg, int offset) } EXPORT_SYMBOL(bulk_sec_desc_unpack); -#ifdef __KERNEL__ - -#ifdef HAVE_ADLER -static int do_bulk_checksum_adler32(struct ptlrpc_bulk_desc *desc, void *buf) -{ - struct page *page; - int off; - char *ptr; - __u32 adler32 = 1; - 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; - - adler32 = adler32(adler32, ptr, len); - - cfs_kunmap(page); - } - - 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) +int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg, + void *buf, int buflen) { - 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; + struct cfs_crypto_hash_desc *hdesc; + int hashsize; + char hashbuf[64]; + unsigned int bufsize; + int i, err; - crc32 = crc32_le(crc32, ptr, len); + LASSERT(alg > BULK_HASH_ALG_NULL && alg < BULK_HASH_ALG_MAX); + LASSERT(buflen >= 4); - cfs_kunmap(page); - } + 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); + } - crc32 = cpu_to_le32(crc32); - memcpy(buf, &crc32, sizeof(crc32)); - return 0; -} + hashsize = cfs_crypto_hash_digestsize(cfs_hash_alg_id[alg]); -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); + 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); #else - CERROR("Adler32 not supported\n"); - return -EINVAL; + cfs_crypto_hash_update(hdesc, desc->bd_iov[i].iov_base, + desc->bd_iov[i].iov_len); #endif - 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++) { - sl.page = desc->bd_iov[i].kiov_page; - sl.offset = desc->bd_iov[i].kiov_offset; - sl.length = desc->bd_iov[i].kiov_len; - 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; + } + 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; } 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__ */