diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-25 09:04:37 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:02 -0400 |
commit | 84eed90fac1b927a2657ff3bb7a0f18b9cb688f7 (patch) | |
tree | 651362117230506a34fcc9d07421faa5b14dda8b | |
parent | 004fb5750615bb3cf53e2aa50f6ef1ea57d97df9 (diff) |
Btrfs: Add failure handling for read_sys_array
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r-- | fs/btrfs/disk-io.c | 11 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 16 |
2 files changed, 18 insertions, 9 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 1281c393c7e6..71838264ca6b 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1278,7 +1278,11 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1278 | mutex_lock(&fs_info->fs_mutex); | 1278 | mutex_lock(&fs_info->fs_mutex); |
1279 | 1279 | ||
1280 | ret = btrfs_read_sys_array(tree_root); | 1280 | ret = btrfs_read_sys_array(tree_root); |
1281 | BUG_ON(ret); | 1281 | if (ret) { |
1282 | printk("btrfs: failed to read the system array on %s\n", | ||
1283 | sb->s_id); | ||
1284 | goto fail_sys_array; | ||
1285 | } | ||
1282 | 1286 | ||
1283 | blocksize = btrfs_level_size(tree_root, | 1287 | blocksize = btrfs_level_size(tree_root, |
1284 | btrfs_super_chunk_root_level(disk_super)); | 1288 | btrfs_super_chunk_root_level(disk_super)); |
@@ -1335,8 +1339,9 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1335 | fail_extent_root: | 1339 | fail_extent_root: |
1336 | free_extent_buffer(extent_root->node); | 1340 | free_extent_buffer(extent_root->node); |
1337 | fail_tree_root: | 1341 | fail_tree_root: |
1338 | mutex_unlock(&fs_info->fs_mutex); | ||
1339 | free_extent_buffer(tree_root->node); | 1342 | free_extent_buffer(tree_root->node); |
1343 | fail_sys_array: | ||
1344 | mutex_unlock(&fs_info->fs_mutex); | ||
1340 | fail_sb_buffer: | 1345 | fail_sb_buffer: |
1341 | free_extent_buffer(fs_info->sb_buffer); | 1346 | free_extent_buffer(fs_info->sb_buffer); |
1342 | extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree); | 1347 | extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree); |
@@ -1344,6 +1349,8 @@ fail_iput: | |||
1344 | iput(fs_info->btree_inode); | 1349 | iput(fs_info->btree_inode); |
1345 | fail: | 1350 | fail: |
1346 | close_all_devices(fs_info); | 1351 | close_all_devices(fs_info); |
1352 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | ||
1353 | |||
1347 | kfree(extent_root); | 1354 | kfree(extent_root); |
1348 | kfree(tree_root); | 1355 | kfree(tree_root); |
1349 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) | 1356 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index bccb5566fd84..c63a982e31d0 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1365,14 +1365,14 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
1365 | struct extent_buffer *sb = root->fs_info->sb_buffer; | 1365 | struct extent_buffer *sb = root->fs_info->sb_buffer; |
1366 | struct btrfs_disk_key *disk_key; | 1366 | struct btrfs_disk_key *disk_key; |
1367 | struct btrfs_chunk *chunk; | 1367 | struct btrfs_chunk *chunk; |
1368 | struct btrfs_key key; | 1368 | u8 *ptr; |
1369 | unsigned long sb_ptr; | ||
1370 | int ret = 0; | ||
1369 | u32 num_stripes; | 1371 | u32 num_stripes; |
1370 | u32 array_size; | 1372 | u32 array_size; |
1371 | u32 len = 0; | 1373 | u32 len = 0; |
1372 | u8 *ptr; | ||
1373 | unsigned long sb_ptr; | ||
1374 | u32 cur; | 1374 | u32 cur; |
1375 | int ret; | 1375 | struct btrfs_key key; |
1376 | 1376 | ||
1377 | array_size = btrfs_super_sys_array_size(super_copy); | 1377 | array_size = btrfs_super_sys_array_size(super_copy); |
1378 | 1378 | ||
@@ -1397,17 +1397,19 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
1397 | if (key.type == BTRFS_CHUNK_ITEM_KEY) { | 1397 | if (key.type == BTRFS_CHUNK_ITEM_KEY) { |
1398 | chunk = (struct btrfs_chunk *)sb_ptr; | 1398 | chunk = (struct btrfs_chunk *)sb_ptr; |
1399 | ret = read_one_chunk(root, &key, sb, chunk); | 1399 | ret = read_one_chunk(root, &key, sb, chunk); |
1400 | BUG_ON(ret); | 1400 | if (ret) |
1401 | break; | ||
1401 | num_stripes = btrfs_chunk_num_stripes(sb, chunk); | 1402 | num_stripes = btrfs_chunk_num_stripes(sb, chunk); |
1402 | len = btrfs_chunk_item_size(num_stripes); | 1403 | len = btrfs_chunk_item_size(num_stripes); |
1403 | } else { | 1404 | } else { |
1404 | BUG(); | 1405 | ret = -EIO; |
1406 | break; | ||
1405 | } | 1407 | } |
1406 | ptr += len; | 1408 | ptr += len; |
1407 | sb_ptr += len; | 1409 | sb_ptr += len; |
1408 | cur += len; | 1410 | cur += len; |
1409 | } | 1411 | } |
1410 | return 0; | 1412 | return ret; |
1411 | } | 1413 | } |
1412 | 1414 | ||
1413 | int btrfs_read_chunk_tree(struct btrfs_root *root) | 1415 | int btrfs_read_chunk_tree(struct btrfs_root *root) |