summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_sysfs.c7
-rw-r--r--fs/xfs/xfs_zone_alloc.h4
-rw-r--r--fs/xfs/xfs_zone_gc.c17
3 files changed, 27 insertions, 1 deletions
diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c
index 6c7909838234..4527119b2961 100644
--- a/fs/xfs/xfs_sysfs.c
+++ b/fs/xfs/xfs_sysfs.c
@@ -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;
}
diff --git a/fs/xfs/xfs_zone_alloc.h b/fs/xfs/xfs_zone_alloc.h
index 4db02816d0fd..8b2ef98c81ef 100644
--- a/fs/xfs/xfs_zone_alloc.h
+++ b/fs/xfs/xfs_zone_alloc.h
@@ -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 */
diff --git a/fs/xfs/xfs_zone_gc.c b/fs/xfs/xfs_zone_gc.c
index 0ff710fa0ee7..a8f71231f351 100644
--- a/fs/xfs/xfs_zone_gc.c
+++ b/fs/xfs/xfs_zone_gc.c
@@ -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)