aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2010-12-13 14:56:23 -0500
committerChris Mason <chris.mason@oracle.com>2010-12-13 20:06:52 -0500
commitcd02dca56442e1504fd6bc5b96f7f1870162b266 (patch)
tree1a38d99fc581974ba6d8136c42ca81f3b1216ea3 /fs/btrfs/extent-tree.c
parent68433b73b104bff388aac376631d32abbbd872b0 (diff)
Btrfs: account for missing devices in RAID allocation profiles
When we mount in RAID degraded mode without adding a new device to replace the failed one, we can end up using the wrong RAID flags for allocations. This results in strange combinations of block groups (raid1 in a raid10 filesystem) and corruptions when we try to allocate blocks from single spindle chunks on drives that are actually missing. The first device has two small 4MB chunks in it that mkfs creates and these are usually unused in a raid1 or raid10 setup. But, in -o degraded, the allocator will fall back to these because the mask of desired raid groups isn't correct. The fix here is to count the missing devices as we build up the list of devices in the system. This count is used when picking the raid level to make sure we continue using the same levels that were in place before we lost a drive. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 41133b064d72..4be231e0d2bd 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3044,7 +3044,13 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
3044 3044
3045u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) 3045u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
3046{ 3046{
3047 u64 num_devices = root->fs_info->fs_devices->rw_devices; 3047 /*
3048 * we add in the count of missing devices because we want
3049 * to make sure that any RAID levels on a degraded FS
3050 * continue to be honored.
3051 */
3052 u64 num_devices = root->fs_info->fs_devices->rw_devices +
3053 root->fs_info->fs_devices->missing_devices;
3048 3054
3049 if (num_devices == 1) 3055 if (num_devices == 1)
3050 flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0); 3056 flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0);
@@ -7891,7 +7897,14 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags)
7891 u64 stripped = BTRFS_BLOCK_GROUP_RAID0 | 7897 u64 stripped = BTRFS_BLOCK_GROUP_RAID0 |
7892 BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; 7898 BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10;
7893 7899
7894 num_devices = root->fs_info->fs_devices->rw_devices; 7900 /*
7901 * we add in the count of missing devices because we want
7902 * to make sure that any RAID levels on a degraded FS
7903 * continue to be honored.
7904 */
7905 num_devices = root->fs_info->fs_devices->rw_devices +
7906 root->fs_info->fs_devices->missing_devices;
7907
7895 if (num_devices == 1) { 7908 if (num_devices == 1) {
7896 stripped |= BTRFS_BLOCK_GROUP_DUP; 7909 stripped |= BTRFS_BLOCK_GROUP_DUP;
7897 stripped = flags & ~stripped; 7910 stripped = flags & ~stripped;