Btrfs supports different raid profile for meta/data/sys, and as different profile support different tolerated missing device, it's better to check if it can be mounted degraded at a per-chunk base.
So this patch will add check for read_one_chunk() against its profile, other than checking it against with the lowest duplication profile. Reported-by: Zhao Lei <[email protected]> Reported-by: Anand Jain <[email protected]> Signed-off-by: Qu Wenruo <[email protected]> --- fs/btrfs/volumes.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 644e070..3272187 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -6164,12 +6164,15 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, struct btrfs_chunk *chunk) { struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; + struct super_block *sb = root->fs_info->sb; struct map_lookup *map; struct extent_map *em; u64 logical; u64 length; u64 devid; u8 uuid[BTRFS_UUID_SIZE]; + int missing = 0; + int max_tolerated; int num_stripes; int ret; int i; @@ -6238,7 +6241,21 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, btrfs_warn(root->fs_info, "devid %llu uuid %pU is missing", devid, uuid); } + if (map->stripes[i].dev->missing) + missing++; map->stripes[i].dev->in_fs_metadata = 1; + + } + + /* XXX: Why the function name is SO LOOOOOOOOOOOOOOOOONG?! */ + max_tolerated = + btrfs_get_num_tolerated_disk_barrier_failures(map->type); + if (missing > max_tolerated && !(sb->s_flags & MS_RDONLY)) { + free_extent_map(em); + btrfs_error(root->fs_info, -EIO, + "missing device(%d) exceeds the limit(%d), writeable mount is not allowed\n", + missing, max_tolerated); + return -EIO; } write_lock(&map_tree->map_tree.lock); -- 2.5.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
