]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: start gc on zonegc_low_space attribute updates
authorHans Holmberg <hans.holmberg@wdc.com>
Wed, 25 Mar 2026 12:43:12 +0000 (13:43 +0100)
committerCarlos Maiolino <cem@kernel.org>
Mon, 30 Mar 2026 14:34:05 +0000 (16:34 +0200)
Start gc if the agressiveness of zone garbage collection is changed
by the user (if the file system is not read only).

Without this change, the new setting will not be taken into account
until the gc thread is woken up by e.g. a write.

Cc: stable@vger.kernel.org # v6.15
Fixes: 845abeb1f06a8a ("xfs: add tunable threshold parameter for triggering zone GC")
Signed-off-by: Hans Holmberg <hans.holmberg@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/xfs_sysfs.c
fs/xfs/xfs_zone_alloc.h
fs/xfs/xfs_zone_gc.c

index 6c79098382346358b919baa00cfaf34497ede751..4527119b29619fb8059734aa3e921b24defc1e29 100644 (file)
@@ -14,6 +14,7 @@
 #include "xfs_log_priv.h"
 #include "xfs_mount.h"
 #include "xfs_zones.h"
+#include "xfs_zone_alloc.h"
 
 struct xfs_sysfs_attr {
        struct attribute attr;
@@ -724,6 +725,7 @@ zonegc_low_space_store(
        const char              *buf,
        size_t                  count)
 {
+       struct xfs_mount        *mp = zoned_to_mp(kobj);
        int                     ret;
        unsigned int            val;
 
@@ -734,7 +736,10 @@ zonegc_low_space_store(
        if (val > 100)
                return -EINVAL;
 
-       zoned_to_mp(kobj)->m_zonegc_low_space = val;
+       if (mp->m_zonegc_low_space != val) {
+               mp->m_zonegc_low_space = val;
+               xfs_zone_gc_wakeup(mp);
+       }
 
        return count;
 }
index 4db02816d0fdad038e9d4904eed12f61e82bd99b..8b2ef98c81eff830a9197301758b085c27933e32 100644 (file)
@@ -51,6 +51,7 @@ int xfs_mount_zones(struct xfs_mount *mp);
 void xfs_unmount_zones(struct xfs_mount *mp);
 void xfs_zone_gc_start(struct xfs_mount *mp);
 void xfs_zone_gc_stop(struct xfs_mount *mp);
+void xfs_zone_gc_wakeup(struct xfs_mount *mp);
 #else
 static inline int xfs_mount_zones(struct xfs_mount *mp)
 {
@@ -65,6 +66,9 @@ static inline void xfs_zone_gc_start(struct xfs_mount *mp)
 static inline void xfs_zone_gc_stop(struct xfs_mount *mp)
 {
 }
+static inline void xfs_zone_gc_wakeup(struct xfs_mount *mp)
+{
+}
 #endif /* CONFIG_XFS_RT */
 
 #endif /* _XFS_ZONE_ALLOC_H */
index 0ff710fa0ee70147b08c7ceeafc1f373eb7519ba..a8f71231f351db2c8e21e9226ad72efb9c20bd5b 100644 (file)
@@ -1171,6 +1171,23 @@ xfs_zone_gc_stop(
                kthread_park(mp->m_zone_info->zi_gc_thread);
 }
 
+void
+xfs_zone_gc_wakeup(
+       struct xfs_mount        *mp)
+{
+       struct super_block      *sb = mp->m_super;
+
+       /*
+        * If we are unmounting the file system we must not try to
+        * wake gc as m_zone_info might have been freed already.
+        */
+       if (down_read_trylock(&sb->s_umount)) {
+               if (!xfs_is_readonly(mp))
+                       wake_up_process(mp->m_zone_info->zi_gc_thread);
+               up_read(&sb->s_umount);
+       }
+}
+
 int
 xfs_zone_gc_mount(
        struct xfs_mount        *mp)