summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_qm_syscalls.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2022-06-01 17:05:06 -0700
committerDarrick J. Wong <djwong@kernel.org>2022-06-06 18:33:56 -0700
commit94a9820d18b9473146a115321c6ee92e565ed73d (patch)
tree57f387ab8f1cd9d0c527a1a0b5b9cc84c4ec036b /fs/xfs/xfs_qm_syscalls.c
parent63fcc99497e220dfefc9f15739b0cf5f47db9fe5 (diff)
xfs: introduce xfs_inodegc_push()
The current blocking mechanism for pushing the inodegc queue out to disk can result in systems becoming unusable when there is a long running inodegc operation. This is because the statfs() implementation currently issues a blocking flush of the inodegc queue and a significant number of common system utilities will call statfs() to discover something about the underlying filesystem. This can result in userspace operations getting stuck on inodegc progress, and when trying to remove a heavily reflinked file on slow storage with a full journal, this can result in delays measuring in hours. Avoid this problem by adding "push" function that expedites the flushing of the inodegc queue, but doesn't wait for it to complete. Convert xfs_fs_statfs() to use this mechanism so it doesn't block but it does ensure that queued operations are expedited. Fixes: ab23a7768739 ("xfs: per-cpu deferred inode inactivation queues") Reported-by: Chris Dunlop <chris@onthe.net.au> Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/xfs_qm_syscalls.c')
-rw-r--r--fs/xfs/xfs_qm_syscalls.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 74ac9ca9e119..20aa5aeffff0 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -454,9 +454,9 @@ xfs_qm_scall_getquota(
struct xfs_dquot *dqp;
int error;
- /* Flush inodegc work at the start of a quota reporting scan. */
+ /* Push inodegc work at the start of a quota reporting scan. */
if (id == 0)
- xfs_inodegc_flush(mp);
+ xfs_inodegc_push(mp);
/*
* Try to get the dquot. We don't want it allocated on disk, so don't
@@ -496,9 +496,9 @@ xfs_qm_scall_getquota_next(
struct xfs_dquot *dqp;
int error;
- /* Flush inodegc work at the start of a quota reporting scan. */
+ /* Push inodegc work at the start of a quota reporting scan. */
if (*id == 0)
- xfs_inodegc_flush(mp);
+ xfs_inodegc_push(mp);
error = xfs_qm_dqget_next(mp, *id, type, &dqp);
if (error)