diff options
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 | /* |