xref: /OK3568_Linux_fs/kernel/fs/ocfs2/blockcheck.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /* -*- mode: c; c-basic-offset: 8; -*-
3*4882a593Smuzhiyun  * vim: noexpandtab sw=8 ts=8 sts=0:
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * blockcheck.h
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Checksum and ECC codes for the OCFS2 userspace library.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * Copyright (C) 2004, 2008 Oracle.  All rights reserved.
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #ifndef OCFS2_BLOCKCHECK_H
13*4882a593Smuzhiyun #define OCFS2_BLOCKCHECK_H
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun /* Count errors and error correction from blockcheck.c */
17*4882a593Smuzhiyun struct ocfs2_blockcheck_stats {
18*4882a593Smuzhiyun 	spinlock_t b_lock;
19*4882a593Smuzhiyun 	u64 b_check_count;	/* Number of blocks we've checked */
20*4882a593Smuzhiyun 	u64 b_failure_count;	/* Number of failed checksums */
21*4882a593Smuzhiyun 	u64 b_recover_count;	/* Number of blocks fixed by ecc */
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 	/*
24*4882a593Smuzhiyun 	 * debugfs entries, used if this is passed to
25*4882a593Smuzhiyun 	 * ocfs2_blockcheck_stats_debugfs_install()
26*4882a593Smuzhiyun 	 */
27*4882a593Smuzhiyun 	struct dentry *b_debug_dir;	/* Parent of the debugfs  files */
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun /* High level block API */
32*4882a593Smuzhiyun void ocfs2_compute_meta_ecc(struct super_block *sb, void *data,
33*4882a593Smuzhiyun 			    struct ocfs2_block_check *bc);
34*4882a593Smuzhiyun int ocfs2_validate_meta_ecc(struct super_block *sb, void *data,
35*4882a593Smuzhiyun 			    struct ocfs2_block_check *bc);
36*4882a593Smuzhiyun void ocfs2_compute_meta_ecc_bhs(struct super_block *sb,
37*4882a593Smuzhiyun 				struct buffer_head **bhs, int nr,
38*4882a593Smuzhiyun 				struct ocfs2_block_check *bc);
39*4882a593Smuzhiyun int ocfs2_validate_meta_ecc_bhs(struct super_block *sb,
40*4882a593Smuzhiyun 				struct buffer_head **bhs, int nr,
41*4882a593Smuzhiyun 				struct ocfs2_block_check *bc);
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun /* Lower level API */
44*4882a593Smuzhiyun void ocfs2_block_check_compute(void *data, size_t blocksize,
45*4882a593Smuzhiyun 			       struct ocfs2_block_check *bc);
46*4882a593Smuzhiyun int ocfs2_block_check_validate(void *data, size_t blocksize,
47*4882a593Smuzhiyun 			       struct ocfs2_block_check *bc,
48*4882a593Smuzhiyun 			       struct ocfs2_blockcheck_stats *stats);
49*4882a593Smuzhiyun void ocfs2_block_check_compute_bhs(struct buffer_head **bhs, int nr,
50*4882a593Smuzhiyun 				   struct ocfs2_block_check *bc);
51*4882a593Smuzhiyun int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr,
52*4882a593Smuzhiyun 				   struct ocfs2_block_check *bc,
53*4882a593Smuzhiyun 				   struct ocfs2_blockcheck_stats *stats);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun /* Debug Initialization */
56*4882a593Smuzhiyun void ocfs2_blockcheck_stats_debugfs_install(struct ocfs2_blockcheck_stats *stats,
57*4882a593Smuzhiyun 					    struct dentry *parent);
58*4882a593Smuzhiyun void ocfs2_blockcheck_stats_debugfs_remove(struct ocfs2_blockcheck_stats *stats);
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /*
61*4882a593Smuzhiyun  * Hamming code functions
62*4882a593Smuzhiyun  */
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun /*
65*4882a593Smuzhiyun  * Encoding hamming code parity bits for a buffer.
66*4882a593Smuzhiyun  *
67*4882a593Smuzhiyun  * This is the low level encoder function.  It can be called across
68*4882a593Smuzhiyun  * multiple hunks just like the crc32 code.  'd' is the number of bits
69*4882a593Smuzhiyun  * _in_this_hunk_.  nr is the bit offset of this hunk.  So, if you had
70*4882a593Smuzhiyun  * two 512B buffers, you would do it like so:
71*4882a593Smuzhiyun  *
72*4882a593Smuzhiyun  * parity = ocfs2_hamming_encode(0, buf1, 512 * 8, 0);
73*4882a593Smuzhiyun  * parity = ocfs2_hamming_encode(parity, buf2, 512 * 8, 512 * 8);
74*4882a593Smuzhiyun  *
75*4882a593Smuzhiyun  * If you just have one buffer, use ocfs2_hamming_encode_block().
76*4882a593Smuzhiyun  */
77*4882a593Smuzhiyun u32 ocfs2_hamming_encode(u32 parity, void *data, unsigned int d,
78*4882a593Smuzhiyun 			 unsigned int nr);
79*4882a593Smuzhiyun /*
80*4882a593Smuzhiyun  * Fix a buffer with a bit error.  The 'fix' is the original parity
81*4882a593Smuzhiyun  * xor'd with the parity calculated now.
82*4882a593Smuzhiyun  *
83*4882a593Smuzhiyun  * Like ocfs2_hamming_encode(), this can handle hunks.  nr is the bit
84*4882a593Smuzhiyun  * offset of the current hunk.  If bit to be fixed is not part of the
85*4882a593Smuzhiyun  * current hunk, this does nothing.
86*4882a593Smuzhiyun  *
87*4882a593Smuzhiyun  * If you only have one buffer, use ocfs2_hamming_fix_block().
88*4882a593Smuzhiyun  */
89*4882a593Smuzhiyun void ocfs2_hamming_fix(void *data, unsigned int d, unsigned int nr,
90*4882a593Smuzhiyun 		       unsigned int fix);
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /* Convenience wrappers for a single buffer of data */
93*4882a593Smuzhiyun extern u32 ocfs2_hamming_encode_block(void *data, unsigned int blocksize);
94*4882a593Smuzhiyun extern void ocfs2_hamming_fix_block(void *data, unsigned int blocksize,
95*4882a593Smuzhiyun 				    unsigned int fix);
96*4882a593Smuzhiyun #endif
97