@@ -110,7 +110,6 @@ xfs_perag_uninit(
#ifdef __KERNEL__
struct xfs_perag *pag = to_perag(xg);
- xfs_defer_drain_free(&pag->pag_intents_drain);
cancel_delayed_work_sync(&pag->pag_blockgc_work);
xfs_buf_cache_destroy(&pag->pag_bcache);
#endif
@@ -232,7 +231,6 @@ xfs_perag_alloc(
spin_lock_init(&pag->pagb_lock);
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
- xfs_defer_drain_init(&pag->pag_intents_drain);
init_waitqueue_head(&pag->pagb_wait);
pag->pagb_tree = RB_ROOT;
xfs_hooks_init(&pag->pag_rmap_update_hooks);
@@ -240,7 +238,7 @@ xfs_perag_alloc(
error = xfs_buf_cache_init(&pag->pag_bcache);
if (error)
- goto out_defer_drain_free;
+ goto out_free_perag;
/*
* Pre-calculated geometry
@@ -258,8 +256,7 @@ xfs_perag_alloc(
out_buf_cache_destroy:
xfs_buf_cache_destroy(&pag->pag_bcache);
-out_defer_drain_free:
- xfs_defer_drain_free(&pag->pag_intents_drain);
+out_free_perag:
kfree(pag);
return error;
}
@@ -97,15 +97,6 @@ struct xfs_perag {
/* background prealloc block trimming */
struct delayed_work pag_blockgc_work;
- /*
- * We use xfs_drain to track the number of deferred log intent items
- * that have been queued (but not yet processed) so that waiters (e.g.
- * scrub) will not lock resources when other threads are in the middle
- * of processing a chain of intent items only to find momentary
- * inconsistencies.
- */
- struct xfs_defer_drain pag_intents_drain;
-
/* Hook to feed rmapbt updates to an active online repair. */
struct xfs_hooks pag_rmap_update_hooks;
#endif /* __KERNEL__ */
@@ -159,6 +159,8 @@ xfs_group_free(
XFS_IS_CORRUPT(mp, atomic_read(&xg->xg_ref) != 0);
+ xfs_defer_drain_free(&xg->xg_intents_drain);
+
if (uninit)
uninit(xg);
@@ -184,6 +186,7 @@ xfs_group_insert(
#ifdef __KERNEL__
spin_lock_init(&xg->xg_state_lock);
#endif
+ xfs_defer_drain_init(&xg->xg_intents_drain);
/* Active ref owned by mount indicates group is online. */
atomic_set(&xg->xg_active_ref, 1);
@@ -191,6 +194,7 @@ xfs_group_insert(
error = xa_insert(&mp->m_groups[type].xa, index, xg, GFP_KERNEL);
if (error) {
WARN_ON_ONCE(error == -EBUSY);
+ xfs_defer_drain_free(&xg->xg_intents_drain);
return error;
}
@@ -22,6 +22,15 @@ struct xfs_group {
uint16_t xg_checked;
uint16_t xg_sick;
spinlock_t xg_state_lock;
+
+ /*
+ * We use xfs_drain to track the number of deferred log intent items
+ * that have been queued (but not yet processed) so that waiters (e.g.
+ * scrub) will not lock resources when other threads are in the middle
+ * of processing a chain of intent items only to find momentary
+ * inconsistencies.
+ */
+ struct xfs_defer_drain xg_intents_drain;
#endif /* __KERNEL__ */
};