}
if (fs_info->data_reloc_bg &&
(ffe_ctl->for_data_reloc !=
- (block_group->start == fs_info->data_reloc_bg)))
- skip = true;
+ (block_group->start == fs_info->data_reloc_bg))) {
+ /*
+ * Relocation stays in its group. Everyone else stays out of
+ * it only while the other groups can serve them: the
+ * dedication can land after a write was admitted against
+ * this group's stripes (the read-only guard covers that
+ * transition, not this one), and refusing the write here
+ * drops its data at writeback. The class tag on the runs
+ * keeps the two sides from ever sharing a stripe, so a
+ * last-resort allocation in the relocation group is safe,
+ * merely unhelpful to relocation. Zoned's hard exclusion
+ * follows from append-only zones, which do not apply here.
+ */
+ if (ffe_ctl->for_data_reloc ||
+ ffe_ctl->loop < LOOP_ALLOC_CHUNK)
+ skip = true;
+ }
spin_unlock(&fs_info->relocation_bg_lock);
if (dedicated_now && block_group->space_info) {
/* its claimable stripes now belong to relocation alone */