Commit c175a518b4a1d514483abf61813ce5d855917164

Authored by Joel Becker
Committed by Mark Fasheh
1 parent 87d35a74b1

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>

Showing 4 changed files with 67 additions and 5 deletions Side-by-side Diff

... ... @@ -48,6 +48,7 @@
48 48 #include "ocfs2.h"
49 49  
50 50 #include "alloc.h"
  51 +#include "blockcheck.h"
51 52 #include "dir.h"
52 53 #include "dlmglue.h"
53 54 #include "extent_map.h"
... ... @@ -107,6 +108,17 @@
107 108  
108 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 123 * XXX: This is executed once on every dirent. We should consider optimizing
112 124 * it.
113 125  
114 126  
... ... @@ -268,14 +280,35 @@
268 280 static int ocfs2_validate_dir_block(struct super_block *sb,
269 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 290 * in-place when the code walks them.
274 291 */
275 292 mlog(0, "Validating dirblock %llu\n",
276 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 /*
... ... @@ -83,5 +83,7 @@
83 83 struct buffer_head *fe_bh,
84 84 struct ocfs2_alloc_context *data_ac);
85 85  
  86 +struct ocfs2_dir_block_trailer *ocfs2_dir_trailer_from_size(int blocksize,
  87 + void *data);
86 88 #endif /* OCFS2_DIR_H */
... ... @@ -415,6 +415,26 @@
415 415 ocfs2_block_check_compute(data, size, &dqt->dq_check);
416 416 }
417 417  
  418 +/*
  419 + * Directory blocks also have their own trigger because the
  420 + * struct ocfs2_block_check offset depends on the blocksize.
  421 + */
  422 +static void ocfs2_db_commit_trigger(struct jbd2_buffer_trigger_type *triggers,
  423 + struct buffer_head *bh,
  424 + void *data, size_t size)
  425 +{
  426 + struct ocfs2_dir_block_trailer *trailer =
  427 + ocfs2_dir_trailer_from_size(size, data);
  428 +
  429 + /*
  430 + * We aren't guaranteed to have the superblock here, so we
  431 + * must unconditionally compute the ecc data.
  432 + * __ocfs2_journal_access() will only set the triggers if
  433 + * metaecc is enabled.
  434 + */
  435 + ocfs2_block_check_compute(data, size, &trailer->db_check);
  436 +}
  437 +
418 438 static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers,
419 439 struct buffer_head *bh)
420 440 {
... ... @@ -454,6 +474,13 @@
454 474 .ot_offset = offsetof(struct ocfs2_group_desc, bg_check),
455 475 };
456 476  
  477 +static struct ocfs2_triggers db_triggers = {
  478 + .ot_triggers = {
  479 + .t_commit = ocfs2_db_commit_trigger,
  480 + .t_abort = ocfs2_abort_trigger,
  481 + },
  482 +};
  483 +
457 484 static struct ocfs2_triggers xb_triggers = {
458 485 .ot_triggers = {
459 486 .t_commit = ocfs2_commit_trigger,
... ... @@ -555,8 +582,8 @@
555 582 int ocfs2_journal_access_db(handle_t *handle, struct inode *inode,
556 583 struct buffer_head *bh, int type)
557 584 {
558   - /* Right now, nothing for dirblocks */
559   - return __ocfs2_journal_access(handle, inode, bh, NULL, type);
  585 + return __ocfs2_journal_access(handle, inode, bh, &db_triggers,
  586 + type);
560 587 }
561 588  
562 589 int ocfs2_journal_access_xb(handle_t *handle, struct inode *inode,
... ... @@ -776,7 +776,7 @@
776 776 /*20*/ __le64 db_blkno; /* Offset on disk, in blocks */
777 777 __le64 db_parent_dinode; /* dinode which owns me, in
778 778 blocks */
779   -/*30*/ __le64 db_check; /* Error checking */
  779 +/*30*/ struct ocfs2_block_check db_check; /* Error checking */
780 780 /*40*/
781 781 };
782 782