[RFC PATCH] xfs: Prevent umount from indefinitely waiting on XFS_IFLUSHING flag on stale inodes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Executing xfs/057 can lead to an unmount task to wait indefinitely for
XFS_IFLUSHING flag on some inodes to be cleared. The following timeline
describes as to how inodes can get into such a state.

  Task A               Task B                      Iclog endio processing
  ----------------------------------------------------------------------------
  Inodes are freed

  Inodes items are
  added to the CIL

  CIL contents are
  written to iclog

  iclog->ic_fail_crc
  is set to true

  iclog is submitted
  for writing to the
  disk

                       Last inode in the cluster
                       buffer is freed

                       XFS_[ISTALE/IFLUSHING] is
                       set on all inodes in the
                       cluster buffer

                       XFS_STALE is set on
                       the cluster buffer
                                                   iclog crc error is detected
                       ...                         during endio processing

                       During xfs_trans_commit,    Set XFS_LI_ABORTED on inode
                       log shutdown is detected    items

                       XFS_LI_ABORTED is set       xfs_inode_item_committed()
                       on xfs_buf_log_item         - Unpin the inode since it
                                                   is stale and return -1
                       xfs_buf_log_item is freed
                                                   Inode log items are not
                       xfs_buf is not freed here   processed further since
                       since b_hold has a          xfs_inode_item_committed()
                       non-zero value              returns -1

During normal operation, the stale inodes are processed by
xfs_buf_item_unpin() => xfs_buf_inode_iodone(). This ends up calling
xfs_iflush_abort() which in turn clears the XFS_IFLUSHING flag. However, in
the case of this bug, the xfs_buf_log_item is freed just before the high level
transaction is committed to the CIL.

To overcome this bug, this commit removes the check for log shutdown during
high level transaction commit operation. The log items in the high level
transaction will now be committed to the CIL despite the log being
shutdown. This will allow the CIL processing logic (i.e. xlog_cil_push_work())
to invoke xlog_cil_committed() as part of error handling. This will cause
xfs_buf log item to to be unpinned and the corresponding inodes to be aborted
and have their XFS_IFLUSHING flag cleared.

Signed-off-by: Chandan Babu R <chandanbabu@xxxxxxxxxx>
---
PS: I have tested this patch by executing xfs/057 in a loop for about 24 hours.
On a non-patched kernel, this issue gets recreated within 24 hours.

 fs/xfs/xfs_trans.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index bdf3704dc301..b43436c8abaa 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -868,17 +868,6 @@ __xfs_trans_commit(
 	if (!(tp->t_flags & XFS_TRANS_DIRTY))
 		goto out_unreserve;
 
-	/*
-	 * We must check against log shutdown here because we cannot abort log
-	 * items and leave them dirty, inconsistent and unpinned in memory while
-	 * the log is active. This leaves them open to being written back to
-	 * disk, and that will lead to on-disk corruption.
-	 */
-	if (xlog_is_shutdown(log)) {
-		error = -EIO;
-		goto out_unreserve;
-	}
-
 	ASSERT(tp->t_ticket != NULL);
 
 	/*
-- 
2.43.0





[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux