ocfs2: Validate metadata only when it's read from disk.

Add an optional validation hook to ocfs2_read_blocks().  Now the
validation function is only called when a block was actually read off of
disk.  It is not called when the buffer was in cache.

We add a buffer state bit BH_NeedsValidate to flag these buffers.  It
must always be one higher than the last JBD2 buffer state bit.

The dinode, dirblock, extent_block, and xattr_block validators are
lifted to this scheme directly.  The group_descriptor validator needs to
be split into two pieces.  The first part only needs the gd buffer and
is passed to ocfs2_read_block().  The second part requires the dinode as
well, and is called every time.  It's only 3 compares, so it's tiny.
This also allows us to clean up the non-fatal gd check used by resize.c.
It now has no magic argument.

Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
This commit is contained in:
Joel Becker
2008-11-13 14:49:19 -08:00
committed by Mark Fasheh
parent 4ae1d69bed
commit 970e4936d7
10 changed files with 149 additions and 97 deletions

View File

@@ -684,6 +684,9 @@ static int ocfs2_validate_extent_block(struct super_block *sb,
struct ocfs2_extent_block *eb =
(struct ocfs2_extent_block *)bh->b_data;
mlog(0, "Validating extent block %llu\n",
(unsigned long long)bh->b_blocknr);
if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
ocfs2_error(sb,
"Extent block #%llu has bad signature %.*s",
@@ -719,21 +722,13 @@ int ocfs2_read_extent_block(struct inode *inode, u64 eb_blkno,
int rc;
struct buffer_head *tmp = *bh;
rc = ocfs2_read_block(inode, eb_blkno, &tmp);
if (rc)
goto out;
rc = ocfs2_validate_extent_block(inode->i_sb, tmp);
if (rc) {
brelse(tmp);
goto out;
}
rc = ocfs2_read_block(inode, eb_blkno, &tmp,
ocfs2_validate_extent_block);
/* If ocfs2_read_block() got us a new bh, pass it up. */
if (!*bh)
if (!rc && !*bh)
*bh = tmp;
out:
return rc;
}