summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 92cd5087958e..fdda9fbd638e 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1465,3 +1465,99 @@ xfs_hook_call(
{
return srcu_notifier_call_chain(&chain->head, val, priv);
}
+
+#if IS_ENABLED(CONFIG_XFS_ONLINE_SCRUB)
+
+#if IS_ENABLED(CONFIG_XFS_RT)
+static inline void
+xfs_rt_bump_intents(
+ struct xfs_mount *mp)
+{
+ trace_xfs_rt_bump_intents(mp, __return_address);
+
+ atomic_inc(&mp->m_rt_intents);
+}
+
+static inline void
+xfs_rt_drop_intents(
+ struct xfs_mount *mp)
+{
+ trace_xfs_rt_drop_intents(mp, __return_address);
+
+ ASSERT(atomic_read(&mp->m_rt_intents) > 0);
+
+ if (atomic_dec_and_test(&mp->m_rt_intents))
+ wake_up(&mp->m_rt_intents_wq);
+}
+
+int
+xfs_rt_wait_intents(
+ struct xfs_mount *mp)
+{
+ trace_xfs_rt_wait_intents(mp, __return_address);
+
+ return wait_event_killable(mp->m_rt_intents_wq,
+ atomic_read(&mp->m_rt_intents) == 0);
+}
+#else
+static inline void xfs_rt_bump_intents(struct xfs_mount *mp) { }
+static inline void xfs_rt_drop_intents(struct xfs_mount *mp) { }
+#endif /* CONFIG_XFS_RT */
+
+static inline void
+xfs_ag_bump_intents(
+ struct xfs_mount *mp,
+ xfs_agnumber_t agno)
+{
+ struct xfs_perag *pag = xfs_perag_get(mp, agno);
+
+ trace_xfs_perag_bump_intents(pag, __return_address);
+
+ atomic_inc(&pag->pag_intents);
+ xfs_perag_put(pag);
+}
+
+static inline void
+xfs_ag_drop_intents(
+ struct xfs_mount *mp,
+ xfs_agnumber_t agno)
+{
+ struct xfs_perag *pag = xfs_perag_get(mp, agno);
+
+ trace_xfs_perag_drop_intents(pag, __return_address);
+
+ ASSERT(atomic_read(&pag->pag_intents) > 0);
+
+ if (atomic_dec_and_test(&pag->pag_intents))
+ wake_up(&pag->pag_intents_wq);
+ xfs_perag_put(pag);
+}
+
+void
+xfs_fs_bump_intents(struct xfs_mount *mp, bool isrt, xfs_fsblock_t fsb)
+{
+ if (isrt)
+ xfs_rt_bump_intents(mp);
+ else
+ xfs_ag_bump_intents(mp, XFS_FSB_TO_AGNO(mp, fsb));
+}
+
+void
+xfs_fs_drop_intents(struct xfs_mount *mp, bool isrt, xfs_fsblock_t fsb)
+{
+ if (isrt)
+ xfs_rt_drop_intents(mp);
+ else
+ xfs_ag_drop_intents(mp, XFS_FSB_TO_AGNO(mp, fsb));
+}
+
+int
+xfs_perag_wait_intents(
+ struct xfs_perag *pag)
+{
+ trace_xfs_perag_wait_intents(pag, __return_address);
+
+ return wait_event_killable(pag->pag_intents_wq,
+ atomic_read(&pag->pag_intents) == 0);
+}
+#endif /* CONFIG_XFS_ONLINE_SCRUB */