aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorliubo <liubo2009@cn.fujitsu.com>2011-04-08 04:44:37 -0400
committerChris Mason <chris.mason@oracle.com>2011-05-14 16:10:26 -0400
commit1aba86d67f340a8001d67183ec32e8a62e3ec658 (patch)
tree8e2a3dc2bceca44c1525f4815b00ef1ae275adad /fs/btrfs/extent-tree.c
parentf5de93914983bf04b92a786d1d205286fc53b49b (diff)
Btrfs: fix easily get into ENOSPC in mixed case
When a btrfs disk is created by mixed data & metadata option, it will have no pure data or pure metadata space info. In btrfs's for-linus branch, commit 78b1ea13838039cd88afdd62519b40b344d6c920 (Btrfs: fix OOPS of empty filesystem after balance) initializes space infos at the very beginning. The problem is this initialization does not take the mixed case into account, which will cause btrfs will easily get into ENOSPC in mixed case. Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index cd52f7f556ef..9ee6bd55e16c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -8856,23 +8856,38 @@ out:
8856int btrfs_init_space_info(struct btrfs_fs_info *fs_info) 8856int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
8857{ 8857{
8858 struct btrfs_space_info *space_info; 8858 struct btrfs_space_info *space_info;
8859 struct btrfs_super_block *disk_super;
8860 u64 features;
8861 u64 flags;
8862 int mixed = 0;
8859 int ret; 8863 int ret;
8860 8864
8861 ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM, 0, 0, 8865 disk_super = &fs_info->super_copy;
8862 &space_info); 8866 if (!btrfs_super_root(disk_super))
8863 if (ret) 8867 return 1;
8864 return ret;
8865 8868
8866 ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA, 0, 0, 8869 features = btrfs_super_incompat_flags(disk_super);
8867 &space_info); 8870 if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
8868 if (ret) 8871 mixed = 1;
8869 return ret;
8870 8872
8871 ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA, 0, 0, 8873 flags = BTRFS_BLOCK_GROUP_SYSTEM;
8872 &space_info); 8874 ret = update_space_info(fs_info, flags, 0, 0, &space_info);
8873 if (ret) 8875 if (ret)
8874 return ret; 8876 goto out;
8875 8877
8878 if (mixed) {
8879 flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA;
8880 ret = update_space_info(fs_info, flags, 0, 0, &space_info);
8881 } else {
8882 flags = BTRFS_BLOCK_GROUP_METADATA;
8883 ret = update_space_info(fs_info, flags, 0, 0, &space_info);
8884 if (ret)
8885 goto out;
8886
8887 flags = BTRFS_BLOCK_GROUP_DATA;
8888 ret = update_space_info(fs_info, flags, 0, 0, &space_info);
8889 }
8890out:
8876 return ret; 8891 return ret;
8877} 8892}
8878 8893