diff mbox

btrfs-progs: corrupt-block: fix a delete and use bug corrupting extent tree.

Message ID 1408678969-9218-1-git-send-email-quwenruo@cn.fujitsu.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Qu Wenruo Aug. 22, 2014, 3:42 a.m. UTC
When corrupting extent tree, corrupt-block will iterate each child
node/leaf of a node.
However, when a node's child is leaf, btrfs_corrupt_extent_leaf() may
delete some item in the leaf, which may cause the children number of the
parent node decrease.

Before this patch, corrupt-block will read out the nritems only *ONCE*
and iterate the 'nritems' times.
When btrfs_corrupt_extent_leaf() deletes enough item, causing the
nritems of btrfs_header decreased, the last few iteration will access
non-existed node, which will cause the delete and use bug like
the following:
---
\# ./btrfs-corrupt-block -E /dev/vdc
deleting extent record: key 40714240 168 16384
Couldn't map the block 3459802452797161472
btrfs-corrupt-block: volumes.c:1137: btrfs_num_copies: Assertion
`!(!ce)' failed.
Aborted
---

This patch will update the nritmes in each iteration to avoid the bug.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
 btrfs-corrupt-block.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
diff mbox

Patch

diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 6ecbe47..486ea19 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -264,12 +264,10 @@  static void btrfs_corrupt_extent_tree(struct btrfs_trans_handle *trans,
 				      struct extent_buffer *eb)
 {
 	int i;
-	u32 nr;
 
 	if (!eb)
 		return;
 
-	nr = btrfs_header_nritems(eb);
 	if (btrfs_is_leaf(eb)) {
 		btrfs_corrupt_extent_leaf(trans, root, eb);
 		return;
@@ -280,7 +278,7 @@  static void btrfs_corrupt_extent_tree(struct btrfs_trans_handle *trans,
 			return;
 	}
 
-	for (i = 0; i < nr; i++) {
+	for (i = 0; i < btrfs_header_nritems(eb); i++) {
 		struct extent_buffer *next;
 
 		next = read_tree_block(root, btrfs_node_blockptr(eb, i),