Skip to contentSkip to conversation

xfs: don't hold the XFS_ILOCK while flushing pages in swapext

PATCH In review Dave Chinner 3 participants 3 messages Jul 27, 2010 XFS filesystem

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 xfs: don't hold the XFS_ILOCK while flushing pages in swapext

From: Dave Chinner <[email protected]>

Otherwise it'll deadlock during allocation/block mapping.

---
 fs/xfs/xfs_dfrag.c |   31 ++++++++++++++++++-------------
 1 files changed, 18 insertions(+), 13 deletions(-)
fs/xfs/xfs_dfrag.c +18 -13
index 3b9582c..f04a79a 100644
@@ -229,29 +229,34 @@ xfs_swap_extents(
 	 * below.
 	 */
 	xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
+
+	/*
+	 * can't hold the ILOCK while flushing pages, so flush now we won't get
+	 * new pages cached as we hold the XFS_IOLOCK_EXCL.
+	 */
+	if (VN_CACHED(VFS_I(tip)) != 0) {
+		error = xfs_flushinval_pages(tip, 0, -1,
+				FI_REMAPF_LOCKED);
+		if (error)
+			goto out_unlock;
+	}
+
 	xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
 
-	/* Verify that both files have the same format */
-	if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
+	/* Verify we have no cached pages for ftmp */
+	if (VN_CACHED(VFS_I(tip)) != 0) {
 		error = XFS_ERROR(EINVAL);
 		goto out_unlock;
 	}
 
-	/* Verify both files are either real-time or non-realtime */
-	if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) {
+	/* Verify that both files have the same format */
+	if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
 		error = XFS_ERROR(EINVAL);
 		goto out_unlock;
 	}
 
-	if (VN_CACHED(VFS_I(tip)) != 0) {
-		error = xfs_flushinval_pages(tip, 0, -1,
-				FI_REMAPF_LOCKED);
-		if (error)
-			goto out_unlock;
-	}
-
-	/* Verify O_DIRECT for ftmp */
-	if (VN_CACHED(VFS_I(tip)) != 0) {
+	/* Verify both files are either real-time or non-realtime */
+	if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) {
 		error = XFS_ERROR(EINVAL);
 		goto out_unlock;
 	}
Signature · 6 lines
1.7.1

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Reviewed-by on v1 1/1
#1 lore raw

fs/xfs/xfs_dfrag.c xfs_swap_extents( · line 237

Quoted 6 lines · Dave Chinner
fs/xfs/xfs_dfrag.c +6 -0
+
+	/*
+	 * can't hold the ILOCK while flushing pages, so flush now we won't get
+	 * new pages cached as we hold the XFS_IOLOCK_EXCL.
+	 */
+	if (VN_CACHED(VFS_I(tip)) != 0) {

There's really no point in the VN_CACHED check here. Not only does xfs_flushinval_pages repeat it at the beginning, but it's also rather superflous as filemap_write_and_wait deals with the condition of no attached pages efficiently.

Otherwise looks good,

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

Reviewed-by on v1 1/1
#2 lore raw
In reply to Dave Chinner
Quoted 3 lines · Dave Chinner

From: Dave Chinner <[email protected]>

Otherwise it'll deadlock during allocation/block mapping.

Is this the cause of the xfs_fsr hangs?

Looks good, anyway.

Quoted 1 line

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs