summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2010-12-13 14:47:58 -0500
committerChris Mason <chris.mason@oracle.com>2010-12-13 14:47:58 -0500
commit68433b73b104bff388aac376631d32abbbd872b0 (patch)
treeb08c8c07f2f77e3d840b316a66a47af1210ab349
parent3dd1462e82bcab7625cec129952f26dae7a8b742 (diff)
downloadlinux-68433b73b104bff388aac376631d32abbbd872b0.tar.gz
linux-68433b73b104bff388aac376631d32abbbd872b0.tar.bz2
linux-68433b73b104bff388aac376631d32abbbd872b0.zip
Btrfs: EIO when we fail to read tree roots
If we just get a plain IO error when we read tree roots, the code wasn't properly sending that error up the chain. This allowed mounts to continue when they should failed, and allowed operations on partially setup root structs. The end result was usually oopsen on spinlocks that hadn't been spun up correctly. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/disk-io.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index b803c2667673..a5d2249e6da5 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1007,7 +1007,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
blocksize, generation);
- BUG_ON(!root->node);
+ if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
+ free_extent_buffer(root->node);
+ return -EIO;
+ }
root->commit_root = btrfs_root_node(root);
return 0;
}