aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-03-19 12:13:25 -0400
committerChris Mason <chris.mason@fusionio.com>2013-03-21 19:24:31 -0400
commit835d974fabfa9bff4d173ad03c054ac2f673263f (patch)
tree7dae22a2ff112055682e79528227814ed7023171 /fs
parentd763448286377b8a0e3f179372e9e292bef3c337 (diff)
Btrfs: handle a bogus chunk tree nicely
If you restore a btrfs-image file system and try to mount that file system we'll panic. That's because btrfs-image restores and just makes one big chunk to envelope the whole disk, since they are really only meant to be messed with by our btrfs-progs. So fix up btrfs_rmap_block and the callers of it for mount so that we no longer panic but instead just return an error and fail to mount. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent-tree.c35
-rw-r--r--fs/btrfs/volumes.c13
2 files changed, 42 insertions, 6 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 350b9b18140c..a8ff25aedca1 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -257,7 +257,8 @@ static int exclude_super_stripes(struct btrfs_root *root,
257 cache->bytes_super += stripe_len; 257 cache->bytes_super += stripe_len;
258 ret = add_excluded_extent(root, cache->key.objectid, 258 ret = add_excluded_extent(root, cache->key.objectid,
259 stripe_len); 259 stripe_len);
260 BUG_ON(ret); /* -ENOMEM */ 260 if (ret)
261 return ret;
261 } 262 }
262 263
263 for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { 264 for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
@@ -265,13 +266,17 @@ static int exclude_super_stripes(struct btrfs_root *root,
265 ret = btrfs_rmap_block(&root->fs_info->mapping_tree, 266 ret = btrfs_rmap_block(&root->fs_info->mapping_tree,
266 cache->key.objectid, bytenr, 267 cache->key.objectid, bytenr,
267 0, &logical, &nr, &stripe_len); 268 0, &logical, &nr, &stripe_len);
268 BUG_ON(ret); /* -ENOMEM */ 269 if (ret)
270 return ret;
269 271
270 while (nr--) { 272 while (nr--) {
271 cache->bytes_super += stripe_len; 273 cache->bytes_super += stripe_len;
272 ret = add_excluded_extent(root, logical[nr], 274 ret = add_excluded_extent(root, logical[nr],
273 stripe_len); 275 stripe_len);
274 BUG_ON(ret); /* -ENOMEM */ 276 if (ret) {
277 kfree(logical);
278 return ret;
279 }
275 } 280 }
276 281
277 kfree(logical); 282 kfree(logical);
@@ -7964,7 +7969,17 @@ int btrfs_read_block_groups(struct btrfs_root *root)
7964 * info has super bytes accounted for, otherwise we'll think 7969 * info has super bytes accounted for, otherwise we'll think
7965 * we have more space than we actually do. 7970 * we have more space than we actually do.
7966 */ 7971 */
7967 exclude_super_stripes(root, cache); 7972 ret = exclude_super_stripes(root, cache);
7973 if (ret) {
7974 /*
7975 * We may have excluded something, so call this just in
7976 * case.
7977 */
7978 free_excluded_extents(root, cache);
7979 kfree(cache->free_space_ctl);
7980 kfree(cache);
7981 goto error;
7982 }
7968 7983
7969 /* 7984 /*
7970 * check for two cases, either we are full, and therefore 7985 * check for two cases, either we are full, and therefore
@@ -8106,7 +8121,17 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
8106 8121
8107 cache->last_byte_to_unpin = (u64)-1; 8122 cache->last_byte_to_unpin = (u64)-1;
8108 cache->cached = BTRFS_CACHE_FINISHED; 8123 cache->cached = BTRFS_CACHE_FINISHED;
8109 exclude_super_stripes(root, cache); 8124 ret = exclude_super_stripes(root, cache);
8125 if (ret) {
8126 /*
8127 * We may have excluded something, so call this just in
8128 * case.
8129 */
8130 free_excluded_extents(root, cache);
8131 kfree(cache->free_space_ctl);
8132 kfree(cache);
8133 return ret;
8134 }
8110 8135
8111 add_new_free_space(cache, root->fs_info, chunk_offset, 8136 add_new_free_space(cache, root->fs_info, chunk_offset,
8112 chunk_offset + size); 8137 chunk_offset + size);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 5989a92236f7..2854c824ab64 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4935,7 +4935,18 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
4935 em = lookup_extent_mapping(em_tree, chunk_start, 1); 4935 em = lookup_extent_mapping(em_tree, chunk_start, 1);
4936 read_unlock(&em_tree->lock); 4936 read_unlock(&em_tree->lock);
4937 4937
4938 BUG_ON(!em || em->start != chunk_start); 4938 if (!em) {
4939 printk(KERN_ERR "btrfs: couldn't find em for chunk %Lu\n",
4940 chunk_start);
4941 return -EIO;
4942 }
4943
4944 if (em->start != chunk_start) {
4945 printk(KERN_ERR "btrfs: bad chunk start, em=%Lu, wanted=%Lu\n",
4946 em->start, chunk_start);
4947 free_extent_map(em);
4948 return -EIO;
4949 }
4939 map = (struct map_lookup *)em->bdev; 4950 map = (struct map_lookup *)em->bdev;
4940 4951
4941 length = em->len; 4952 length = em->len;