@@ -1894,9 +1894,13 @@ xfs_inodegc_free_space(
struct xfs_mount *mp,
struct xfs_eofblocks *eofb)
{
+ int error;
+
trace_xfs_inodegc_free_space(mp, eofb, _RET_IP_);
- return xfs_inode_walk(mp, XFS_ICI_INODEGC_TAG, eofb);
+ error = xfs_inode_walk(mp, XFS_ICI_INODEGC_TAG, eofb);
+ wake_up(&mp->m_inactive_wait);
+ return error;
}
/* Background inode inactivation worker. */
@@ -1938,6 +1942,46 @@ xfs_inodegc_flush(
flush_workqueue(mp->m_gc_workqueue);
}
+/*
+ * Force all queued inode inactivation work to run immediately, and poll
+ * until the work is complete. Callers should only use this function if they
+ * must inactivate inodes while holding VFS mutexes.
+ */
+void
+xfs_inodegc_flush_poll(
+ struct xfs_mount *mp)
+{
+ struct xfs_perag *pag;
+ xfs_agnumber_t agno;
+ bool queued = false;
+
+ /*
+ * Force to the foreground any inode inactivations that may happen
+ * while we're running our polling loop.
+ */
+ set_bit(XFS_OPFLAG_INACTIVATE_NOW_BIT, &mp->m_opflags);
+
+ for_each_perag_tag(mp, agno, pag, XFS_ICI_INODEGC_TAG) {
+ mod_delayed_work(mp->m_gc_workqueue, &pag->pag_inodegc_work, 0);
+ queued = true;
+ }
+ if (!queued)
+ goto clear;
+
+ /*
+ * Touch the softlockup watchdog every 1/10th of a second while there
+ * are still inactivation-tagged inodes in the filesystem.
+ */
+ while (!wait_event_timeout(mp->m_inactive_wait,
+ !radix_tree_tagged(&mp->m_perag_tree,
+ XFS_ICI_INODEGC_TAG),
+ HZ / 10)) {
+ touch_softlockup_watchdog();
+ }
+clear:
+ clear_bit(XFS_OPFLAG_INACTIVATE_NOW_BIT, &mp->m_opflags);
+}
+
/* Stop all queued inactivation work. */
void
xfs_inodegc_stop(
@@ -76,6 +76,7 @@ void xfs_inew_wait(struct xfs_inode *ip);
void xfs_inodegc_worker(struct work_struct *work);
void xfs_inodegc_flush(struct xfs_mount *mp);
+void xfs_inodegc_flush_poll(struct xfs_mount *mp);
void xfs_inodegc_stop(struct xfs_mount *mp);
void xfs_inodegc_start(struct xfs_mount *mp);
int xfs_inodegc_free_space(struct xfs_mount *mp, struct xfs_eofblocks *eofb);
@@ -61,6 +61,7 @@ typedef __u32 xfs_nlink_t;
#include <linux/ratelimit.h>
#include <linux/rhashtable.h>
#include <linux/xattr.h>
+#include <linux/nmi.h>
#include <asm/page.h>
#include <asm/div64.h>
@@ -1115,7 +1115,7 @@ xfs_unmountfs(
* Flush all the queued inode inactivation work to disk before tearing
* down rt metadata and quotas.
*/
- xfs_inodegc_flush(mp);
+ xfs_inodegc_flush_poll(mp);
xfs_blockgc_stop(mp);
xfs_fs_unreserve_ag_blocks(mp);
@@ -216,6 +216,11 @@ typedef struct xfs_mount {
struct xfs_kobj m_errortag_kobj;
#endif
struct ratelimit_state m_inodegc_ratelimit;
+ /*
+ * Use this to wait for the inode inactivation workqueue to finish
+ * inactivating all the inodes.
+ */
+ struct wait_queue_head m_inactive_wait;
} xfs_mount_t;
#define M_IGEO(mp) (&(mp)->m_ino_geo)
@@ -1798,7 +1798,7 @@ xfs_remount_ro(
* Since this can involve finobt updates, do it now before we lose the
* per-AG space reservations to guarantee that we won't fail there.
*/
- xfs_inodegc_flush(mp);
+ xfs_inodegc_flush_poll(mp);
/* Free the per-AG metadata reservation pool. */
error = xfs_fs_unreserve_ag_blocks(mp);
@@ -1924,6 +1924,7 @@ static int xfs_init_fs_context(
INIT_WORK(&mp->m_flush_inodes_work, xfs_flush_inodes_worker);
INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
mp->m_kobj.kobject.kset = xfs_kset;
+ init_waitqueue_head(&mp->m_inactive_wait);
/*
* We don't create the finobt per-ag space reservation until after log
* recovery, so we must set this to true so that an ifree transaction