diff options
author | Chris Mason <chris.mason@oracle.com> | 2009-09-22 14:45:50 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-09-22 14:45:50 -0400 |
commit | 33b4d47f5e24b986f486d7de9a2df915ad1fdfbc (patch) | |
tree | 198fb5c7d48bfd9e4010eb253e9e7573172a7680 | |
parent | 1b2da372b0324b5c604fc8790e70a7efbeacb0b6 (diff) |
Btrfs: deal with NULL space info
After a balance it is briefly possible for the space info
field in the inode to be NULL. This adds some checks
to make sure things properly deal with the NULL value.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r-- | fs/btrfs/extent-tree.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 5f3544e5f3cb..1b9b87870f51 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2778,6 +2778,8 @@ int btrfs_check_metadata_free_space(struct btrfs_root *root) | |||
2778 | /* get the space info for where the metadata will live */ | 2778 | /* get the space info for where the metadata will live */ |
2779 | alloc_target = btrfs_get_alloc_profile(root, 0); | 2779 | alloc_target = btrfs_get_alloc_profile(root, 0); |
2780 | meta_sinfo = __find_space_info(info, alloc_target); | 2780 | meta_sinfo = __find_space_info(info, alloc_target); |
2781 | if (!meta_sinfo) | ||
2782 | goto alloc; | ||
2781 | 2783 | ||
2782 | again: | 2784 | again: |
2783 | spin_lock(&meta_sinfo->lock); | 2785 | spin_lock(&meta_sinfo->lock); |
@@ -2795,7 +2797,7 @@ again: | |||
2795 | if (!meta_sinfo->full) { | 2797 | if (!meta_sinfo->full) { |
2796 | meta_sinfo->force_alloc = 1; | 2798 | meta_sinfo->force_alloc = 1; |
2797 | spin_unlock(&meta_sinfo->lock); | 2799 | spin_unlock(&meta_sinfo->lock); |
2798 | 2800 | alloc: | |
2799 | trans = btrfs_start_transaction(root, 1); | 2801 | trans = btrfs_start_transaction(root, 1); |
2800 | if (!trans) | 2802 | if (!trans) |
2801 | return -ENOMEM; | 2803 | return -ENOMEM; |
@@ -2803,6 +2805,10 @@ again: | |||
2803 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | 2805 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
2804 | 2 * 1024 * 1024, alloc_target, 0); | 2806 | 2 * 1024 * 1024, alloc_target, 0); |
2805 | btrfs_end_transaction(trans, root); | 2807 | btrfs_end_transaction(trans, root); |
2808 | if (!meta_sinfo) { | ||
2809 | meta_sinfo = __find_space_info(info, | ||
2810 | alloc_target); | ||
2811 | } | ||
2806 | goto again; | 2812 | goto again; |
2807 | } | 2813 | } |
2808 | spin_unlock(&meta_sinfo->lock); | 2814 | spin_unlock(&meta_sinfo->lock); |
@@ -2838,6 +2844,9 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, | |||
2838 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | 2844 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); |
2839 | 2845 | ||
2840 | data_sinfo = BTRFS_I(inode)->space_info; | 2846 | data_sinfo = BTRFS_I(inode)->space_info; |
2847 | if (!data_sinfo) | ||
2848 | goto alloc; | ||
2849 | |||
2841 | again: | 2850 | again: |
2842 | /* make sure we have enough space to handle the data first */ | 2851 | /* make sure we have enough space to handle the data first */ |
2843 | spin_lock(&data_sinfo->lock); | 2852 | spin_lock(&data_sinfo->lock); |
@@ -2856,7 +2865,7 @@ again: | |||
2856 | 2865 | ||
2857 | data_sinfo->force_alloc = 1; | 2866 | data_sinfo->force_alloc = 1; |
2858 | spin_unlock(&data_sinfo->lock); | 2867 | spin_unlock(&data_sinfo->lock); |
2859 | 2868 | alloc: | |
2860 | alloc_target = btrfs_get_alloc_profile(root, 1); | 2869 | alloc_target = btrfs_get_alloc_profile(root, 1); |
2861 | trans = btrfs_start_transaction(root, 1); | 2870 | trans = btrfs_start_transaction(root, 1); |
2862 | if (!trans) | 2871 | if (!trans) |
@@ -2868,6 +2877,11 @@ again: | |||
2868 | btrfs_end_transaction(trans, root); | 2877 | btrfs_end_transaction(trans, root); |
2869 | if (ret) | 2878 | if (ret) |
2870 | return ret; | 2879 | return ret; |
2880 | |||
2881 | if (!data_sinfo) { | ||
2882 | btrfs_set_inode_space_info(root, inode); | ||
2883 | data_sinfo = BTRFS_I(inode)->space_info; | ||
2884 | } | ||
2871 | goto again; | 2885 | goto again; |
2872 | } | 2886 | } |
2873 | spin_unlock(&data_sinfo->lock); | 2887 | spin_unlock(&data_sinfo->lock); |