xfs
[Top] [All Lists]

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

To: xfs@xxxxxxxxxxx
Subject: [PATCH 1/2] xfs: move shutdown out of xfs_trans_ail_delete_bulk
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Fri, 23 Mar 2012 12:47:42 +1100
In-reply-to: <1332467263-12985-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1332467263-12985-1-git-send-email-david@xxxxxxxxxxxxx>
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

<Prev in Thread] Current Thread [Next in Thread>