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

Reply via email to