-#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)
-{
- 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;
-}
-
-static int do_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u32 alg, void *buf)
-{
- struct hash_desc hdesc;
- struct scatterlist *sl;
- int i, rc = 0, bytes = 0;
-
- LASSERT(alg > BULK_HASH_ALG_NULL &&
- alg < BULK_HASH_ALG_MAX);
-
- switch (alg) {
- case BULK_HASH_ALG_ADLER32:
-#ifdef HAVE_ADLER
- return do_bulk_checksum_adler32(desc, buf);
-#else
- CERROR("Adler32 not supported\n");
- return -EINVAL;
-#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;
-
- OBD_ALLOC(sl, sizeof(*sl) * desc->bd_iov_count);
- if (sl == NULL) {
- rc = -ENOMEM;
- goto out_tfm;
- }
-
- for (i = 0; i < desc->bd_iov_count; i++) {
- sl[i].page = desc->bd_iov[i].kiov_page;
- sl[i].offset = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK;
- sl[i].length = desc->bd_iov[i].kiov_len;
- bytes += desc->bd_iov[i].kiov_len;
- }
-
- ll_crypto_hash_init(&hdesc);
- ll_crypto_hash_update(&hdesc, sl, bytes);
- ll_crypto_hash_final(&hdesc, buf);
-
- OBD_FREE(sl, sizeof(*sl) * desc->bd_iov_count);
-
-out_tfm:
- ll_crypto_free_hash(hdesc.tfm);
- return rc;
-}
-
-#else /* !__KERNEL__ */
-
-static int do_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u32 alg, void *buf)
-{
- __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__ */
-
-/*
- * perform algorithm @alg checksum on @desc, store result in @buf.
- * if anything goes wrong, leave 'alg' be BULK_HASH_ALG_NULL.
- */
-static
-int generate_bulk_csum(struct ptlrpc_bulk_desc *desc, __u32 alg,
- struct ptlrpc_bulk_sec_desc *bsd, int bsdsize)
-{
- int rc;
-
- LASSERT(bsd);
- LASSERT(alg < BULK_HASH_ALG_MAX);
-
- bsd->bsd_hash_alg = BULK_HASH_ALG_NULL;
-
- if (alg == BULK_HASH_ALG_NULL)
- return 0;
-
- LASSERT(bsdsize >= sizeof(*bsd) + hash_types[alg].sht_size);
-
- rc = do_bulk_checksum(desc, alg, bsd->bsd_csum);
- if (rc == 0)
- bsd->bsd_hash_alg = alg;
-
- return rc;
-}
-
-static
-int verify_bulk_csum(struct ptlrpc_bulk_desc *desc, int read,
- struct ptlrpc_bulk_sec_desc *bsdv, int bsdvsize,
- struct ptlrpc_bulk_sec_desc *bsdr, int bsdrsize)
-{
- char *csum_p;
- char *buf = NULL;
- int csum_size, rc = 0;
-
- LASSERT(bsdv);
- LASSERT(bsdv->bsd_hash_alg < BULK_HASH_ALG_MAX);
-
- if (bsdr)
- bsdr->bsd_hash_alg = BULK_HASH_ALG_NULL;
-
- if (bsdv->bsd_hash_alg == BULK_HASH_ALG_NULL)
- return 0;
-
- /* for all supported algorithms */
- csum_size = hash_types[bsdv->bsd_hash_alg].sht_size;
-
- if (bsdvsize < sizeof(*bsdv) + csum_size) {
- CERROR("verifier size %d too small, require %d\n",
- bsdvsize, (int) sizeof(*bsdv) + csum_size);
- return -EINVAL;
- }
-
- if (bsdr) {
- LASSERT(bsdrsize >= sizeof(*bsdr) + csum_size);
- csum_p = (char *) bsdr->bsd_csum;
- } else {
- OBD_ALLOC(buf, csum_size);
- if (buf == NULL)
- return -EINVAL;
- csum_p = buf;
- }
-
- rc = do_bulk_checksum(desc, bsdv->bsd_hash_alg, csum_p);
-
- if (memcmp(bsdv->bsd_csum, csum_p, csum_size)) {
- CERROR("BAD %s CHECKSUM (%s), data mutated during "
- "transfer!\n", read ? "READ" : "WRITE",
- hash_types[bsdv->bsd_hash_alg].sht_name);
- rc = -EINVAL;
- } else {
- CDEBUG(D_SEC, "bulk %s checksum (%s) verified\n",
- read ? "read" : "write",
- hash_types[bsdv->bsd_hash_alg].sht_name);
- }
-
- if (bsdr) {
- bsdr->bsd_hash_alg = bsdv->bsd_hash_alg;
- memcpy(bsdr->bsd_csum, csum_p, csum_size);
- } else {
- LASSERT(buf);
- OBD_FREE(buf, csum_size);
- }
-
- return rc;
-}
-
-int bulk_csum_cli_request(struct ptlrpc_bulk_desc *desc, int read,
- __u32 alg, struct lustre_msg *rmsg, int roff)
-{
- struct ptlrpc_bulk_sec_desc *bsdr;
- int rsize, rc = 0;
-
- rsize = rmsg->lm_buflens[roff];
- bsdr = lustre_msg_buf(rmsg, roff, sizeof(*bsdr));
-
- LASSERT(bsdr);
- LASSERT(rsize >= sizeof(*bsdr));
- LASSERT(alg < BULK_HASH_ALG_MAX);
-
- if (read) {
- bsdr->bsd_hash_alg = alg;
- } else {
- rc = generate_bulk_csum(desc, alg, bsdr, rsize);
- if (rc)
- CERROR("bulk write: client failed to compute "
- "checksum: %d\n", rc);
-
- /* For sending we only compute the wrong checksum instead
- * of corrupting the data so it is still correct on a redo */
- if (rc == 0 && OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_SEND) &&
- bsdr->bsd_hash_alg != BULK_HASH_ALG_NULL)
- bsdr->bsd_csum[0] ^= 0x1;
- }
-
- return rc;
-}
-EXPORT_SYMBOL(bulk_csum_cli_request);
-
-int bulk_csum_cli_reply(struct ptlrpc_bulk_desc *desc, int read,
- struct lustre_msg *rmsg, int roff,
- struct lustre_msg *vmsg, int voff)