summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_icache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_icache.c')
-rw-r--r--fs/xfs/xfs_icache.c96
1 files changed, 31 insertions, 65 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 34cc84fc7391..c6ef4d14fb8d 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1328,41 +1328,24 @@ xfs_inode_free_eofblocks(
}
/*
- * Background scanning to trim post-EOF preallocated space. This is queued
- * based on the 'speculative_prealloc_lifetime' tunable (5m by default).
+ * Background scanning to trim preallocated space. This is queued based on the
+ * 'speculative_prealloc_lifetime' tunable (5m by default).
*/
-void
-xfs_queue_eofblocks(
- struct xfs_mount *mp)
+static inline void
+xfs_blockgc_queue(
+ struct xfs_mount *mp)
{
rcu_read_lock();
if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_BLOCKGC_TAG))
- queue_delayed_work(mp->m_eofblocks_workqueue,
- &mp->m_eofblocks_work,
- msecs_to_jiffies(xfs_eofb_secs * 1000));
+ queue_delayed_work(mp->m_blockgc_workqueue,
+ &mp->m_blockgc_work,
+ msecs_to_jiffies(xfs_blockgc_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);
-
- if (!sb_start_write_trylock(mp->m_super))
- return;
- xfs_inode_walk(mp, 0, xfs_inode_free_eofblocks, NULL,
- XFS_ICI_BLOCKGC_TAG);
- sb_end_write(mp->m_super);
-
- xfs_queue_eofblocks(mp);
-}
-
static void
xfs_blockgc_set_iflag(
struct xfs_inode *ip,
- void (*execute)(struct xfs_mount *mp),
unsigned long iflag)
{
struct xfs_mount *mp = ip->i_mount;
@@ -1397,7 +1380,7 @@ xfs_blockgc_set_iflag(
spin_unlock(&ip->i_mount->m_perag_lock);
/* kick off background trimming */
- execute(ip->i_mount);
+ xfs_blockgc_queue(ip->i_mount);
trace_xfs_perag_set_blockgc(ip->i_mount, pag->pag_agno, -1,
_RET_IP_);
@@ -1412,7 +1395,7 @@ xfs_inode_set_eofblocks_tag(
xfs_inode_t *ip)
{
trace_xfs_inode_set_eofblocks_tag(ip);
- return xfs_blockgc_set_iflag(ip, xfs_queue_eofblocks, XFS_IEOFBLOCKS);
+ return xfs_blockgc_set_iflag(ip, XFS_IEOFBLOCKS);
}
static void
@@ -1556,45 +1539,12 @@ out_iolock:
return ret;
}
-/*
- * Background scanning to trim preallocated CoW space. This is queued
- * based on the 'speculative_cow_prealloc_lifetime' tunable (5m by default).
- * (We'll just piggyback on the post-EOF prealloc space workqueue.)
- */
-void
-xfs_queue_cowblocks(
- struct xfs_mount *mp)
-{
- rcu_read_lock();
- if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_BLOCKGC_TAG))
- queue_delayed_work(mp->m_eofblocks_workqueue,
- &mp->m_cowblocks_work,
- msecs_to_jiffies(xfs_cowb_secs * 1000));
- rcu_read_unlock();
-}
-
-void
-xfs_cowblocks_worker(
- struct work_struct *work)
-{
- struct xfs_mount *mp = container_of(to_delayed_work(work),
- struct xfs_mount, m_cowblocks_work);
-
- if (!sb_start_write_trylock(mp->m_super))
- return;
- xfs_inode_walk(mp, 0, xfs_inode_free_cowblocks, NULL,
- XFS_ICI_BLOCKGC_TAG);
- sb_end_write(mp->m_super);
-
- xfs_queue_cowblocks(mp);
-}
-
void
xfs_inode_set_cowblocks_tag(
xfs_inode_t *ip)
{
trace_xfs_inode_set_cowblocks_tag(ip);
- return xfs_blockgc_set_iflag(ip, xfs_queue_cowblocks, XFS_ICOWBLOCKS);
+ return xfs_blockgc_set_iflag(ip, XFS_ICOWBLOCKS);
}
void
@@ -1610,8 +1560,7 @@ void
xfs_stop_block_reaping(
struct xfs_mount *mp)
{
- cancel_delayed_work_sync(&mp->m_eofblocks_work);
- cancel_delayed_work_sync(&mp->m_cowblocks_work);
+ cancel_delayed_work_sync(&mp->m_blockgc_work);
}
/* Enable post-EOF and CoW block auto-reclamation. */
@@ -1619,8 +1568,7 @@ void
xfs_start_block_reaping(
struct xfs_mount *mp)
{
- xfs_queue_eofblocks(mp);
- xfs_queue_cowblocks(mp);
+ xfs_blockgc_queue(mp);
}
/* Scan all incore inodes for block preallocations that we can remove. */
@@ -1644,6 +1592,24 @@ xfs_blockgc_scan(
return 0;
}
+/* Background worker that trims preallocated space. */
+void
+xfs_blockgc_worker(
+ struct work_struct *work)
+{
+ struct xfs_mount *mp = container_of(to_delayed_work(work),
+ struct xfs_mount, m_blockgc_work);
+ int error;
+
+ if (!sb_start_write_trylock(mp->m_super))
+ return;
+ error = xfs_blockgc_scan(mp, NULL);
+ if (error)
+ xfs_info(mp, "preallocation gc worker failed, err=%d", error);
+ sb_end_write(mp->m_super);
+ xfs_blockgc_queue(mp);
+}
+
/*
* Try to free space in the filesystem by purging eofblocks and cowblocks.
*/