public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: xfs@oss.sgi.com
Subject: [PATCH 1/2] xfs: move shutdown out of xfs_trans_ail_delete_bulk
Date: Fri, 23 Mar 2012 12:47:42 +1100	[thread overview]
Message-ID: <1332467263-12985-2-git-send-email-david@fromorbit.com> (raw)
In-Reply-To: <1332467263-12985-1-git-send-email-david@fromorbit.com>

From: Dave Chinner <dchinner@redhat.com>

xfs_trans_ail_delete_bulk() can be called from different contexts so
if the itemis not in the AIL we need different shutdown for each
context.  Move the shutdown to the call locations to prepare for
changing the shutdown methods where appropriate.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/xfs_buf_item.c     |   12 ++++++++++--
 fs/xfs/xfs_dquot.c        |    9 ++++++---
 fs/xfs/xfs_dquot_item.c   |    5 ++++-
 fs/xfs/xfs_extfree_item.c |    7 ++++++-
 fs/xfs/xfs_iget.c         |    9 ++++++---
 fs/xfs/xfs_inode_item.c   |   16 +++++++++++++---
 fs/xfs/xfs_log_recover.c  |   12 +++++++-----
 fs/xfs/xfs_trans_ail.c    |   10 ++++++----
 fs/xfs/xfs_trans_priv.h   |    6 +++---
 9 files changed, 61 insertions(+), 25 deletions(-)

diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index eac97ef..3e5f654 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -454,8 +454,13 @@ xfs_buf_item_unpin(
 			bp->b_fspriv = NULL;
 			bp->b_iodone = NULL;
 		} else {
+			int error;
+
 			spin_lock(&ailp->xa_lock);
-			xfs_trans_ail_delete(ailp, (xfs_log_item_t *)bip);
+			error = xfs_trans_ail_delete(ailp, lip);
+			if (error == EFSCORRUPTED)
+				xfs_force_shutdown(ailp->xa_mount,
+						   SHUTDOWN_CORRUPT_INCORE);
 			xfs_buf_item_relse(bp);
 			ASSERT(bp->b_fspriv == NULL);
 		}
