[07/10] xfs: force inode inactivation and retry fs writes when there isn't space
diff mbox series

Message ID 157784096361.1362752.6646122257069139549.stgit@magnolia
State New
Headers show
Series
  • xfs: deferred inode inactivation
Related show

Commit Message

Darrick J. Wong Jan. 1, 2020, 1:09 a.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

Any time we try to modify a file's contents and it fails due to ENOSPC
or EDQUOT, force inactivation work to free up some resources and try one
more time.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_iomap.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

Patch
diff mbox series

diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index b398f197d748..192852499729 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -883,6 +883,7 @@  xfs_buffered_write_iomap_begin(
 	struct xfs_iext_cursor	icur, ccur;
 	xfs_fsblock_t		prealloc_blocks = 0;
 	bool			eof = false, cow_eof = false, shared = false;
+	bool			cleared_space = false;
 	int			allocfork = XFS_DATA_FORK;
 	int			error = 0;
 
@@ -893,6 +894,7 @@  xfs_buffered_write_iomap_begin(
 
 	ASSERT(!XFS_IS_REALTIME_INODE(ip));
 
+start_over:
 	xfs_ilock(ip, XFS_ILOCK_EXCL);
 
 	if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, XFS_DATA_FORK)) ||
@@ -1035,6 +1037,18 @@  xfs_buffered_write_iomap_begin(
 		break;
 	case -ENOSPC:
 	case -EDQUOT:
+		/*
+		 * If the delalloc reservation failed due to a lack of space,
+		 * try to flush inactive inodes to free some space.
+		 */
+		if (!cleared_space) {
+			cleared_space = true;
+			allocfork = XFS_DATA_FORK;
+			xfs_iunlock(ip, XFS_ILOCK_EXCL);
+			xfs_inactive_force(mp);
+			error = 0;
+			goto start_over;
+		}
 		/* retry without any preallocation */
 		trace_xfs_delalloc_enospc(ip, offset, count);
 		if (prealloc_blocks) {