aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2012-04-29 18:21:10 -0400
committerTheodore Ts'o <tytso@mit.edu>2012-04-29 18:21:10 -0400
commitf84891289e62a74e9b4942eaad80617368b2d778 (patch)
tree6e86704a9780dd6ed97f25ba1cd32d59ffebf430 /fs/ext4
parent69964ea4c7b68c9399f7977aa5b9aa6539a6a98a (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.c35
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
415static 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
416static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) 436static 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 }