18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/* -*- mode: c; c-basic-offset: 8; -*-
38c2ecf20Sopenharmony_ci * vim: noexpandtab sw=8 ts=8 sts=0:
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * blockcheck.h
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Checksum and ECC codes for the OCFS2 userspace library.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Copyright (C) 2004, 2008 Oracle.  All rights reserved.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#ifndef OCFS2_BLOCKCHECK_H
138c2ecf20Sopenharmony_ci#define OCFS2_BLOCKCHECK_H
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci/* Count errors and error correction from blockcheck.c */
178c2ecf20Sopenharmony_cistruct ocfs2_blockcheck_stats {
188c2ecf20Sopenharmony_ci	spinlock_t b_lock;
198c2ecf20Sopenharmony_ci	u64 b_check_count;	/* Number of blocks we've checked */
208c2ecf20Sopenharmony_ci	u64 b_failure_count;	/* Number of failed checksums */
218c2ecf20Sopenharmony_ci	u64 b_recover_count;	/* Number of blocks fixed by ecc */
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	/*
248c2ecf20Sopenharmony_ci	 * debugfs entries, used if this is passed to
258c2ecf20Sopenharmony_ci	 * ocfs2_blockcheck_stats_debugfs_install()
268c2ecf20Sopenharmony_ci	 */
278c2ecf20Sopenharmony_ci	struct dentry *b_debug_dir;	/* Parent of the debugfs  files */
288c2ecf20Sopenharmony_ci};
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/* High level block API */
328c2ecf20Sopenharmony_civoid ocfs2_compute_meta_ecc(struct super_block *sb, void *data,
338c2ecf20Sopenharmony_ci			    struct ocfs2_block_check *bc);
348c2ecf20Sopenharmony_ciint ocfs2_validate_meta_ecc(struct super_block *sb, void *data,
358c2ecf20Sopenharmony_ci			    struct ocfs2_block_check *bc);
368c2ecf20Sopenharmony_civoid ocfs2_compute_meta_ecc_bhs(struct super_block *sb,
378c2ecf20Sopenharmony_ci				struct buffer_head **bhs, int nr,
388c2ecf20Sopenharmony_ci				struct ocfs2_block_check *bc);
398c2ecf20Sopenharmony_ciint ocfs2_validate_meta_ecc_bhs(struct super_block *sb,
408c2ecf20Sopenharmony_ci				struct buffer_head **bhs, int nr,
418c2ecf20Sopenharmony_ci				struct ocfs2_block_check *bc);
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/* Lower level API */
448c2ecf20Sopenharmony_civoid ocfs2_block_check_compute(void *data, size_t blocksize,
458c2ecf20Sopenharmony_ci			       struct ocfs2_block_check *bc);
468c2ecf20Sopenharmony_ciint ocfs2_block_check_validate(void *data, size_t blocksize,
478c2ecf20Sopenharmony_ci			       struct ocfs2_block_check *bc,
488c2ecf20Sopenharmony_ci			       struct ocfs2_blockcheck_stats *stats);
498c2ecf20Sopenharmony_civoid ocfs2_block_check_compute_bhs(struct buffer_head **bhs, int nr,
508c2ecf20Sopenharmony_ci				   struct ocfs2_block_check *bc);
518c2ecf20Sopenharmony_ciint ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr,
528c2ecf20Sopenharmony_ci				   struct ocfs2_block_check *bc,
538c2ecf20Sopenharmony_ci				   struct ocfs2_blockcheck_stats *stats);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/* Debug Initialization */
568c2ecf20Sopenharmony_civoid ocfs2_blockcheck_stats_debugfs_install(struct ocfs2_blockcheck_stats *stats,
578c2ecf20Sopenharmony_ci					    struct dentry *parent);
588c2ecf20Sopenharmony_civoid ocfs2_blockcheck_stats_debugfs_remove(struct ocfs2_blockcheck_stats *stats);
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci/*
618c2ecf20Sopenharmony_ci * Hamming code functions
628c2ecf20Sopenharmony_ci */
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci/*
658c2ecf20Sopenharmony_ci * Encoding hamming code parity bits for a buffer.
668c2ecf20Sopenharmony_ci *
678c2ecf20Sopenharmony_ci * This is the low level encoder function.  It can be called across
688c2ecf20Sopenharmony_ci * multiple hunks just like the crc32 code.  'd' is the number of bits
698c2ecf20Sopenharmony_ci * _in_this_hunk_.  nr is the bit offset of this hunk.  So, if you had
708c2ecf20Sopenharmony_ci * two 512B buffers, you would do it like so:
718c2ecf20Sopenharmony_ci *
728c2ecf20Sopenharmony_ci * parity = ocfs2_hamming_encode(0, buf1, 512 * 8, 0);
738c2ecf20Sopenharmony_ci * parity = ocfs2_hamming_encode(parity, buf2, 512 * 8, 512 * 8);
748c2ecf20Sopenharmony_ci *
758c2ecf20Sopenharmony_ci * If you just have one buffer, use ocfs2_hamming_encode_block().
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_ciu32 ocfs2_hamming_encode(u32 parity, void *data, unsigned int d,
788c2ecf20Sopenharmony_ci			 unsigned int nr);
798c2ecf20Sopenharmony_ci/*
808c2ecf20Sopenharmony_ci * Fix a buffer with a bit error.  The 'fix' is the original parity
818c2ecf20Sopenharmony_ci * xor'd with the parity calculated now.
828c2ecf20Sopenharmony_ci *
838c2ecf20Sopenharmony_ci * Like ocfs2_hamming_encode(), this can handle hunks.  nr is the bit
848c2ecf20Sopenharmony_ci * offset of the current hunk.  If bit to be fixed is not part of the
858c2ecf20Sopenharmony_ci * current hunk, this does nothing.
868c2ecf20Sopenharmony_ci *
878c2ecf20Sopenharmony_ci * If you only have one buffer, use ocfs2_hamming_fix_block().
888c2ecf20Sopenharmony_ci */
898c2ecf20Sopenharmony_civoid ocfs2_hamming_fix(void *data, unsigned int d, unsigned int nr,
908c2ecf20Sopenharmony_ci		       unsigned int fix);
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci/* Convenience wrappers for a single buffer of data */
938c2ecf20Sopenharmony_ciextern u32 ocfs2_hamming_encode_block(void *data, unsigned int blocksize);
948c2ecf20Sopenharmony_ciextern void ocfs2_hamming_fix_block(void *data, unsigned int blocksize,
958c2ecf20Sopenharmony_ci				    unsigned int fix);
968c2ecf20Sopenharmony_ci#endif
97