All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Btrfs-progs: check blocks when checking fs roots
@ 2014-10-02 19:11 Josef Bacik
  0 siblings, 0 replies; only message in thread
From: Josef Bacik @ 2014-10-02 19:11 UTC (permalink / raw)
  To: linux-btrfs

If check block fails during the extent tree checks we could evict the extent
buffer from cache, so the next time we go to read it for the fs_tree checks we
could miss the fact that its bogus and blow up in strange and interesting ways.
Fix this by running the leaf/node checks on all blocks in the fs root so we know
we're looking at valid blocks.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 cmds-check.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/cmds-check.c b/cmds-check.c
index 5b8417c..db779ae 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -1376,6 +1376,8 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
 
 		next = btrfs_find_tree_block(root, bytenr, blocksize);
 		if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
+			enum btrfs_tree_block_status status;
+
 			free_extent_buffer(next);
 			reada_walk_down(root, cur, path->slots[*level]);
 			next = read_tree_block(root, bytenr, blocksize,
@@ -1384,6 +1386,16 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
 				err = -EIO;
 				goto out;
 			}
+
+			if (btrfs_is_leaf(next))
+				status = btrfs_check_leaf(root, NULL, next);
+			else
+				status = btrfs_check_node(root, NULL, next);
+			if (status != BTRFS_TREE_BLOCK_CLEAN) {
+				free_extent_buffer(next);
+				err = -EIO;
+				goto out;
+			}
 		}
 
 		*level = *level - 1;
@@ -2078,6 +2090,7 @@ static int check_fs_root(struct btrfs_root *root,
 	struct shared_node root_node;
 	struct root_record *rec;
 	struct btrfs_root_item *root_item = &root->root_item;
+	enum btrfs_tree_block_status status;
 
 	if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) {
 		rec = get_root_rec(root_cache, root->root_key.objectid);
@@ -2096,6 +2109,14 @@ static int check_fs_root(struct btrfs_root *root,
 	wc->active_node = level;
 	wc->root_level = level;
 
+	/* We may not have checked the root block, lets do that now */
+	if (btrfs_is_leaf(root->node))
+		status = btrfs_check_leaf(root, NULL, root->node);
+	else
+		status = btrfs_check_node(root, NULL, root->node);
+	if (status != BTRFS_TREE_BLOCK_CLEAN)
+		return -EIO;
+
 	if (btrfs_root_refs(root_item) > 0 ||
 	    btrfs_disk_key_objectid(&root_item->drop_progress) == 0) {
 		path.nodes[level] = root->node;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2014-10-02 19:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-02 19:11 [PATCH] Btrfs-progs: check blocks when checking fs roots Josef Bacik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.