xfs_qwarncnt_t          warnings;
 };
 
+static inline bool
+xfs_dquot_res_over_limits(
+       const struct xfs_dquot_res      *qres)
+{
+       if ((qres->softlimit && qres->softlimit < qres->reserved) ||
+           (qres->hardlimit && qres->hardlimit < qres->reserved))
+               return true;
+       return false;
+}
+
 /*
  * The incore dquot structure
  */
 
  *
  *  - We've accumulated more than one inode cluster buffer's worth of inodes.
  *  - There is less than 5% free space left.
+ *  - Any of the quotas for this inode are near an enforcement limit.
  */
 static inline bool
 xfs_inodegc_want_queue_work(
                                XFS_FDBLOCKS_BATCH) < 0)
                return true;
 
+       if (xfs_inode_near_dquot_enforcement(ip, XFS_DQTYPE_USER))
+               return true;
+
+       if (xfs_inode_near_dquot_enforcement(ip, XFS_DQTYPE_GROUP))
+               return true;
+
+       if (xfs_inode_near_dquot_enforcement(ip, XFS_DQTYPE_PROJ))
+               return true;
+
        return false;
 }
 
 
        }
 }
 
+/* Decide if this inode's dquot is near an enforcement boundary. */
+bool
+xfs_inode_near_dquot_enforcement(
+       struct xfs_inode        *ip,
+       xfs_dqtype_t            type)
+{
+       struct xfs_dquot        *dqp;
+       int64_t                 freesp;
+
+       /* We only care for quotas that are enabled and enforced. */
+       dqp = xfs_inode_dquot(ip, type);
+       if (!dqp || !xfs_dquot_is_enforced(dqp))
+               return false;
+
+       if (xfs_dquot_res_over_limits(&dqp->q_ino) ||
+           xfs_dquot_res_over_limits(&dqp->q_rtb))
+               return true;
+
+       /* For space on the data device, check the various thresholds. */
+       if (!dqp->q_prealloc_hi_wmark)
+               return false;
+
+       if (dqp->q_blk.reserved < dqp->q_prealloc_lo_wmark)
+               return false;
+
+       if (dqp->q_blk.reserved >= dqp->q_prealloc_hi_wmark)
+               return true;
+
+       freesp = dqp->q_prealloc_hi_wmark - dqp->q_blk.reserved;
+       if (freesp < dqp->q_low_space[XFS_QLOWSP_5_PCNT])
+               return true;
+
+       return false;
+}
 
 {
        return xfs_trans_reserve_quota_nblks(NULL, ip, blocks, 0, false);
 }
+bool xfs_inode_near_dquot_enforcement(struct xfs_inode *ip, xfs_dqtype_t type);
 #else
 static inline int
 xfs_qm_vop_dqalloc(struct xfs_inode *ip, kuid_t kuid, kgid_t kgid,
 #define xfs_qm_mount_quotas(mp)
 #define xfs_qm_unmount(mp)
 #define xfs_qm_unmount_quotas(mp)
+#define xfs_inode_near_dquot_enforcement(ip, type)                     (false)
 #endif /* CONFIG_XFS_QUOTA */
 
 static inline int