xref: /OK3568_Linux_fs/kernel/fs/ocfs2/blockcheck.c (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.c
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Checksum and ECC codes for the OCFS2 userspace library.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * Copyright (C) 2006, 2008 Oracle.  All rights reserved.
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/kernel.h>
13*4882a593Smuzhiyun #include <linux/types.h>
14*4882a593Smuzhiyun #include <linux/crc32.h>
15*4882a593Smuzhiyun #include <linux/buffer_head.h>
16*4882a593Smuzhiyun #include <linux/bitops.h>
17*4882a593Smuzhiyun #include <linux/debugfs.h>
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <linux/fs.h>
20*4882a593Smuzhiyun #include <asm/byteorder.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #include <cluster/masklog.h>
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #include "ocfs2.h"
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #include "blockcheck.h"
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /*
30*4882a593Smuzhiyun  * We use the following conventions:
31*4882a593Smuzhiyun  *
32*4882a593Smuzhiyun  * d = # data bits
33*4882a593Smuzhiyun  * p = # parity bits
34*4882a593Smuzhiyun  * c = # total code bits (d + p)
35*4882a593Smuzhiyun  */
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /*
39*4882a593Smuzhiyun  * Calculate the bit offset in the hamming code buffer based on the bit's
40*4882a593Smuzhiyun  * offset in the data buffer.  Since the hamming code reserves all
41*4882a593Smuzhiyun  * power-of-two bits for parity, the data bit number and the code bit
42*4882a593Smuzhiyun  * number are offset by all the parity bits beforehand.
43*4882a593Smuzhiyun  *
44*4882a593Smuzhiyun  * Recall that bit numbers in hamming code are 1-based.  This function
45*4882a593Smuzhiyun  * takes the 0-based data bit from the caller.
46*4882a593Smuzhiyun  *
47*4882a593Smuzhiyun  * An example.  Take bit 1 of the data buffer.  1 is a power of two (2^0),
48*4882a593Smuzhiyun  * so it's a parity bit.  2 is a power of two (2^1), so it's a parity bit.
49*4882a593Smuzhiyun  * 3 is not a power of two.  So bit 1 of the data buffer ends up as bit 3
50*4882a593Smuzhiyun  * in the code buffer.
51*4882a593Smuzhiyun  *
52*4882a593Smuzhiyun  * The caller can pass in *p if it wants to keep track of the most recent
53*4882a593Smuzhiyun  * number of parity bits added.  This allows the function to start the
54*4882a593Smuzhiyun  * calculation at the last place.
55*4882a593Smuzhiyun  */
calc_code_bit(unsigned int i,unsigned int * p_cache)56*4882a593Smuzhiyun static unsigned int calc_code_bit(unsigned int i, unsigned int *p_cache)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun 	unsigned int b, p = 0;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	/*
61*4882a593Smuzhiyun 	 * Data bits are 0-based, but we're talking code bits, which
62*4882a593Smuzhiyun 	 * are 1-based.
63*4882a593Smuzhiyun 	 */
64*4882a593Smuzhiyun 	b = i + 1;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	/* Use the cache if it is there */
67*4882a593Smuzhiyun 	if (p_cache)
68*4882a593Smuzhiyun 		p = *p_cache;
69*4882a593Smuzhiyun         b += p;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	/*
72*4882a593Smuzhiyun 	 * For every power of two below our bit number, bump our bit.
73*4882a593Smuzhiyun 	 *
74*4882a593Smuzhiyun 	 * We compare with (b + 1) because we have to compare with what b
75*4882a593Smuzhiyun 	 * would be _if_ it were bumped up by the parity bit.  Capice?
76*4882a593Smuzhiyun 	 *
77*4882a593Smuzhiyun 	 * p is set above.
78*4882a593Smuzhiyun 	 */
79*4882a593Smuzhiyun 	for (; (1 << p) < (b + 1); p++)
80*4882a593Smuzhiyun 		b++;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	if (p_cache)
83*4882a593Smuzhiyun 		*p_cache = p;
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	return b;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /*
89*4882a593Smuzhiyun  * This is the low level encoder function.  It can be called across
90*4882a593Smuzhiyun  * multiple hunks just like the crc32 code.  'd' is the number of bits
91*4882a593Smuzhiyun  * _in_this_hunk_.  nr is the bit offset of this hunk.  So, if you had
92*4882a593Smuzhiyun  * two 512B buffers, you would do it like so:
93*4882a593Smuzhiyun  *
94*4882a593Smuzhiyun  * parity = ocfs2_hamming_encode(0, buf1, 512 * 8, 0);
95*4882a593Smuzhiyun  * parity = ocfs2_hamming_encode(parity, buf2, 512 * 8, 512 * 8);
96*4882a593Smuzhiyun  *
97*4882a593Smuzhiyun  * If you just have one buffer, use ocfs2_hamming_encode_block().
98*4882a593Smuzhiyun  */
ocfs2_hamming_encode(u32 parity,void * data,unsigned int d,unsigned int nr)99*4882a593Smuzhiyun u32 ocfs2_hamming_encode(u32 parity, void *data, unsigned int d, unsigned int nr)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	unsigned int i, b, p = 0;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	BUG_ON(!d);
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	/*
106*4882a593Smuzhiyun 	 * b is the hamming code bit number.  Hamming code specifies a
107*4882a593Smuzhiyun 	 * 1-based array, but C uses 0-based.  So 'i' is for C, and 'b' is
108*4882a593Smuzhiyun 	 * for the algorithm.
109*4882a593Smuzhiyun 	 *
110*4882a593Smuzhiyun 	 * The i++ in the for loop is so that the start offset passed
111*4882a593Smuzhiyun 	 * to ocfs2_find_next_bit_set() is one greater than the previously
112*4882a593Smuzhiyun 	 * found bit.
113*4882a593Smuzhiyun 	 */
114*4882a593Smuzhiyun 	for (i = 0; (i = ocfs2_find_next_bit(data, d, i)) < d; i++)
115*4882a593Smuzhiyun 	{
116*4882a593Smuzhiyun 		/*
117*4882a593Smuzhiyun 		 * i is the offset in this hunk, nr + i is the total bit
118*4882a593Smuzhiyun 		 * offset.
119*4882a593Smuzhiyun 		 */
120*4882a593Smuzhiyun 		b = calc_code_bit(nr + i, &p);
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 		/*
123*4882a593Smuzhiyun 		 * Data bits in the resultant code are checked by
124*4882a593Smuzhiyun 		 * parity bits that are part of the bit number
125*4882a593Smuzhiyun 		 * representation.  Huh?
126*4882a593Smuzhiyun 		 *
127*4882a593Smuzhiyun 		 * <wikipedia href="https://en.wikipedia.org/wiki/Hamming_code">
128*4882a593Smuzhiyun 		 * In other words, the parity bit at position 2^k
129*4882a593Smuzhiyun 		 * checks bits in positions having bit k set in
130*4882a593Smuzhiyun 		 * their binary representation.  Conversely, for
131*4882a593Smuzhiyun 		 * instance, bit 13, i.e. 1101(2), is checked by
132*4882a593Smuzhiyun 		 * bits 1000(2) = 8, 0100(2)=4 and 0001(2) = 1.
133*4882a593Smuzhiyun 		 * </wikipedia>
134*4882a593Smuzhiyun 		 *
135*4882a593Smuzhiyun 		 * Note that 'k' is the _code_ bit number.  'b' in
136*4882a593Smuzhiyun 		 * our loop.
137*4882a593Smuzhiyun 		 */
138*4882a593Smuzhiyun 		parity ^= b;
139*4882a593Smuzhiyun 	}
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	/* While the data buffer was treated as little endian, the
142*4882a593Smuzhiyun 	 * return value is in host endian. */
143*4882a593Smuzhiyun 	return parity;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun 
ocfs2_hamming_encode_block(void * data,unsigned int blocksize)146*4882a593Smuzhiyun u32 ocfs2_hamming_encode_block(void *data, unsigned int blocksize)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun 	return ocfs2_hamming_encode(0, data, blocksize * 8, 0);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun /*
152*4882a593Smuzhiyun  * Like ocfs2_hamming_encode(), this can handle hunks.  nr is the bit
153*4882a593Smuzhiyun  * offset of the current hunk.  If bit to be fixed is not part of the
154*4882a593Smuzhiyun  * current hunk, this does nothing.
155*4882a593Smuzhiyun  *
156*4882a593Smuzhiyun  * If you only have one hunk, use ocfs2_hamming_fix_block().
157*4882a593Smuzhiyun  */
ocfs2_hamming_fix(void * data,unsigned int d,unsigned int nr,unsigned int fix)158*4882a593Smuzhiyun void ocfs2_hamming_fix(void *data, unsigned int d, unsigned int nr,
159*4882a593Smuzhiyun 		       unsigned int fix)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	unsigned int i, b;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	BUG_ON(!d);
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	/*
166*4882a593Smuzhiyun 	 * If the bit to fix has an hweight of 1, it's a parity bit.  One
167*4882a593Smuzhiyun 	 * busted parity bit is its own error.  Nothing to do here.
168*4882a593Smuzhiyun 	 */
169*4882a593Smuzhiyun 	if (hweight32(fix) == 1)
170*4882a593Smuzhiyun 		return;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	/*
173*4882a593Smuzhiyun 	 * nr + d is the bit right past the data hunk we're looking at.
174*4882a593Smuzhiyun 	 * If fix after that, nothing to do
175*4882a593Smuzhiyun 	 */
176*4882a593Smuzhiyun 	if (fix >= calc_code_bit(nr + d, NULL))
177*4882a593Smuzhiyun 		return;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	/*
180*4882a593Smuzhiyun 	 * nr is the offset in the data hunk we're starting at.  Let's
181*4882a593Smuzhiyun 	 * start b at the offset in the code buffer.  See hamming_encode()
182*4882a593Smuzhiyun 	 * for a more detailed description of 'b'.
183*4882a593Smuzhiyun 	 */
184*4882a593Smuzhiyun 	b = calc_code_bit(nr, NULL);
185*4882a593Smuzhiyun 	/* If the fix is before this hunk, nothing to do */
186*4882a593Smuzhiyun 	if (fix < b)
187*4882a593Smuzhiyun 		return;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	for (i = 0; i < d; i++, b++)
190*4882a593Smuzhiyun 	{
191*4882a593Smuzhiyun 		/* Skip past parity bits */
192*4882a593Smuzhiyun 		while (hweight32(b) == 1)
193*4882a593Smuzhiyun 			b++;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 		/*
196*4882a593Smuzhiyun 		 * i is the offset in this data hunk.
197*4882a593Smuzhiyun 		 * nr + i is the offset in the total data buffer.
198*4882a593Smuzhiyun 		 * b is the offset in the total code buffer.
199*4882a593Smuzhiyun 		 *
200*4882a593Smuzhiyun 		 * Thus, when b == fix, bit i in the current hunk needs
201*4882a593Smuzhiyun 		 * fixing.
202*4882a593Smuzhiyun 		 */
203*4882a593Smuzhiyun 		if (b == fix)
204*4882a593Smuzhiyun 		{
205*4882a593Smuzhiyun 			if (ocfs2_test_bit(i, data))
206*4882a593Smuzhiyun 				ocfs2_clear_bit(i, data);
207*4882a593Smuzhiyun 			else
208*4882a593Smuzhiyun 				ocfs2_set_bit(i, data);
209*4882a593Smuzhiyun 			break;
210*4882a593Smuzhiyun 		}
211*4882a593Smuzhiyun 	}
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun 
ocfs2_hamming_fix_block(void * data,unsigned int blocksize,unsigned int fix)214*4882a593Smuzhiyun void ocfs2_hamming_fix_block(void *data, unsigned int blocksize,
215*4882a593Smuzhiyun 			     unsigned int fix)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun 	ocfs2_hamming_fix(data, blocksize * 8, 0, fix);
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun /*
222*4882a593Smuzhiyun  * Debugfs handling.
223*4882a593Smuzhiyun  */
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
226*4882a593Smuzhiyun 
blockcheck_u64_get(void * data,u64 * val)227*4882a593Smuzhiyun static int blockcheck_u64_get(void *data, u64 *val)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun 	*val = *(u64 *)data;
230*4882a593Smuzhiyun 	return 0;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun DEFINE_SIMPLE_ATTRIBUTE(blockcheck_fops, blockcheck_u64_get, NULL, "%llu\n");
233*4882a593Smuzhiyun 
ocfs2_blockcheck_debug_remove(struct ocfs2_blockcheck_stats * stats)234*4882a593Smuzhiyun static void ocfs2_blockcheck_debug_remove(struct ocfs2_blockcheck_stats *stats)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun 	if (stats) {
237*4882a593Smuzhiyun 		debugfs_remove_recursive(stats->b_debug_dir);
238*4882a593Smuzhiyun 		stats->b_debug_dir = NULL;
239*4882a593Smuzhiyun 	}
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun 
ocfs2_blockcheck_debug_install(struct ocfs2_blockcheck_stats * stats,struct dentry * parent)242*4882a593Smuzhiyun static void ocfs2_blockcheck_debug_install(struct ocfs2_blockcheck_stats *stats,
243*4882a593Smuzhiyun 					   struct dentry *parent)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	struct dentry *dir;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	dir = debugfs_create_dir("blockcheck", parent);
248*4882a593Smuzhiyun 	stats->b_debug_dir = dir;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	debugfs_create_file("blocks_checked", S_IFREG | S_IRUSR, dir,
251*4882a593Smuzhiyun 			    &stats->b_check_count, &blockcheck_fops);
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	debugfs_create_file("checksums_failed", S_IFREG | S_IRUSR, dir,
254*4882a593Smuzhiyun 			    &stats->b_failure_count, &blockcheck_fops);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	debugfs_create_file("ecc_recoveries", S_IFREG | S_IRUSR, dir,
257*4882a593Smuzhiyun 			    &stats->b_recover_count, &blockcheck_fops);
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun #else
ocfs2_blockcheck_debug_install(struct ocfs2_blockcheck_stats * stats,struct dentry * parent)261*4882a593Smuzhiyun static inline void ocfs2_blockcheck_debug_install(struct ocfs2_blockcheck_stats *stats,
262*4882a593Smuzhiyun 						  struct dentry *parent)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
ocfs2_blockcheck_debug_remove(struct ocfs2_blockcheck_stats * stats)266*4882a593Smuzhiyun static inline void ocfs2_blockcheck_debug_remove(struct ocfs2_blockcheck_stats *stats)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun #endif  /* CONFIG_DEBUG_FS */
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun /* Always-called wrappers for starting and stopping the debugfs files */
ocfs2_blockcheck_stats_debugfs_install(struct ocfs2_blockcheck_stats * stats,struct dentry * parent)272*4882a593Smuzhiyun void ocfs2_blockcheck_stats_debugfs_install(struct ocfs2_blockcheck_stats *stats,
273*4882a593Smuzhiyun 					    struct dentry *parent)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun 	ocfs2_blockcheck_debug_install(stats, parent);
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun 
ocfs2_blockcheck_stats_debugfs_remove(struct ocfs2_blockcheck_stats * stats)278*4882a593Smuzhiyun void ocfs2_blockcheck_stats_debugfs_remove(struct ocfs2_blockcheck_stats *stats)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun 	ocfs2_blockcheck_debug_remove(stats);
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
ocfs2_blockcheck_inc_check(struct ocfs2_blockcheck_stats * stats)283*4882a593Smuzhiyun static void ocfs2_blockcheck_inc_check(struct ocfs2_blockcheck_stats *stats)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	u64 new_count;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	if (!stats)
288*4882a593Smuzhiyun 		return;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	spin_lock(&stats->b_lock);
291*4882a593Smuzhiyun 	stats->b_check_count++;
292*4882a593Smuzhiyun 	new_count = stats->b_check_count;
293*4882a593Smuzhiyun 	spin_unlock(&stats->b_lock);
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	if (!new_count)
296*4882a593Smuzhiyun 		mlog(ML_NOTICE, "Block check count has wrapped\n");
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun 
ocfs2_blockcheck_inc_failure(struct ocfs2_blockcheck_stats * stats)299*4882a593Smuzhiyun static void ocfs2_blockcheck_inc_failure(struct ocfs2_blockcheck_stats *stats)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun 	u64 new_count;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	if (!stats)
304*4882a593Smuzhiyun 		return;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	spin_lock(&stats->b_lock);
307*4882a593Smuzhiyun 	stats->b_failure_count++;
308*4882a593Smuzhiyun 	new_count = stats->b_failure_count;
309*4882a593Smuzhiyun 	spin_unlock(&stats->b_lock);
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	if (!new_count)
312*4882a593Smuzhiyun 		mlog(ML_NOTICE, "Checksum failure count has wrapped\n");
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun 
ocfs2_blockcheck_inc_recover(struct ocfs2_blockcheck_stats * stats)315*4882a593Smuzhiyun static void ocfs2_blockcheck_inc_recover(struct ocfs2_blockcheck_stats *stats)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun 	u64 new_count;
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	if (!stats)
320*4882a593Smuzhiyun 		return;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	spin_lock(&stats->b_lock);
323*4882a593Smuzhiyun 	stats->b_recover_count++;
324*4882a593Smuzhiyun 	new_count = stats->b_recover_count;
325*4882a593Smuzhiyun 	spin_unlock(&stats->b_lock);
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	if (!new_count)
328*4882a593Smuzhiyun 		mlog(ML_NOTICE, "ECC recovery count has wrapped\n");
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun /*
334*4882a593Smuzhiyun  * These are the low-level APIs for using the ocfs2_block_check structure.
335*4882a593Smuzhiyun  */
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun /*
338*4882a593Smuzhiyun  * This function generates check information for a block.
339*4882a593Smuzhiyun  * data is the block to be checked.  bc is a pointer to the
340*4882a593Smuzhiyun  * ocfs2_block_check structure describing the crc32 and the ecc.
341*4882a593Smuzhiyun  *
342*4882a593Smuzhiyun  * bc should be a pointer inside data, as the function will
343*4882a593Smuzhiyun  * take care of zeroing it before calculating the check information.  If
344*4882a593Smuzhiyun  * bc does not point inside data, the caller must make sure any inline
345*4882a593Smuzhiyun  * ocfs2_block_check structures are zeroed.
346*4882a593Smuzhiyun  *
347*4882a593Smuzhiyun  * The data buffer must be in on-disk endian (little endian for ocfs2).
348*4882a593Smuzhiyun  * bc will be filled with little-endian values and will be ready to go to
349*4882a593Smuzhiyun  * disk.
350*4882a593Smuzhiyun  */
ocfs2_block_check_compute(void * data,size_t blocksize,struct ocfs2_block_check * bc)351*4882a593Smuzhiyun void ocfs2_block_check_compute(void *data, size_t blocksize,
352*4882a593Smuzhiyun 			       struct ocfs2_block_check *bc)
353*4882a593Smuzhiyun {
354*4882a593Smuzhiyun 	u32 crc;
355*4882a593Smuzhiyun 	u32 ecc;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	memset(bc, 0, sizeof(struct ocfs2_block_check));
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	crc = crc32_le(~0, data, blocksize);
360*4882a593Smuzhiyun 	ecc = ocfs2_hamming_encode_block(data, blocksize);
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	/*
363*4882a593Smuzhiyun 	 * No ecc'd ocfs2 structure is larger than 4K, so ecc will be no
364*4882a593Smuzhiyun 	 * larger than 16 bits.
365*4882a593Smuzhiyun 	 */
366*4882a593Smuzhiyun 	BUG_ON(ecc > USHRT_MAX);
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	bc->bc_crc32e = cpu_to_le32(crc);
369*4882a593Smuzhiyun 	bc->bc_ecc = cpu_to_le16((u16)ecc);
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun /*
373*4882a593Smuzhiyun  * This function validates existing check information.  Like _compute,
374*4882a593Smuzhiyun  * the function will take care of zeroing bc before calculating check codes.
375*4882a593Smuzhiyun  * If bc is not a pointer inside data, the caller must have zeroed any
376*4882a593Smuzhiyun  * inline ocfs2_block_check structures.
377*4882a593Smuzhiyun  *
378*4882a593Smuzhiyun  * Again, the data passed in should be the on-disk endian.
379*4882a593Smuzhiyun  */
ocfs2_block_check_validate(void * data,size_t blocksize,struct ocfs2_block_check * bc,struct ocfs2_blockcheck_stats * stats)380*4882a593Smuzhiyun int ocfs2_block_check_validate(void *data, size_t blocksize,
381*4882a593Smuzhiyun 			       struct ocfs2_block_check *bc,
382*4882a593Smuzhiyun 			       struct ocfs2_blockcheck_stats *stats)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	int rc = 0;
385*4882a593Smuzhiyun 	u32 bc_crc32e;
386*4882a593Smuzhiyun 	u16 bc_ecc;
387*4882a593Smuzhiyun 	u32 crc, ecc;
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	ocfs2_blockcheck_inc_check(stats);
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	bc_crc32e = le32_to_cpu(bc->bc_crc32e);
392*4882a593Smuzhiyun 	bc_ecc = le16_to_cpu(bc->bc_ecc);
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	memset(bc, 0, sizeof(struct ocfs2_block_check));
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	/* Fast path - if the crc32 validates, we're good to go */
397*4882a593Smuzhiyun 	crc = crc32_le(~0, data, blocksize);
398*4882a593Smuzhiyun 	if (crc == bc_crc32e)
399*4882a593Smuzhiyun 		goto out;
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	ocfs2_blockcheck_inc_failure(stats);
402*4882a593Smuzhiyun 	mlog(ML_ERROR,
403*4882a593Smuzhiyun 	     "CRC32 failed: stored: 0x%x, computed 0x%x. Applying ECC.\n",
404*4882a593Smuzhiyun 	     (unsigned int)bc_crc32e, (unsigned int)crc);
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	/* Ok, try ECC fixups */
407*4882a593Smuzhiyun 	ecc = ocfs2_hamming_encode_block(data, blocksize);
408*4882a593Smuzhiyun 	ocfs2_hamming_fix_block(data, blocksize, ecc ^ bc_ecc);
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	/* And check the crc32 again */
411*4882a593Smuzhiyun 	crc = crc32_le(~0, data, blocksize);
412*4882a593Smuzhiyun 	if (crc == bc_crc32e) {
413*4882a593Smuzhiyun 		ocfs2_blockcheck_inc_recover(stats);
414*4882a593Smuzhiyun 		goto out;
415*4882a593Smuzhiyun 	}
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	mlog(ML_ERROR, "Fixed CRC32 failed: stored: 0x%x, computed 0x%x\n",
418*4882a593Smuzhiyun 	     (unsigned int)bc_crc32e, (unsigned int)crc);
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 	rc = -EIO;
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun out:
423*4882a593Smuzhiyun 	bc->bc_crc32e = cpu_to_le32(bc_crc32e);
424*4882a593Smuzhiyun 	bc->bc_ecc = cpu_to_le16(bc_ecc);
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	return rc;
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun /*
430*4882a593Smuzhiyun  * This function generates check information for a list of buffer_heads.
431*4882a593Smuzhiyun  * bhs is the blocks to be checked.  bc is a pointer to the
432*4882a593Smuzhiyun  * ocfs2_block_check structure describing the crc32 and the ecc.
433*4882a593Smuzhiyun  *
434*4882a593Smuzhiyun  * bc should be a pointer inside data, as the function will
435*4882a593Smuzhiyun  * take care of zeroing it before calculating the check information.  If
436*4882a593Smuzhiyun  * bc does not point inside data, the caller must make sure any inline
437*4882a593Smuzhiyun  * ocfs2_block_check structures are zeroed.
438*4882a593Smuzhiyun  *
439*4882a593Smuzhiyun  * The data buffer must be in on-disk endian (little endian for ocfs2).
440*4882a593Smuzhiyun  * bc will be filled with little-endian values and will be ready to go to
441*4882a593Smuzhiyun  * disk.
442*4882a593Smuzhiyun  */
ocfs2_block_check_compute_bhs(struct buffer_head ** bhs,int nr,struct ocfs2_block_check * bc)443*4882a593Smuzhiyun void ocfs2_block_check_compute_bhs(struct buffer_head **bhs, int nr,
444*4882a593Smuzhiyun 				   struct ocfs2_block_check *bc)
445*4882a593Smuzhiyun {
446*4882a593Smuzhiyun 	int i;
447*4882a593Smuzhiyun 	u32 crc, ecc;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	BUG_ON(nr < 0);
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	if (!nr)
452*4882a593Smuzhiyun 		return;
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	memset(bc, 0, sizeof(struct ocfs2_block_check));
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	for (i = 0, crc = ~0, ecc = 0; i < nr; i++) {
457*4882a593Smuzhiyun 		crc = crc32_le(crc, bhs[i]->b_data, bhs[i]->b_size);
458*4882a593Smuzhiyun 		/*
459*4882a593Smuzhiyun 		 * The number of bits in a buffer is obviously b_size*8.
460*4882a593Smuzhiyun 		 * The offset of this buffer is b_size*i, so the bit offset
461*4882a593Smuzhiyun 		 * of this buffer is b_size*8*i.
462*4882a593Smuzhiyun 		 */
463*4882a593Smuzhiyun 		ecc = (u16)ocfs2_hamming_encode(ecc, bhs[i]->b_data,
464*4882a593Smuzhiyun 						bhs[i]->b_size * 8,
465*4882a593Smuzhiyun 						bhs[i]->b_size * 8 * i);
466*4882a593Smuzhiyun 	}
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	/*
469*4882a593Smuzhiyun 	 * No ecc'd ocfs2 structure is larger than 4K, so ecc will be no
470*4882a593Smuzhiyun 	 * larger than 16 bits.
471*4882a593Smuzhiyun 	 */
472*4882a593Smuzhiyun 	BUG_ON(ecc > USHRT_MAX);
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	bc->bc_crc32e = cpu_to_le32(crc);
475*4882a593Smuzhiyun 	bc->bc_ecc = cpu_to_le16((u16)ecc);
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun /*
479*4882a593Smuzhiyun  * This function validates existing check information on a list of
480*4882a593Smuzhiyun  * buffer_heads.  Like _compute_bhs, the function will take care of
481*4882a593Smuzhiyun  * zeroing bc before calculating check codes.  If bc is not a pointer
482*4882a593Smuzhiyun  * inside data, the caller must have zeroed any inline
483*4882a593Smuzhiyun  * ocfs2_block_check structures.
484*4882a593Smuzhiyun  *
485*4882a593Smuzhiyun  * Again, the data passed in should be the on-disk endian.
486*4882a593Smuzhiyun  */
ocfs2_block_check_validate_bhs(struct buffer_head ** bhs,int nr,struct ocfs2_block_check * bc,struct ocfs2_blockcheck_stats * stats)487*4882a593Smuzhiyun int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr,
488*4882a593Smuzhiyun 				   struct ocfs2_block_check *bc,
489*4882a593Smuzhiyun 				   struct ocfs2_blockcheck_stats *stats)
490*4882a593Smuzhiyun {
491*4882a593Smuzhiyun 	int i, rc = 0;
492*4882a593Smuzhiyun 	u32 bc_crc32e;
493*4882a593Smuzhiyun 	u16 bc_ecc;
494*4882a593Smuzhiyun 	u32 crc, ecc, fix;
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	BUG_ON(nr < 0);
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	if (!nr)
499*4882a593Smuzhiyun 		return 0;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	ocfs2_blockcheck_inc_check(stats);
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	bc_crc32e = le32_to_cpu(bc->bc_crc32e);
504*4882a593Smuzhiyun 	bc_ecc = le16_to_cpu(bc->bc_ecc);
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun 	memset(bc, 0, sizeof(struct ocfs2_block_check));
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	/* Fast path - if the crc32 validates, we're good to go */
509*4882a593Smuzhiyun 	for (i = 0, crc = ~0; i < nr; i++)
510*4882a593Smuzhiyun 		crc = crc32_le(crc, bhs[i]->b_data, bhs[i]->b_size);
511*4882a593Smuzhiyun 	if (crc == bc_crc32e)
512*4882a593Smuzhiyun 		goto out;
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	ocfs2_blockcheck_inc_failure(stats);
515*4882a593Smuzhiyun 	mlog(ML_ERROR,
516*4882a593Smuzhiyun 	     "CRC32 failed: stored: %u, computed %u.  Applying ECC.\n",
517*4882a593Smuzhiyun 	     (unsigned int)bc_crc32e, (unsigned int)crc);
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 	/* Ok, try ECC fixups */
520*4882a593Smuzhiyun 	for (i = 0, ecc = 0; i < nr; i++) {
521*4882a593Smuzhiyun 		/*
522*4882a593Smuzhiyun 		 * The number of bits in a buffer is obviously b_size*8.
523*4882a593Smuzhiyun 		 * The offset of this buffer is b_size*i, so the bit offset
524*4882a593Smuzhiyun 		 * of this buffer is b_size*8*i.
525*4882a593Smuzhiyun 		 */
526*4882a593Smuzhiyun 		ecc = (u16)ocfs2_hamming_encode(ecc, bhs[i]->b_data,
527*4882a593Smuzhiyun 						bhs[i]->b_size * 8,
528*4882a593Smuzhiyun 						bhs[i]->b_size * 8 * i);
529*4882a593Smuzhiyun 	}
530*4882a593Smuzhiyun 	fix = ecc ^ bc_ecc;
531*4882a593Smuzhiyun 	for (i = 0; i < nr; i++) {
532*4882a593Smuzhiyun 		/*
533*4882a593Smuzhiyun 		 * Try the fix against each buffer.  It will only affect
534*4882a593Smuzhiyun 		 * one of them.
535*4882a593Smuzhiyun 		 */
536*4882a593Smuzhiyun 		ocfs2_hamming_fix(bhs[i]->b_data, bhs[i]->b_size * 8,
537*4882a593Smuzhiyun 				  bhs[i]->b_size * 8 * i, fix);
538*4882a593Smuzhiyun 	}
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	/* And check the crc32 again */
541*4882a593Smuzhiyun 	for (i = 0, crc = ~0; i < nr; i++)
542*4882a593Smuzhiyun 		crc = crc32_le(crc, bhs[i]->b_data, bhs[i]->b_size);
543*4882a593Smuzhiyun 	if (crc == bc_crc32e) {
544*4882a593Smuzhiyun 		ocfs2_blockcheck_inc_recover(stats);
545*4882a593Smuzhiyun 		goto out;
546*4882a593Smuzhiyun 	}
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n",
549*4882a593Smuzhiyun 	     (unsigned int)bc_crc32e, (unsigned int)crc);
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	rc = -EIO;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun out:
554*4882a593Smuzhiyun 	bc->bc_crc32e = cpu_to_le32(bc_crc32e);
555*4882a593Smuzhiyun 	bc->bc_ecc = cpu_to_le16(bc_ecc);
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 	return rc;
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun /*
561*4882a593Smuzhiyun  * These are the main API.  They check the superblock flag before
562*4882a593Smuzhiyun  * calling the underlying operations.
563*4882a593Smuzhiyun  *
564*4882a593Smuzhiyun  * They expect the buffer(s) to be in disk format.
565*4882a593Smuzhiyun  */
ocfs2_compute_meta_ecc(struct super_block * sb,void * data,struct ocfs2_block_check * bc)566*4882a593Smuzhiyun void ocfs2_compute_meta_ecc(struct super_block *sb, void *data,
567*4882a593Smuzhiyun 			    struct ocfs2_block_check *bc)
568*4882a593Smuzhiyun {
569*4882a593Smuzhiyun 	if (ocfs2_meta_ecc(OCFS2_SB(sb)))
570*4882a593Smuzhiyun 		ocfs2_block_check_compute(data, sb->s_blocksize, bc);
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun 
ocfs2_validate_meta_ecc(struct super_block * sb,void * data,struct ocfs2_block_check * bc)573*4882a593Smuzhiyun int ocfs2_validate_meta_ecc(struct super_block *sb, void *data,
574*4882a593Smuzhiyun 			    struct ocfs2_block_check *bc)
575*4882a593Smuzhiyun {
576*4882a593Smuzhiyun 	int rc = 0;
577*4882a593Smuzhiyun 	struct ocfs2_super *osb = OCFS2_SB(sb);
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	if (ocfs2_meta_ecc(osb))
580*4882a593Smuzhiyun 		rc = ocfs2_block_check_validate(data, sb->s_blocksize, bc,
581*4882a593Smuzhiyun 						&osb->osb_ecc_stats);
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun 	return rc;
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun 
ocfs2_compute_meta_ecc_bhs(struct super_block * sb,struct buffer_head ** bhs,int nr,struct ocfs2_block_check * bc)586*4882a593Smuzhiyun void ocfs2_compute_meta_ecc_bhs(struct super_block *sb,
587*4882a593Smuzhiyun 				struct buffer_head **bhs, int nr,
588*4882a593Smuzhiyun 				struct ocfs2_block_check *bc)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun 	if (ocfs2_meta_ecc(OCFS2_SB(sb)))
591*4882a593Smuzhiyun 		ocfs2_block_check_compute_bhs(bhs, nr, bc);
592*4882a593Smuzhiyun }
593*4882a593Smuzhiyun 
ocfs2_validate_meta_ecc_bhs(struct super_block * sb,struct buffer_head ** bhs,int nr,struct ocfs2_block_check * bc)594*4882a593Smuzhiyun int ocfs2_validate_meta_ecc_bhs(struct super_block *sb,
595*4882a593Smuzhiyun 				struct buffer_head **bhs, int nr,
596*4882a593Smuzhiyun 				struct ocfs2_block_check *bc)
597*4882a593Smuzhiyun {
598*4882a593Smuzhiyun 	int rc = 0;
599*4882a593Smuzhiyun 	struct ocfs2_super *osb = OCFS2_SB(sb);
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 	if (ocfs2_meta_ecc(osb))
602*4882a593Smuzhiyun 		rc = ocfs2_block_check_validate_bhs(bhs, nr, bc,
603*4882a593Smuzhiyun 						    &osb->osb_ecc_stats);
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	return rc;
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun 
608