btrfs: factor out reading of bg from find_frist_block_group
authorJohannes Thumshirn <johannes.thumshirn@wdc.com>
Tue, 2 Jun 2020 10:05:57 +0000 (19:05 +0900)
committerDavid Sterba <dsterba@suse.com>
Mon, 27 Jul 2020 10:55:20 +0000 (12:55 +0200)
When find_first_block_group() finds a block group item in the extent-tree,
it does a lookup of the object in the extent mapping tree and does further
checks on the item.

Factor out this step from find_first_block_group() so we can further
simplify the code.

While we're at it, we can also just return early in
find_first_block_group(), if the tree slot isn't found.

Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/block-group.c

index bfb5f42583363cfa62bae5c462e46b18248b77c6..11244b67434e5429c29c5897ca56d3f20f716f90 100644 (file)
@@ -1532,21 +1532,70 @@ void btrfs_mark_bg_unused(struct btrfs_block_group *bg)
        spin_unlock(&fs_info->unused_bgs_lock);
 }
 
+static int read_bg_from_eb(struct btrfs_fs_info *fs_info, struct btrfs_key *key,
+                          struct btrfs_path *path)
+{
+       struct extent_map_tree *em_tree;
+       struct extent_map *em;
+       struct btrfs_block_group_item bg;
+       struct extent_buffer *leaf;
+       int slot;
+       u64 flags;
+       int ret = 0;
+
+       slot = path->slots[0];
+       leaf = path->nodes[0];
+
+       em_tree = &fs_info->mapping_tree;
+       read_lock(&em_tree->lock);
+       em = lookup_extent_mapping(em_tree, key->objectid, key->offset);
+       read_unlock(&em_tree->lock);
+       if (!em) {
+               btrfs_err(fs_info,
+                         "logical %llu len %llu found bg but no related chunk",
+                         key->objectid, key->offset);
+               return -ENOENT;
+       }
+
+       if (em->start != key->objectid || em->len != key->offset) {
+               btrfs_err(fs_info,
+                       "block group %llu len %llu mismatch with chunk %llu len %llu",
+                       key->objectid, key->offset, em->start, em->len);
+               ret = -EUCLEAN;
+               goto out_free_em;
+       }
+
+       read_extent_buffer(leaf, &bg, btrfs_item_ptr_offset(leaf, slot),
+                          sizeof(bg));
+       flags = btrfs_stack_block_group_flags(&bg) &
+               BTRFS_BLOCK_GROUP_TYPE_MASK;
+
+       if (flags != (em->map_lookup->type & BTRFS_BLOCK_GROUP_TYPE_MASK)) {
+               btrfs_err(fs_info,
+"block group %llu len %llu type flags 0x%llx mismatch with chunk type flags 0x%llx",
+                         key->objectid, key->offset, flags,
+                         (BTRFS_BLOCK_GROUP_TYPE_MASK & em->map_lookup->type));
+               ret = -EUCLEAN;
+       }
+
+out_free_em:
+       free_extent_map(em);
+       return ret;
+}
+
 static int find_first_block_group(struct btrfs_fs_info *fs_info,
                                  struct btrfs_path *path,
                                  struct btrfs_key *key)
 {
        struct btrfs_root *root = fs_info->extent_root;
-       int ret = 0;
+       int ret;
        struct btrfs_key found_key;
        struct extent_buffer *leaf;
-       struct btrfs_block_group_item bg;
-       u64 flags;
        int slot;
 
        ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
        if (ret < 0)
-               goto out;
+               return ret;
 
        while (1) {
                slot = path->slots[0];
@@ -1563,49 +1612,10 @@ static int find_first_block_group(struct btrfs_fs_info *fs_info,
 
                if (found_key.objectid >= key->objectid &&
                    found_key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) {
-                       struct extent_map_tree *em_tree;
-                       struct extent_map *em;
-
-                       em_tree = &fs_info->mapping_tree;
-                       read_lock(&em_tree->lock);
-                       em = lookup_extent_mapping(em_tree, found_key.objectid,
-                                                  found_key.offset);
-                       read_unlock(&em_tree->lock);
-                       if (!em) {
-                               btrfs_err(fs_info,
-                       "logical %llu len %llu found bg but no related chunk",
-                                         found_key.objectid, found_key.offset);
-                               ret = -ENOENT;
-                       } else if (em->start != found_key.objectid ||
-                                  em->len != found_key.offset) {
-                               btrfs_err(fs_info,
-               "block group %llu len %llu mismatch with chunk %llu len %llu",
-                                         found_key.objectid, found_key.offset,
-                                         em->start, em->len);
-                               ret = -EUCLEAN;
-                       } else {
-                               read_extent_buffer(leaf, &bg,
-                                       btrfs_item_ptr_offset(leaf, slot),
-                                       sizeof(bg));
-                               flags = btrfs_stack_block_group_flags(&bg) &
-                                       BTRFS_BLOCK_GROUP_TYPE_MASK;
-
-                               if (flags != (em->map_lookup->type &
-                                             BTRFS_BLOCK_GROUP_TYPE_MASK)) {
-                                       btrfs_err(fs_info,
-"block group %llu len %llu type flags 0x%llx mismatch with chunk type flags 0x%llx",
-                                               found_key.objectid,
-                                               found_key.offset, flags,
-                                               (BTRFS_BLOCK_GROUP_TYPE_MASK &
-                                                em->map_lookup->type));
-                                       ret = -EUCLEAN;
-                               } else {
-                                       ret = 0;
-                               }
-                       }
-                       free_extent_map(em);
-                       goto out;
+                       ret = read_bg_from_eb(fs_info, &found_key, path);
+                       break;
                }
+
                path->slots[0]++;
        }
 out: