u64 total_claimable_reloc = 0;
int raid;
- if (!(sinfo->flags & BTRFS_BLOCK_GROUP_DATA))
+ /*
+ * Data groups under stripe_alloc and metadata groups under
+ * stripe_meta both place extents in whole stripes only, so
+ * both carry trapped free space. Mixed groups are refused.
+ */
+ if (!(sinfo->flags & (BTRFS_BLOCK_GROUP_DATA |
+ BTRFS_BLOCK_GROUP_METADATA)))
continue;
down_read(&sinfo->groups_sem);
for (raid = 0; raid < BTRFS_NR_RAID_TYPES; raid++) {
* btrfs_can_overcommit check here, and we need to pass in
* BTRFS_RESERVE_NO_FLUSH to give ourselves the most amount of
* leeway to allow us to mark this block group as read only.
+ *
+ * As for data above: a stripe_meta group's trapped bytes are
+ * already in the space_info total, do not re-provide them.
*/
- if (btrfs_can_overcommit(sinfo, num_bytes, BTRFS_RESERVE_NO_FLUSH))
+ u64 trapped = 0;
+
+ if (READ_ONCE(cache->stripe_unusable_ready))
+ trapped = min(READ_ONCE(cache->stripe_unusable), num_bytes);
+ if (btrfs_can_overcommit(sinfo, num_bytes - trapped,
+ BTRFS_RESERVE_NO_FLUSH))
ret = 0;
}
u64 trapped;
u64 claimable;
- if (!btrfs_is_stripe_alloc_bg(bg))
+ if (!btrfs_is_stripe_alloc_bg(bg) && !btrfs_is_stripe_meta_bg(bg))
return;
spin_lock(&ctl->tree_lock);
u64 nstripes;
u32 *freep;
- if (!btrfs_is_stripe_alloc_bg(bg))
+ if (!btrfs_is_stripe_alloc_bg(bg) && !btrfs_is_stripe_meta_bg(bg))
return;
nstripes = stripe_unusable_nstripes(bg);