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