Skip to content

Commit e771da0

Browse files
Christoph Hellwigcmaiolino
authored andcommitted
xfs: delay initial open of the GC zone
The code currently used to select the new GC target zone when the previous one is full also handles the case where there is no current GC target zone at all. Make use of that to simplify the logic in xfs_zone_gc_mount. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
1 parent 29a7b26 commit e771da0

1 file changed

Lines changed: 20 additions & 25 deletions

File tree

fs/xfs/xfs_zone_gc.c

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ xfs_zone_gc_select_victim(
527527
return true;
528528
}
529529

530-
static struct xfs_open_zone *
530+
static int
531531
xfs_zone_gc_steal_open(
532532
struct xfs_zone_info *zi)
533533
{
@@ -538,15 +538,18 @@ xfs_zone_gc_steal_open(
538538
if (!found || oz->oz_allocated < found->oz_allocated)
539539
found = oz;
540540
}
541-
542-
if (found) {
543-
found->oz_is_gc = true;
544-
list_del_init(&found->oz_entry);
545-
zi->zi_nr_open_zones--;
541+
if (!found) {
542+
spin_unlock(&zi->zi_open_zones_lock);
543+
return -EIO;
546544
}
547545

546+
trace_xfs_zone_gc_target_opened(found->oz_rtg);
547+
found->oz_is_gc = true;
548+
list_del_init(&found->oz_entry);
549+
zi->zi_nr_open_zones--;
550+
zi->zi_open_gc_zone = found;
548551
spin_unlock(&zi->zi_open_zones_lock);
549-
return found;
552+
return 0;
550553
}
551554

552555
static struct xfs_open_zone *
@@ -1194,31 +1197,24 @@ xfs_zone_gc_mount(
11941197
{
11951198
struct xfs_zone_info *zi = mp->m_zone_info;
11961199
struct xfs_zone_gc_data *data;
1197-
struct xfs_open_zone *oz;
11981200
int error;
11991201

12001202
/*
1201-
* If there are no free zones available for GC, pick the open zone with
1203+
* If there are no free zones available for GC, or the number of open
1204+
* zones has reached the open zone limit, pick the open zone with
12021205
* the least used space to GC into. This should only happen after an
1203-
* unclean shutdown near ENOSPC while GC was ongoing.
1204-
*
1205-
* We also need to do this for the first gc zone allocation if we
1206-
* unmounted while at the open limit.
1206+
* unclean shutdown while GC was ongoing. Otherwise a GC zone will
1207+
* be selected from the free zone pool on demand.
12071208
*/
12081209
if (!xfs_group_marked(mp, XG_TYPE_RTG, XFS_RTG_FREE) ||
1209-
zi->zi_nr_open_zones == mp->m_max_open_zones)
1210-
oz = xfs_zone_gc_steal_open(zi);
1211-
else
1212-
oz = xfs_open_zone(mp, WRITE_LIFE_NOT_SET, true);
1213-
if (!oz) {
1214-
xfs_warn(mp, "unable to allocate a zone for gc");
1215-
error = -EIO;
1216-
goto out;
1210+
zi->zi_nr_open_zones >= mp->m_max_open_zones) {
1211+
error = xfs_zone_gc_steal_open(zi);
1212+
if (error) {
1213+
xfs_warn(mp, "unable to steal an open zone for gc");
1214+
return error;
1215+
}
12171216
}
12181217

1219-
trace_xfs_zone_gc_target_opened(oz->oz_rtg);
1220-
zi->zi_open_gc_zone = oz;
1221-
12221218
data = xfs_zone_gc_data_alloc(mp);
12231219
if (!data) {
12241220
error = -ENOMEM;
@@ -1241,7 +1237,6 @@ xfs_zone_gc_mount(
12411237
kfree(data);
12421238
out_put_gc_zone:
12431239
xfs_open_zone_put(zi->zi_open_gc_zone);
1244-
out:
12451240
return error;
12461241
}
12471242

0 commit comments

Comments
 (0)