diff options
author | Darrick J. Wong <djwong@us.ibm.com> | 2012-04-29 18:21:10 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-04-29 18:21:10 -0400 |
commit | f84891289e62a74e9b4942eaad80617368b2d778 (patch) | |
tree | 6e86704a9780dd6ed97f25ba1cd32d59ffebf430 /fs/ext4 | |
parent | 69964ea4c7b68c9399f7977aa5b9aa6539a6a98a (diff) |
ext4: create a new BH_Verified flag to avoid unnecessary metadata validation
Create a new BH_Verified flag to indicate that we've verified all the
data in a buffer_head for correctness. This allows us to bypass
expensive verification steps when they are not necessary without
missing them when they are.
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/extents.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index abcdeab67f52..8c1334ee8c7f 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -412,6 +412,26 @@ int ext4_ext_check_inode(struct inode *inode) | |||
412 | return ext4_ext_check(inode, ext_inode_hdr(inode), ext_depth(inode)); | 412 | return ext4_ext_check(inode, ext_inode_hdr(inode), ext_depth(inode)); |
413 | } | 413 | } |
414 | 414 | ||
415 | static int __ext4_ext_check_block(const char *function, unsigned int line, | ||
416 | struct inode *inode, | ||
417 | struct ext4_extent_header *eh, | ||
418 | int depth, | ||
419 | struct buffer_head *bh) | ||
420 | { | ||
421 | int ret; | ||
422 | |||
423 | if (buffer_verified(bh)) | ||
424 | return 0; | ||
425 | ret = ext4_ext_check(inode, eh, depth); | ||
426 | if (ret) | ||
427 | return ret; | ||
428 | set_buffer_verified(bh); | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | #define ext4_ext_check_block(inode, eh, depth, bh) \ | ||
433 | __ext4_ext_check_block(__func__, __LINE__, inode, eh, depth, bh) | ||
434 | |||
415 | #ifdef EXT_DEBUG | 435 | #ifdef EXT_DEBUG |
416 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) | 436 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) |
417 | { | 437 | { |
@@ -668,8 +688,6 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
668 | i = depth; | 688 | i = depth; |
669 | /* walk through the tree */ | 689 | /* walk through the tree */ |
670 | while (i) { | 690 | while (i) { |
671 | int need_to_validate = 0; | ||
672 | |||
673 | ext_debug("depth %d: num %d, max %d\n", | 691 | ext_debug("depth %d: num %d, max %d\n", |
674 | ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); | 692 | ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); |
675 | 693 | ||
@@ -688,8 +706,6 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
688 | put_bh(bh); | 706 | put_bh(bh); |
689 | goto err; | 707 | goto err; |
690 | } | 708 | } |
691 | /* validate the extent entries */ | ||
692 | need_to_validate = 1; | ||
693 | } | 709 | } |
694 | eh = ext_block_hdr(bh); | 710 | eh = ext_block_hdr(bh); |
695 | ppos++; | 711 | ppos++; |
@@ -703,7 +719,7 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
703 | path[ppos].p_hdr = eh; | 719 | path[ppos].p_hdr = eh; |
704 | i--; | 720 | i--; |
705 | 721 | ||
706 | if (need_to_validate && ext4_ext_check(inode, eh, i)) | 722 | if (ext4_ext_check_block(inode, eh, i, bh)) |
707 | goto err; | 723 | goto err; |
708 | } | 724 | } |
709 | 725 | ||
@@ -1344,7 +1360,8 @@ got_index: | |||
1344 | return -EIO; | 1360 | return -EIO; |
1345 | eh = ext_block_hdr(bh); | 1361 | eh = ext_block_hdr(bh); |
1346 | /* subtract from p_depth to get proper eh_depth */ | 1362 | /* subtract from p_depth to get proper eh_depth */ |
1347 | if (ext4_ext_check(inode, eh, path->p_depth - depth)) { | 1363 | if (ext4_ext_check_block(inode, eh, |
1364 | path->p_depth - depth, bh)) { | ||
1348 | put_bh(bh); | 1365 | put_bh(bh); |
1349 | return -EIO; | 1366 | return -EIO; |
1350 | } | 1367 | } |
@@ -1357,7 +1374,7 @@ got_index: | |||
1357 | if (bh == NULL) | 1374 | if (bh == NULL) |
1358 | return -EIO; | 1375 | return -EIO; |
1359 | eh = ext_block_hdr(bh); | 1376 | eh = ext_block_hdr(bh); |
1360 | if (ext4_ext_check(inode, eh, path->p_depth - depth)) { | 1377 | if (ext4_ext_check_block(inode, eh, path->p_depth - depth, bh)) { |
1361 | put_bh(bh); | 1378 | put_bh(bh); |
1362 | return -EIO; | 1379 | return -EIO; |
1363 | } | 1380 | } |
@@ -2644,8 +2661,8 @@ cont: | |||
2644 | err = -EIO; | 2661 | err = -EIO; |
2645 | break; | 2662 | break; |
2646 | } | 2663 | } |
2647 | if (ext4_ext_check(inode, ext_block_hdr(bh), | 2664 | if (ext4_ext_check_block(inode, ext_block_hdr(bh), |
2648 | depth - i - 1)) { | 2665 | depth - i - 1, bh)) { |
2649 | err = -EIO; | 2666 | err = -EIO; |
2650 | break; | 2667 | break; |
2651 | } | 2668 | } |