Btrfs: Add failure handling for read_sys_array
authorChris Mason <chris.mason@oracle.com>
Fri, 25 Apr 2008 13:04:37 +0000 (09:04 -0400)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:04:02 +0000 (11:04 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/disk-io.c
fs/btrfs/volumes.c

index 1281c39..7183826 100644 (file)
@@ -1278,7 +1278,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        mutex_lock(&fs_info->fs_mutex);
 
        ret = btrfs_read_sys_array(tree_root);
-       BUG_ON(ret);
+       if (ret) {
+               printk("btrfs: failed to read the system array on %s\n",
+                      sb->s_id);
+               goto fail_sys_array;
+       }
 
        blocksize = btrfs_level_size(tree_root,
                                     btrfs_super_chunk_root_level(disk_super));
@@ -1335,8 +1339,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 fail_extent_root:
        free_extent_buffer(extent_root->node);
 fail_tree_root:
-       mutex_unlock(&fs_info->fs_mutex);
        free_extent_buffer(tree_root->node);
+fail_sys_array:
+       mutex_unlock(&fs_info->fs_mutex);
 fail_sb_buffer:
        free_extent_buffer(fs_info->sb_buffer);
        extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree);
@@ -1344,6 +1349,8 @@ fail_iput:
        iput(fs_info->btree_inode);
 fail:
        close_all_devices(fs_info);
+       btrfs_mapping_tree_free(&fs_info->mapping_tree);
+
        kfree(extent_root);
        kfree(tree_root);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
index bccb556..c63a982 100644 (file)
@@ -1365,14 +1365,14 @@ int btrfs_read_sys_array(struct btrfs_root *root)
        struct extent_buffer *sb = root->fs_info->sb_buffer;
        struct btrfs_disk_key *disk_key;
        struct btrfs_chunk *chunk;
-       struct btrfs_key key;
+       u8 *ptr;
+       unsigned long sb_ptr;
+       int ret = 0;
        u32 num_stripes;
        u32 array_size;
        u32 len = 0;
-       u8 *ptr;
-       unsigned long sb_ptr;
        u32 cur;
-       int ret;
+       struct btrfs_key key;
 
        array_size = btrfs_super_sys_array_size(super_copy);
 
@@ -1397,17 +1397,19 @@ int btrfs_read_sys_array(struct btrfs_root *root)
                if (key.type == BTRFS_CHUNK_ITEM_KEY) {
                        chunk = (struct btrfs_chunk *)sb_ptr;
                        ret = read_one_chunk(root, &key, sb, chunk);
-                       BUG_ON(ret);
+                       if (ret)
+                               break;
                        num_stripes = btrfs_chunk_num_stripes(sb, chunk);
                        len = btrfs_chunk_item_size(num_stripes);
                } else {
-                       BUG();
+                       ret = -EIO;
+                       break;
                }
                ptr += len;
                sb_ptr += len;
                cur += len;
        }
-       return 0;
+       return ret;
 }
 
 int btrfs_read_chunk_tree(struct btrfs_root *root)