diff options
author | Joel Becker <joel.becker@oracle.com> | 2008-12-10 20:58:22 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-01-05 11:40:34 -0500 |
commit | c175a518b4a1d514483abf61813ce5d855917164 (patch) | |
tree | e437a3d1377fab38c1d8ef6289fd9ea3590d09b2 /fs/ocfs2/dir.c | |
parent | 87d35a74b15ec703910a63e0667692fb5e267be0 (diff) |
ocfs2: Checksum and ECC for directory blocks.
Use the db_check field of ocfs2_dir_block_trailer to crc/ecc the
dirblocks.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/dir.c')
-rw-r--r-- | fs/ocfs2/dir.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 1efd0ab680cf..f2c4098cf337 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include "ocfs2.h" | 48 | #include "ocfs2.h" |
49 | 49 | ||
50 | #include "alloc.h" | 50 | #include "alloc.h" |
51 | #include "blockcheck.h" | ||
51 | #include "dir.h" | 52 | #include "dir.h" |
52 | #include "dlmglue.h" | 53 | #include "dlmglue.h" |
53 | #include "extent_map.h" | 54 | #include "extent_map.h" |
@@ -107,6 +108,17 @@ static inline unsigned int ocfs2_dir_trailer_blk_off(struct super_block *sb) | |||
107 | 108 | ||
108 | #define ocfs2_trailer_from_bh(_bh, _sb) ((struct ocfs2_dir_block_trailer *) ((_bh)->b_data + ocfs2_dir_trailer_blk_off((_sb)))) | 109 | #define ocfs2_trailer_from_bh(_bh, _sb) ((struct ocfs2_dir_block_trailer *) ((_bh)->b_data + ocfs2_dir_trailer_blk_off((_sb)))) |
109 | 110 | ||
111 | /* XXX ocfs2_block_dqtrailer() is similar but not quite - can we make | ||
112 | * them more consistent? */ | ||
113 | struct ocfs2_dir_block_trailer *ocfs2_dir_trailer_from_size(int blocksize, | ||
114 | void *data) | ||
115 | { | ||
116 | char *p = data; | ||
117 | |||
118 | p += blocksize - sizeof(struct ocfs2_dir_block_trailer); | ||
119 | return (struct ocfs2_dir_block_trailer *)p; | ||
120 | } | ||
121 | |||
110 | /* | 122 | /* |
111 | * XXX: This is executed once on every dirent. We should consider optimizing | 123 | * XXX: This is executed once on every dirent. We should consider optimizing |
112 | * it. | 124 | * it. |
@@ -268,14 +280,35 @@ out: | |||
268 | static int ocfs2_validate_dir_block(struct super_block *sb, | 280 | static int ocfs2_validate_dir_block(struct super_block *sb, |
269 | struct buffer_head *bh) | 281 | struct buffer_head *bh) |
270 | { | 282 | { |
283 | int rc; | ||
284 | struct ocfs2_dir_block_trailer *trailer = | ||
285 | ocfs2_trailer_from_bh(bh, sb); | ||
286 | |||
287 | |||
271 | /* | 288 | /* |
272 | * Nothing yet. We don't validate dirents here, that's handled | 289 | * We don't validate dirents here, that's handled |
273 | * in-place when the code walks them. | 290 | * in-place when the code walks them. |
274 | */ | 291 | */ |
275 | mlog(0, "Validating dirblock %llu\n", | 292 | mlog(0, "Validating dirblock %llu\n", |
276 | (unsigned long long)bh->b_blocknr); | 293 | (unsigned long long)bh->b_blocknr); |
277 | 294 | ||
278 | return 0; | 295 | BUG_ON(!buffer_uptodate(bh)); |
296 | |||
297 | /* | ||
298 | * If the ecc fails, we return the error but otherwise | ||
299 | * leave the filesystem running. We know any error is | ||
300 | * local to this block. | ||
301 | * | ||
302 | * Note that we are safe to call this even if the directory | ||
303 | * doesn't have a trailer. Filesystems without metaecc will do | ||
304 | * nothing, and filesystems with it will have one. | ||
305 | */ | ||
306 | rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &trailer->db_check); | ||
307 | if (rc) | ||
308 | mlog(ML_ERROR, "Checksum failed for dinode %llu\n", | ||
309 | (unsigned long long)bh->b_blocknr); | ||
310 | |||
311 | return rc; | ||
279 | } | 312 | } |
280 | 313 | ||
281 | /* | 314 | /* |