summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_icache.c
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2012-11-06 15:50:47 +0100
committerBen Myers <bpm@sgi.com>2012-11-08 22:34:59 +0100
commit579b62faa5fb16ffeeb88cda5e2c4e95730881af (patch)
treeb0d71a823d2b6e5718786f99921968109d8f644e /fs/xfs/xfs_icache.c
parentxfs: add minimum file size filtering to eofblocks scan (diff)
downloadlinux-579b62faa5fb16ffeeb88cda5e2c4e95730881af.tar.xz
linux-579b62faa5fb16ffeeb88cda5e2c4e95730881af.zip
xfs: add background scanning to clear eofblocks inodes
Create a new mount workqueue and delayed_work to enable background scanning and freeing of eofblocks inodes. The scanner kicks in once speculative preallocation occurs and stops requeueing itself when no eofblocks inodes exist. The scan interval is based on the new 'speculative_prealloc_lifetime' tunable (default to 5m). The background scanner performs unfiltered, best effort scans (which skips inodes under lock contention or with a dirty cache mapping). Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_icache.c')
-rw-r--r--fs/xfs/xfs_icache.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 906e6dcd2c55..96e344e3e927 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -615,6 +615,32 @@ restart:
return last_error;
}
+/*
+ * Background scanning to trim post-EOF preallocated space. This is queued
+ * based on the 'background_prealloc_discard_period' tunable (5m by default).
+ */
+STATIC void
+xfs_queue_eofblocks(
+ struct xfs_mount *mp)
+{
+ rcu_read_lock();
+ if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_EOFBLOCKS_TAG))
+ queue_delayed_work(mp->m_eofblocks_workqueue,
+ &mp->m_eofblocks_work,
+ msecs_to_jiffies(xfs_eofb_secs * 1000));
+ rcu_read_unlock();
+}
+
+void
+xfs_eofblocks_worker(
+ struct work_struct *work)
+{
+ struct xfs_mount *mp = container_of(to_delayed_work(work),
+ struct xfs_mount, m_eofblocks_work);
+ xfs_icache_free_eofblocks(mp, NULL);
+ xfs_queue_eofblocks(mp);
+}
+
int
xfs_inode_ag_iterator(
struct xfs_mount *mp,
@@ -1273,6 +1299,9 @@ xfs_inode_set_eofblocks_tag(
XFS_ICI_EOFBLOCKS_TAG);
spin_unlock(&ip->i_mount->m_perag_lock);
+ /* kick off background trimming */
+ xfs_queue_eofblocks(ip->i_mount);
+
trace_xfs_perag_set_eofblocks(ip->i_mount, pag->pag_agno,
-1, _RET_IP_);
}