diff --git a/fs/xfs/xfs_zone_gc.c b/fs/xfs/xfs_zone_gc.c index 7efeecd2d85f..aaa0a3119d91 100644 --- a/fs/xfs/xfs_zone_gc.c +++ b/fs/xfs/xfs_zone_gc.c @@ -171,25 +171,37 @@ xfs_zoned_need_gc( s64 available, free, threshold; s32 remainder; + /* If we have no reclaimable blocks, running GC is useless. */ if (!xfs_zoned_have_reclaimable(mp->m_zone_info)) return false; + /* + * In order to avoid file fragmentation as much as possible, we should + * make sure that we can open enough zones. So trigger GC if the number + * of blocks immediately available for writes is lower than the total + * number of blocks from all possible open zones. + */ available = xfs_estimate_freecounter(mp, XC_FREE_RTAVAILABLE); - if (available < xfs_rtgs_to_rfsbs(mp, mp->m_max_open_zones - XFS_OPEN_GC_ZONES)) return true; - free = xfs_estimate_freecounter(mp, XC_FREE_RTEXTENTS); + /* + * For cases where the user wants to be more aggressive with GC, + * the sysfs attribute zonegc_low_space may be set to a non zero value, + * to indicate that GC should try to maintain at least zonegc_low_space + * percent of the free space to be directly available for writing. Check + * this here. + */ + if (!mp->m_zonegc_low_space) + return false; + free = xfs_estimate_freecounter(mp, XC_FREE_RTEXTENTS); threshold = div_s64_rem(free, 100, &remainder); threshold = threshold * mp->m_zonegc_low_space + remainder * div_s64(mp->m_zonegc_low_space, 100); - if (available < threshold) - return true; - - return false; + return available < threshold; } static struct xfs_zone_gc_data *