aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/super.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2009-01-06 17:57:08 -0500
committerJoel Becker <joel.becker@oracle.com>2009-06-03 22:15:36 -0400
commit73be192b17e43b6dc4f492dab41d70ab5b9d2908 (patch)
tree9482070421cda81f490036b28033d4f300a58a94 /fs/ocfs2/super.c
parent15633a220ffe74fc61bc8117e6a89a494011ea3d (diff)
ocfs2: Add statistics for the checksum and ecc operations.
It would be nice to know how often we get checksum failures. Even better, how many of them we can fix with the single bit ecc. So, we add a statistics structure. The structure can be installed into debugfs wherever the user wants. For ocfs2, we'll put it in the superblock-specific debugfs directory and pass it down from our higher-level functions. The stats are only registered with debugfs when the filesystem supports metadata ecc. Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r--fs/ocfs2/super.c42
1 files changed, 33 insertions, 9 deletions
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 }