[PATCH 1/2] xfs: move shutdown out of xfs_trans_ail_delete_bulk

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

 



From: Dave Chinner <dchinner@xxxxxxxxxx>

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@xxxxxxxxxx>
---
 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@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs


[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux