summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-01-16 10:12:13 -0800
committerDarrick J. Wong <darrick.wong@oracle.com>2019-02-04 09:31:15 -0800
commitda01851741c0bb94c6ffee814a9faa8c5bca73cc (patch)
tree7af6b9d4142df1135b3d2dcba9b17c48a7ad6605
parent0a88004c1071acbbbd717f78ce3ee4c649b41f6e (diff)
xfs: force inactivation before fallocate when space is low
If we think that inactivation will free enough blocks to make it easier to satisfy an fallocate request, force inactivation. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r--fs/xfs/xfs_bmap_util.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 1eae87cb6d4e..99b9ac8faeb2 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -33,6 +33,7 @@
#include "xfs_iomap.h"
#include "xfs_reflink.h"
#include "xfs_refcount.h"
+#include "xfs_sb.h"
/* Kernel only BMAP related definitions and functions */
@@ -841,6 +842,38 @@ out_unlock:
return error;
}
+/*
+ * If we suspect that the target device isn't going to be able to satisfy the
+ * entire request, try forcing inode inactivation to free up space.
+ */
+static void
+xfs_alloc_reclaim_inactive_space(
+ struct xfs_mount *mp,
+ bool is_rt,
+ xfs_filblks_t allocatesize_fsb)
+{
+ struct xfs_perag *pag;
+ struct xfs_sb *sbp = &mp->m_sb;
+ xfs_extlen_t free;
+ xfs_agnumber_t agno;
+
+ if (is_rt) {
+ if (sbp->sb_frextents * sbp->sb_rextsize >= allocatesize_fsb)
+ return;
+ } else {
+ for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
+ pag = xfs_perag_get(mp, agno);
+ free = pag->pagf_freeblks;
+ xfs_perag_put(pag);
+
+ if (free >= allocatesize_fsb)
+ return;
+ }
+ }
+
+ xfs_inactive_force(mp);
+}
+
int
xfs_alloc_file_space(
struct xfs_inode *ip,
@@ -927,6 +960,8 @@ xfs_alloc_file_space(
quota_flag = XFS_QMOPT_RES_REGBLKS;
}
+ xfs_alloc_reclaim_inactive_space(mp, rt, allocatesize_fsb);
+
/*
* Allocate and setup the transaction.
*/