@@ -1030,6 +1035,7 @@ xfs_buf_iodone(
 	struct xfs_log_item	*lip)
 {
 	struct xfs_ail		*ailp = lip->li_ailp;
+	int			error;
 
 	ASSERT(BUF_ITEM(lip)->bli_buf == bp);
 
@@ -1045,6 +1051,8 @@ xfs_buf_iodone(
 	 * Either way, AIL is useless if we're forcing a shutdown.
 	 */
 	spin_lock(&ailp->xa_lock);
-	xfs_trans_ail_delete(ailp, lip);
+	error = xfs_trans_ail_delete(ailp, lip);
+	if (error == EFSCORRUPTED)
+		xfs_force_shutdown(ailp->xa_mount, SHUTDOWN_CORRUPT_INCORE);
 	xfs_buf_item_free(BUF_ITEM(lip));
 }
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 4be16a0..cd5bd4b 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -856,9 +856,12 @@ xfs_qm_dqflush_done(
 
 		/* xfs_trans_ail_delete() drops the AIL lock. */
 		spin_lock(&ailp->xa_lock);
-		if (lip->li_lsn == qip->qli_flush_lsn)
-			xfs_trans_ail_delete(ailp, lip);
-		else
+		if (lip->li_lsn == qip->qli_flush_lsn) {
+			int	error = xfs_trans_ail_delete(ailp, lip);
+			if (error == EFSCORRUPTED)
+				xfs_force_shutdown(ailp->xa_mount,
+						SHUTDOWN_CORRUPT_INCORE);
+		} else
 			spin_unlock(&ailp->xa_lock);
 	}
 
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
index 34baeae..69a098c 100644
--- a/fs/xfs/xfs_dquot_item.c
+++ b/fs/xfs/xfs_dquot_item.c
@@ -448,13 +448,16 @@ xfs_qm_qoffend_logitem_committed(
 	struct xfs_qoff_logitem	*qfe = QOFF_ITEM(lip);
 	struct xfs_qoff_logitem	*qfs = qfe->qql_start_lip;
 	struct xfs_ail		*ailp = qfs->qql_item.li_ailp;
+	int			error;
 
 	/*
 	 * Delete the qoff-start logitem from the AIL.
 	 * xfs_trans_ail_delete() drops the AIL lock.
 	 */
 	spin_lock(&ailp->xa_lock);
-	xfs_trans_ail_delete(ailp, (xfs_log_item_t *)qfs);
+	error = xfs_trans_ail_delete(ailp, (struct xfs_log_item *)qfs);
+	if (error == EFSCORRUPTED)
+		xfs_force_shutdown(ailp->xa_mount, SHUTDOWN_CORRUPT_INCORE);
 
 	kmem_free(qfs);
 	kmem_free(qfe);
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 35c2aff..4ccf2b6 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -62,9 +62,14 @@ __xfs_efi_release(
 	struct xfs_ail		*ailp = efip->efi_item.li_ailp;
 
 	if (!test_and_clear_bit(XFS_EFI_COMMITTED, &efip->efi_flags)) {
+		int	error;
+
 		spin_lock(&ailp->xa_lock);
 		/* xfs_trans_ail_delete() drops the AIL lock. */
-		xfs_trans_ail_delete(ailp, &efip->efi_item);
+		error = xfs_trans_ail_delete(ailp, &efip->efi_item);
+		if (error == EFSCORRUPTED)
+			xfs_force_shutdown(ailp->xa_mount,
+						SHUTDOWN_CORRUPT_INCORE);
 		xfs_efi_item_free(efip);
 	}
 }
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index bcc6c24..4700ba4 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -135,9 +135,12 @@ xfs_inode_free(
 				       XFS_FORCED_SHUTDOWN(ip->i_mount));
 		if (lip->li_flags & XFS_LI_IN_AIL) {
 			spin_lock(&ailp->xa_lock);
-			if (lip->li_flags & XFS_LI_IN_AIL)
-				xfs_trans_ail_delete(ailp, lip);
-			else
+			if (lip->li_flags & XFS_LI_IN_AIL) {
+				int	error = xfs_trans_ail_delete(ailp, lip);
+				if (error == EFSCORRUPTED)
+					xfs_force_shutdown(ailp->xa_mount,
+							SHUTDOWN_CORRUPT_INCORE);
+			} else
 				spin_unlock(&ailp->xa_lock);
 		}
 		xfs_inode_item_destroy(ip);
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 05d924e..b0a813f 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -837,7 +837,9 @@ xfs_iflush_done(
 	 */
 	if (need_ail) {
 		struct xfs_log_item *log_items[need_ail];
-		int i = 0;
+		int	i = 0;
+		int	error;
+
 		spin_lock(&ailp->xa_lock);
 		for (blip = lip; blip; blip = blip->li_bio_list) {
 			iip = INODE_ITEM(blip);
@@ -848,7 +850,10 @@ xfs_iflush_done(
 			ASSERT(i <= need_ail);
 		}
 		/* xfs_trans_ail_delete_bulk() drops the AIL lock. */
-		xfs_trans_ail_delete_bulk(ailp, log_items, i);
+		error = xfs_trans_ail_delete_bulk(ailp, log_items, i);
+		if (error == EFSCORRUPTED)
+			xfs_force_shutdown(ailp->xa_mount,
+						SHUTDOWN_CORRUPT_INCORE);
 	}
 
 
@@ -887,8 +892,13 @@ xfs_iflush_abort(
 		if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
 			spin_lock(&ailp->xa_lock);
 			if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
+				int	error;
 				/* xfs_trans_ail_delete() drops the AIL lock. */
-				xfs_trans_ail_delete(ailp, (xfs_log_item_t *)iip);
+				error = xfs_trans_ail_delete(ailp,
+							(xfs_log_item_t *)iip);
+				if (error == EFSCORRUPTED)
+					xfs_force_shutdown(ailp->xa_mount,
+							SHUTDOWN_CORRUPT_INCORE);
 			} else
 				spin_unlock(&ailp->xa_lock);
 		}
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 7c75c73..63df121 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2638,11 +2638,13 @@ xlog_recover_efd_pass2(
 		if (lip->li_type == XFS_LI_EFI) {
 			efip = (xfs_efi_log_item_t *)lip;
 			if (efip->efi_format.efi_id == efi_id) {
-				/*
-				 * xfs_trans_ail_delete() drops the
-				 * AIL lock.
-				 */
-				xfs_trans_ail_delete(ailp, lip);
+				int	error;
+
+				/* xfs_trans_ail_delete() drops the AIL lock. */
+				error = xfs_trans_ail_delete(ailp, lip);
+				if (error == EFSCORRUPTED)
+					xfs_force_shutdown(ailp->xa_mount,
+							SHUTDOWN_CORRUPT_INCORE);
 				xfs_efi_item_free(efip);
 				spin_lock(&ailp->xa_lock);
 				break;
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 1dead07..4c94a1f 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -694,9 +694,10 @@ xfs_trans_ail_update_bulk(
  * of traffic on the lock, especially during IO completion.
  *
  * This function must be called with the AIL lock held.  The lock is dropped
- * before returning.
+ * before returning. If EFSCORRUPTED is returned, the caller must shut down the
+ * filesystem.
  */
-void
+int
 xfs_trans_ail_delete_bulk(
 	struct xfs_ail		*ailp,
 	struct xfs_log_item	**log_items,
@@ -718,9 +719,9 @@ xfs_trans_ail_delete_bulk(
 				xfs_alert_tag(mp, XFS_PTAG_AILDELETE,
 		"%s: attempting to delete a log item that is not in the AIL",
 						__func__);
-				xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+				return EFSCORRUPTED;
 			}
-			return;
+			return 0;
 		}
 
 		xfs_ail_delete(ailp, lip);
@@ -735,6 +736,7 @@ xfs_trans_ail_delete_bulk(
 		xlog_assign_tail_lsn(ailp->xa_mount);
 		xfs_log_space_wake(ailp->xa_mount);
 	}
+	return 0;
 }
 
 /*
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
index 8ab2ced..8ca636a 100644
--- a/fs/xfs/xfs_trans_priv.h
+++ b/fs/xfs/xfs_trans_priv.h
@@ -89,15 +89,15 @@ xfs_trans_ail_update(
 	xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn);
 }
 
-void	xfs_trans_ail_delete_bulk(struct xfs_ail *ailp,
+int	xfs_trans_ail_delete_bulk(struct xfs_ail *ailp,
 				struct xfs_log_item **log_items, int nr_items)
 				__releases(ailp->xa_lock);
-static inline void
+static inline int
 xfs_trans_ail_delete(
 	struct xfs_ail	*ailp,
 	xfs_log_item_t	*lip) __releases(ailp->xa_lock)
 {
-	xfs_trans_ail_delete_bulk(ailp, &lip, 1);
+	return xfs_trans_ail_delete_bulk(ailp, &lip, 1);
 }
 
 void			xfs_ail_push(struct xfs_ail *, xfs_lsn_t);
-- 
1.7.9

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  reply	other threads:[~2012-03-23  1:48 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-23  1:47 [PATCH 0/2] xfs: fix a class of shutdown hangs Dave Chinner
2012-03-23  1:47 ` Dave Chinner [this message]
2012-03-24 17:01   ` [PATCH 1/2] xfs: move shutdown out of xfs_trans_ail_delete_bulk Christoph Hellwig
2012-03-23  1:47 ` [PATCH 2/2] xfs: avoid shutdown hang in xlog_wait() Dave Chinner
2012-03-24 17:03   ` Christoph Hellwig
2012-03-24 22:46     ` Dave Chinner
2012-03-25 11:28       ` Christoph Hellwig
2012-03-27  9:45         ` [PATCH v2] shutdown hang fix (was Re: [PATCH 2/2] xfs: avoid shutdown hang in xlog_wait()) Dave Chinner
2012-03-27  9:57           ` Christoph Hellwig
2012-04-06 17:42           ` Mark Tinguely

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1332467263-12985-2-git-send-email-david@fromorbit.com \
    --to=david@fromorbit.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox