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:
@@ -39,6 +39,19 @@
|
||||
|
||||
#include "buffer_head_io.h"
|
||||
|
||||
/*
|
||||
* Bits on bh->b_state used by ocfs2.
|
||||
*
|
||||
* These MUST be after the JBD2 bits. Currently BH_Unshadow is the last
|
||||
* JBD2 bit.
|
||||
*/
|
||||
enum ocfs2_state_bits {
|
||||
BH_NeedsValidate = BH_Unshadow + 1,
|
||||
};
|
||||
|
||||
/* Expand the magic b_state functions */
|
||||
BUFFER_FNS(NeedsValidate, needs_validate);
|
||||
|
||||
int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
|
||||
struct inode *inode)
|
||||
{
|
||||
@@ -166,7 +179,9 @@ bail:
|
||||
}
|
||||
|
||||
int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
|
||||
struct buffer_head *bhs[], int flags)
|
||||
struct buffer_head *bhs[], int flags,
|
||||
int (*validate)(struct super_block *sb,
|
||||
struct buffer_head *bh))
|
||||
{
|
||||
int status = 0;
|
||||
int i, ignore_cache = 0;
|
||||
@@ -298,6 +313,8 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
|
||||
|
||||
clear_buffer_uptodate(bh);
|
||||
get_bh(bh); /* for end_buffer_read_sync() */
|
||||
if (validate)
|
||||
set_buffer_needs_validate(bh);
|
||||
bh->b_end_io = end_buffer_read_sync;
|
||||
submit_bh(READ, bh);
|
||||
continue;
|
||||
@@ -328,6 +345,20 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
|
||||
bhs[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buffer_needs_validate(bh)) {
|
||||
/* We never set NeedsValidate if the
|
||||
* buffer was held by the journal, so
|
||||
* that better not have changed */
|
||||
BUG_ON(buffer_jbd(bh));
|
||||
clear_buffer_needs_validate(bh);
|
||||
status = validate(inode->i_sb, bh);
|
||||
if (status) {
|
||||
put_bh(bh);
|
||||
bhs[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Always set the buffer in the cache, even if it was
|
||||
|
Reference in New Issue
Block a user