return 0;
 }
 
+/*
+ * Enhanced version of chunk item checker.
+ *
+ * The common btrfs_check_chunk_valid() doesn't check item size since it needs
+ * to work on super block sys_chunk_array which doesn't have full item ptr.
+ */
+static int check_leaf_chunk_item(struct extent_buffer *leaf,
+                                struct btrfs_chunk *chunk,
+                                struct btrfs_key *key, int slot)
+{
+       int num_stripes;
+
+       if (btrfs_item_size_nr(leaf, slot) < sizeof(struct btrfs_chunk)) {
+               chunk_err(leaf, chunk, key->offset,
+                       "invalid chunk item size: have %u expect [%zu, %u)",
+                       btrfs_item_size_nr(leaf, slot),
+                       sizeof(struct btrfs_chunk),
+                       BTRFS_LEAF_DATA_SIZE(leaf->fs_info));
+               return -EUCLEAN;
+       }
+
+       num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
+       /* Let btrfs_check_chunk_valid() handle this error type */
+       if (num_stripes == 0)
+               goto out;
+
+       if (btrfs_chunk_item_size(num_stripes) !=
+           btrfs_item_size_nr(leaf, slot)) {
+               chunk_err(leaf, chunk, key->offset,
+                       "invalid chunk item size: have %u expect %lu",
+                       btrfs_item_size_nr(leaf, slot),
+                       btrfs_chunk_item_size(num_stripes));
+               return -EUCLEAN;
+       }
+out:
+       return btrfs_check_chunk_valid(leaf, chunk, key->offset);
+}
+
 __printf(3, 4)
 __cold
 static void dev_item_err(const struct extent_buffer *eb, int slot,
                break;
        case BTRFS_CHUNK_ITEM_KEY:
                chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
-               ret = btrfs_check_chunk_valid(leaf, chunk, key->offset);
+               ret = check_leaf_chunk_item(leaf, chunk, key, slot);
                break;
        case BTRFS_DEV_ITEM_KEY:
                ret = check_dev_item(leaf, key, slot);