aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/blockcheck.c184
-rw-r--r--fs/ocfs2/blockcheck.h29
-rw-r--r--fs/ocfs2/ocfs2.h4
-rw-r--r--fs/ocfs2/super.c42
4 files changed, 240 insertions, 19 deletions
diff --git a/fs/ocfs2/blockcheck.c b/fs/ocfs2/blockcheck.c
index 2a947c44e594..a1163b8b417c 100644
--- a/fs/ocfs2/blockcheck.c
+++ b/fs/ocfs2/blockcheck.c
@@ -22,6 +22,9 @@
22#include <linux/crc32.h> 22#include <linux/crc32.h>
23#include <linux/buffer_head.h> 23#include <linux/buffer_head.h>
24#include <linux/bitops.h> 24#include <linux/bitops.h>
25#include <linux/debugfs.h>
26#include <linux/module.h>
27#include <linux/fs.h>
25#include <asm/byteorder.h> 28#include <asm/byteorder.h>
26 29
27#include <cluster/masklog.h> 30#include <cluster/masklog.h>
@@ -222,6 +225,155 @@ void ocfs2_hamming_fix_block(void *data, unsigned int blocksize,
222 ocfs2_hamming_fix(data, blocksize * 8, 0, fix); 225 ocfs2_hamming_fix(data, blocksize * 8, 0, fix);
223} 226}
224 227
228
229/*
230 * Debugfs handling.
231 */
232
233#ifdef CONFIG_DEBUG_FS
234
235static int blockcheck_u64_get(void *data, u64 *val)
236{
237 *val = *(u64 *)data;
238 return 0;
239}
240DEFINE_SIMPLE_ATTRIBUTE(blockcheck_fops, blockcheck_u64_get, NULL, "%llu\n");
241
242static 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
250static 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
264static 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
294out:
295 if (rc)
296 ocfs2_blockcheck_debug_remove(stats);
297 return rc;
298}
299#else
300static inline int ocfs2_blockcheck_debug_install(struct ocfs2_blockcheck_stats *stats,
301 struct dentry *parent)
302{
303 return 0;
304}
305
306static 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 */
312int 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
318void ocfs2_blockcheck_stats_debugfs_remove(struct ocfs2_blockcheck_stats *stats)
319{
320 ocfs2_blockcheck_debug_remove(stats);
321}
322
323static 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
339static 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
355static 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
225/* 377/*
226 * This function generates check information for a block. 378 * This function generates check information for a block.
227 * data is the block to be checked. bc is a pointer to the 379 * data is the block to be checked. bc is a pointer to the
@@ -266,12 +418,15 @@ void ocfs2_block_check_compute(void *data, size_t blocksize,
266 * Again, the data passed in should be the on-disk endian. 418 * Again, the data passed in should be the on-disk endian.
267 */ 419 */
268int ocfs2_block_check_validate(void *data, size_t blocksize, 420int ocfs2_block_check_validate(void *data, size_t blocksize,
269 struct ocfs2_block_check *bc) 421 struct ocfs2_block_check *bc,
422 struct ocfs2_blockcheck_stats *stats)
270{ 423{
271 int rc = 0; 424 int rc = 0;
272 struct ocfs2_block_check check; 425 struct ocfs2_block_check check;
273 u32 crc, ecc; 426 u32 crc, ecc;
274 427
428 ocfs2_blockcheck_inc_check(stats);
429
275 check.bc_crc32e = le32_to_cpu(bc->bc_crc32e); 430 check.bc_crc32e = le32_to_cpu(bc->bc_crc32e);
276 check.bc_ecc = le16_to_cpu(bc->bc_ecc); 431 check.bc_ecc = le16_to_cpu(bc->bc_ecc);
277 432
@@ -282,6 +437,7 @@ int ocfs2_block_check_validate(void *data, size_t blocksize,
282 if (crc == check.bc_crc32e) 437 if (crc == check.bc_crc32e)
283 goto out; 438 goto out;
284 439
440 ocfs2_blockcheck_inc_failure(stats);
285 mlog(ML_ERROR, 441 mlog(ML_ERROR,
286 "CRC32 failed: stored: %u, computed %u. Applying ECC.\n", 442 "CRC32 failed: stored: %u, computed %u. Applying ECC.\n",
287 (unsigned int)check.bc_crc32e, (unsigned int)crc); 443 (unsigned int)check.bc_crc32e, (unsigned int)crc);
@@ -292,8 +448,10 @@ int ocfs2_block_check_validate(void *data, size_t blocksize,
292 448
293 /* And check the crc32 again */ 449 /* And check the crc32 again */
294 crc = crc32_le(~0, data, blocksize); 450 crc = crc32_le(~0, data, blocksize);
295 if (crc == check.bc_crc32e) 451 if (crc == check.bc_crc32e) {
452 ocfs2_blockcheck_inc_recover(stats);
296 goto out; 453 goto out;
454 }
297 455
298 mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n", 456 mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n",
299 (unsigned int)check.bc_crc32e, (unsigned int)crc); 457 (unsigned int)check.bc_crc32e, (unsigned int)crc);
@@ -366,7 +524,8 @@ void ocfs2_block_check_compute_bhs(struct buffer_head **bhs, int nr,
366 * Again, the data passed in should be the on-disk endian. 524 * Again, the data passed in should be the on-disk endian.
367 */ 525 */
368int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr, 526int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr,
369 struct ocfs2_block_check *bc) 527 struct ocfs2_block_check *bc,
528 struct ocfs2_blockcheck_stats *stats)
370{ 529{
371 int i, rc = 0; 530 int i, rc = 0;
372 struct ocfs2_block_check check; 531 struct ocfs2_block_check check;
@@ -377,6 +536,8 @@ int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr,
377 if (!nr) 536 if (!nr)
378 return 0; 537 return 0;
379 538
539 ocfs2_blockcheck_inc_check(stats);
540
380 check.bc_crc32e = le32_to_cpu(bc->bc_crc32e); 541 check.bc_crc32e = le32_to_cpu(bc->bc_crc32e);
381 check.bc_ecc = le16_to_cpu(bc->bc_ecc); 542 check.bc_ecc = le16_to_cpu(bc->bc_ecc);
382 543
@@ -388,6 +549,7 @@ int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr,
388 if (crc == check.bc_crc32e) 549 if (crc == check.bc_crc32e)
389 goto out; 550 goto out;
390 551
552 ocfs2_blockcheck_inc_failure(stats);
391 mlog(ML_ERROR, 553 mlog(ML_ERROR,
392 "CRC32 failed: stored: %u, computed %u. Applying ECC.\n", 554 "CRC32 failed: stored: %u, computed %u. Applying ECC.\n",
393 (unsigned int)check.bc_crc32e, (unsigned int)crc); 555 (unsigned int)check.bc_crc32e, (unsigned int)crc);
@@ -416,8 +578,10 @@ int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr,
416 /* And check the crc32 again */ 578 /* And check the crc32 again */
417 for (i = 0, crc = ~0; i < nr; i++) 579 for (i = 0, crc = ~0; i < nr; i++)
418 crc = crc32_le(crc, bhs[i]->b_data, bhs[i]->b_size); 580 crc = crc32_le(crc, bhs[i]->b_data, bhs[i]->b_size);
419 if (crc == check.bc_crc32e) 581 if (crc == check.bc_crc32e) {
582 ocfs2_blockcheck_inc_recover(stats);
420 goto out; 583 goto out;
584 }
421 585
422 mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n", 586 mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n",
423 (unsigned int)check.bc_crc32e, (unsigned int)crc); 587 (unsigned int)check.bc_crc32e, (unsigned int)crc);
@@ -448,9 +612,11 @@ int ocfs2_validate_meta_ecc(struct super_block *sb, void *data,
448 struct ocfs2_block_check *bc) 612 struct ocfs2_block_check *bc)
449{ 613{
450 int rc = 0; 614 int rc = 0;
615 struct ocfs2_super *osb = OCFS2_SB(sb);
451 616
452 if (ocfs2_meta_ecc(OCFS2_SB(sb))) 617 if (ocfs2_meta_ecc(osb))
453 rc = ocfs2_block_check_validate(data, sb->s_blocksize, bc); 618 rc = ocfs2_block_check_validate(data, sb->s_blocksize, bc,
619 &osb->osb_ecc_stats);
454 620
455 return rc; 621 return rc;
456} 622}
@@ -468,9 +634,11 @@ int ocfs2_validate_meta_ecc_bhs(struct super_block *sb,
468 struct ocfs2_block_check *bc) 634 struct ocfs2_block_check *bc)
469{ 635{
470 int rc = 0; 636 int rc = 0;
637 struct ocfs2_super *osb = OCFS2_SB(sb);
471 638
472 if (ocfs2_meta_ecc(OCFS2_SB(sb))) 639 if (ocfs2_meta_ecc(osb))
473 rc = ocfs2_block_check_validate_bhs(bhs, nr, bc); 640 rc = ocfs2_block_check_validate_bhs(bhs, nr, bc,
641 &osb->osb_ecc_stats);
474 642
475 return rc; 643 return rc;
476} 644}
diff --git a/fs/ocfs2/blockcheck.h b/fs/ocfs2/blockcheck.h
index 70ec3feda32f..d4b69febf70a 100644
--- a/fs/ocfs2/blockcheck.h
+++ b/fs/ocfs2/blockcheck.h
@@ -21,6 +21,24 @@
21#define OCFS2_BLOCKCHECK_H 21#define OCFS2_BLOCKCHECK_H
22 22
23 23
24/* Count errors and error correction from blockcheck.c */
25struct ocfs2_blockcheck_stats {
26 spinlock_t b_lock;
27 u64 b_check_count; /* Number of blocks we've checked */
28 u64 b_failure_count; /* Number of failed checksums */
29 u64 b_recover_count; /* Number of blocks fixed by ecc */
30
31 /*
32 * debugfs entries, used if this is passed to
33 * ocfs2_blockcheck_stats_debugfs_install()
34 */
35 struct dentry *b_debug_dir; /* Parent of the debugfs files */
36 struct dentry *b_debug_check; /* Exposes b_check_count */
37 struct dentry *b_debug_failure; /* Exposes b_failure_count */
38 struct dentry *b_debug_recover; /* Exposes b_recover_count */
39};
40
41
24/* High level block API */ 42/* High level block API */
25void ocfs2_compute_meta_ecc(struct super_block *sb, void *data, 43void ocfs2_compute_meta_ecc(struct super_block *sb, void *data,
26 struct ocfs2_block_check *bc); 44 struct ocfs2_block_check *bc);
@@ -37,11 +55,18 @@ int ocfs2_validate_meta_ecc_bhs(struct super_block *sb,
37void ocfs2_block_check_compute(void *data, size_t blocksize, 55void ocfs2_block_check_compute(void *data, size_t blocksize,
38 struct ocfs2_block_check *bc); 56 struct ocfs2_block_check *bc);
39int ocfs2_block_check_validate(void *data, size_t blocksize, 57int ocfs2_block_check_validate(void *data, size_t blocksize,
40 struct ocfs2_block_check *bc); 58 struct ocfs2_block_check *bc,
59 struct ocfs2_blockcheck_stats *stats);
41void ocfs2_block_check_compute_bhs(struct buffer_head **bhs, int nr, 60void ocfs2_block_check_compute_bhs(struct buffer_head **bhs, int nr,
42 struct ocfs2_block_check *bc); 61 struct ocfs2_block_check *bc);
43int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr, 62int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr,
44 struct ocfs2_block_check *bc); 63 struct ocfs2_block_check *bc,
64 struct ocfs2_blockcheck_stats *stats);
65
66/* Debug Initialization */
67int ocfs2_blockcheck_stats_debugfs_install(struct ocfs2_blockcheck_stats *stats,
68 struct dentry *parent);
69void ocfs2_blockcheck_stats_debugfs_remove(struct ocfs2_blockcheck_stats *stats);
45 70
46/* 71/*
47 * Hamming code functions 72 * Hamming code functions
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index ab285be023b2..18c1d9ec1c93 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -47,6 +47,9 @@
47#include "ocfs2_fs.h" 47#include "ocfs2_fs.h"
48#include "ocfs2_lockid.h" 48#include "ocfs2_lockid.h"
49 49
50/* For struct ocfs2_blockcheck_stats */
51#include "blockcheck.h"
52
50/* Most user visible OCFS2 inodes will have very few pieces of 53/* Most user visible OCFS2 inodes will have very few pieces of
51 * metadata, but larger files (including bitmaps, etc) must be taken 54 * metadata, but larger files (including bitmaps, etc) must be taken
52 * into account when designing an access scheme. We allow a small 55 * into account when designing an access scheme. We allow a small
@@ -305,6 +308,7 @@ struct ocfs2_super
305 struct ocfs2_dinode *local_alloc_copy; 308 struct ocfs2_dinode *local_alloc_copy;
306 struct ocfs2_quota_recovery *quota_rec; 309 struct ocfs2_quota_recovery *quota_rec;
307 310
311 struct ocfs2_blockcheck_stats osb_ecc_stats;
308 struct ocfs2_alloc_stats alloc_stats; 312 struct ocfs2_alloc_stats alloc_stats;
309 char dev_str[20]; /* "major,minor" of the device */ 313 char dev_str[20]; /* "major,minor" of the device */
310 314
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index d05f3caec410..86f500c5d63d 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -118,10 +118,12 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb);
118static int ocfs2_check_volume(struct ocfs2_super *osb); 118static int ocfs2_check_volume(struct ocfs2_super *osb);
119static int ocfs2_verify_volume(struct ocfs2_dinode *di, 119static int ocfs2_verify_volume(struct ocfs2_dinode *di,
120 struct buffer_head *bh, 120 struct buffer_head *bh,
121 u32 sectsize); 121 u32 sectsize,
122 struct ocfs2_blockcheck_stats *stats);
122static int ocfs2_initialize_super(struct super_block *sb, 123static int ocfs2_initialize_super(struct super_block *sb,
123 struct buffer_head *bh, 124 struct buffer_head *bh,
124 int sector_size); 125 int sector_size,
126 struct ocfs2_blockcheck_stats *stats);
125static int ocfs2_get_sector(struct super_block *sb, 127static int ocfs2_get_sector(struct super_block *sb,
126 struct buffer_head **bh, 128 struct buffer_head **bh,
127 int block, 129 int block,
@@ -711,7 +713,8 @@ out:
711 713
712static int ocfs2_sb_probe(struct super_block *sb, 714static int ocfs2_sb_probe(struct super_block *sb,
713 struct buffer_head **bh, 715 struct buffer_head **bh,
714 int *sector_size) 716 int *sector_size,
717 struct ocfs2_blockcheck_stats *stats)
715{ 718{
716 int status, tmpstat; 719 int status, tmpstat;
717 struct ocfs1_vol_disk_hdr *hdr; 720 struct ocfs1_vol_disk_hdr *hdr;
@@ -777,7 +780,8 @@ static int ocfs2_sb_probe(struct super_block *sb,
777 goto bail; 780 goto bail;
778 } 781 }
779 di = (struct ocfs2_dinode *) (*bh)->b_data; 782 di = (struct ocfs2_dinode *) (*bh)->b_data;
780 status = ocfs2_verify_volume(di, *bh, blksize); 783 memset(stats, 0, sizeof(struct ocfs2_blockcheck_stats));
784 status = ocfs2_verify_volume(di, *bh, blksize, stats);
781 if (status >= 0) 785 if (status >= 0)
782 goto bail; 786 goto bail;
783 brelse(*bh); 787 brelse(*bh);
@@ -983,6 +987,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
983 struct ocfs2_super *osb = NULL; 987 struct ocfs2_super *osb = NULL;
984 struct buffer_head *bh = NULL; 988 struct buffer_head *bh = NULL;
985 char nodestr[8]; 989 char nodestr[8];
990 struct ocfs2_blockcheck_stats stats;
986 991
987 mlog_entry("%p, %p, %i", sb, data, silent); 992 mlog_entry("%p, %p, %i", sb, data, silent);
988 993
@@ -992,13 +997,13 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
992 } 997 }
993 998
994 /* probe for superblock */ 999 /* probe for superblock */
995 status = ocfs2_sb_probe(sb, &bh, &sector_size); 1000 status = ocfs2_sb_probe(sb, &bh, &sector_size, &stats);
996 if (status < 0) { 1001 if (status < 0) {
997 mlog(ML_ERROR, "superblock probe failed!\n"); 1002 mlog(ML_ERROR, "superblock probe failed!\n");
998 goto read_super_error; 1003 goto read_super_error;
999 } 1004 }
1000 1005
1001 status = ocfs2_initialize_super(sb, bh, sector_size); 1006 status = ocfs2_initialize_super(sb, bh, sector_size, &stats);
1002 osb = OCFS2_SB(sb); 1007 osb = OCFS2_SB(sb);
1003 if (status < 0) { 1008 if (status < 0) {
1004 mlog_errno(status); 1009 mlog_errno(status);
@@ -1108,6 +1113,18 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
1108 goto read_super_error; 1113 goto read_super_error;
1109 } 1114 }
1110 1115
1116 if (ocfs2_meta_ecc(osb)) {
1117 status = ocfs2_blockcheck_stats_debugfs_install(
1118 &osb->osb_ecc_stats,
1119 osb->osb_debug_root);
1120 if (status) {
1121 mlog(ML_ERROR,
1122 "Unable to create blockcheck statistics "
1123 "files\n");
1124 goto read_super_error;
1125 }
1126 }
1127
1111 status = ocfs2_mount_volume(sb); 1128 status = ocfs2_mount_volume(sb);
1112 if (osb->root_inode) 1129 if (osb->root_inode)
1113 inode = igrab(osb->root_inode); 1130 inode = igrab(osb->root_inode);
@@ -1849,6 +1866,7 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
1849 if (osb->cconn) 1866 if (osb->cconn)
1850 ocfs2_dlm_shutdown(osb, hangup_needed); 1867 ocfs2_dlm_shutdown(osb, hangup_needed);
1851 1868
1869 ocfs2_blockcheck_stats_debugfs_remove(&osb->osb_ecc_stats);
1852 debugfs_remove(osb->osb_debug_root); 1870 debugfs_remove(osb->osb_debug_root);
1853 1871
1854 if (hangup_needed) 1872 if (hangup_needed)
@@ -1896,7 +1914,8 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu
1896 1914
1897static int ocfs2_initialize_super(struct super_block *sb, 1915static int ocfs2_initialize_super(struct super_block *sb,
1898 struct buffer_head *bh, 1916 struct buffer_head *bh,
1899 int sector_size) 1917 int sector_size,
1918 struct ocfs2_blockcheck_stats *stats)
1900{ 1919{
1901 int status; 1920 int status;
1902 int i, cbits, bbits; 1921 int i, cbits, bbits;
@@ -1955,6 +1974,9 @@ static int ocfs2_initialize_super(struct super_block *sb,
1955 atomic_set(&osb->alloc_stats.bg_allocs, 0); 1974 atomic_set(&osb->alloc_stats.bg_allocs, 0);
1956 atomic_set(&osb->alloc_stats.bg_extends, 0); 1975 atomic_set(&osb->alloc_stats.bg_extends, 0);
1957 1976
1977 /* Copy the blockcheck stats from the superblock probe */
1978 osb->osb_ecc_stats = *stats;
1979
1958 ocfs2_init_node_maps(osb); 1980 ocfs2_init_node_maps(osb);
1959 1981
1960 snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u", 1982 snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
@@ -2192,7 +2214,8 @@ bail:
2192 */ 2214 */
2193static int ocfs2_verify_volume(struct ocfs2_dinode *di, 2215static int ocfs2_verify_volume(struct ocfs2_dinode *di,
2194 struct buffer_head *bh, 2216 struct buffer_head *bh,
2195 u32 blksz) 2217 u32 blksz,
2218 struct ocfs2_blockcheck_stats *stats)
2196{ 2219{
2197 int status = -EAGAIN; 2220 int status = -EAGAIN;
2198 2221
@@ -2205,7 +2228,8 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di,
2205 OCFS2_FEATURE_INCOMPAT_META_ECC) { 2228 OCFS2_FEATURE_INCOMPAT_META_ECC) {
2206 status = ocfs2_block_check_validate(bh->b_data, 2229 status = ocfs2_block_check_validate(bh->b_data,
2207 bh->b_size, 2230 bh->b_size,
2208 &di->i_check); 2231 &di->i_check,
2232 stats);
2209 if (status) 2233 if (status)
2210 goto out; 2234 goto out;
2211 } 2235 }