diff options
author | Josef Bacik <josef@redhat.com> | 2010-03-19 16:49:55 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2010-03-30 21:19:09 -0400 |
commit | 1b1d1f6625e517a08640ddb4b8f8a0e025243fe3 (patch) | |
tree | d662fe7e7d9ddec1214982b3dcd955228e18562f /fs/btrfs/disk-io.c | |
parent | 6cf8bfbf5e88edfb09a2bf0631a067060f534592 (diff) |
Btrfs: fail to mount if we have problems reading the block groups
We don't actually check the return value of btrfs_read_block_groups, so we can
possibly succeed to mount, but then fail to say read the superblock xattr for
selinux which will cause the vfs code to deactivate the super.
This is a problem because in find_free_extent we just assume that we
will find the right space_info for the allocation we want. But if we
failed to read the block groups, we won't have setup any space_info's,
and we'll hit a NULL pointer deref in find_free_extent.
This patch fixes that problem by checking the return value of
btrfs_read_block_groups, and failing out properly. I've also added a
check in find_free_extent so if for some reason we don't find an
appropriate space_info, we just return -ENOSPC.
Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 11d0ad30e203..5ae1c0fcfce0 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1922,7 +1922,11 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1922 | 1922 | ||
1923 | csum_root->track_dirty = 1; | 1923 | csum_root->track_dirty = 1; |
1924 | 1924 | ||
1925 | btrfs_read_block_groups(extent_root); | 1925 | ret = btrfs_read_block_groups(extent_root); |
1926 | if (ret) { | ||
1927 | printk(KERN_ERR "Failed to read block groups: %d\n", ret); | ||
1928 | goto fail_block_groups; | ||
1929 | } | ||
1926 | 1930 | ||
1927 | fs_info->generation = generation; | 1931 | fs_info->generation = generation; |
1928 | fs_info->last_trans_committed = generation; | 1932 | fs_info->last_trans_committed = generation; |
@@ -1932,7 +1936,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1932 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, | 1936 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, |
1933 | "btrfs-cleaner"); | 1937 | "btrfs-cleaner"); |
1934 | if (IS_ERR(fs_info->cleaner_kthread)) | 1938 | if (IS_ERR(fs_info->cleaner_kthread)) |
1935 | goto fail_csum_root; | 1939 | goto fail_block_groups; |
1936 | 1940 | ||
1937 | fs_info->transaction_kthread = kthread_run(transaction_kthread, | 1941 | fs_info->transaction_kthread = kthread_run(transaction_kthread, |
1938 | tree_root, | 1942 | tree_root, |
@@ -2020,7 +2024,8 @@ fail_cleaner: | |||
2020 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); | 2024 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); |
2021 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 2025 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
2022 | 2026 | ||
2023 | fail_csum_root: | 2027 | fail_block_groups: |
2028 | btrfs_free_block_groups(fs_info); | ||
2024 | free_extent_buffer(csum_root->node); | 2029 | free_extent_buffer(csum_root->node); |
2025 | free_extent_buffer(csum_root->commit_root); | 2030 | free_extent_buffer(csum_root->commit_root); |
2026 | fail_dev_root: | 2031 | fail_dev_root: |