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