xfs: acquire ->ail_lock from xfs_trans_ail_delete()
authorBrian Foster <bfoster@redhat.com>
Wed, 6 May 2020 20:25:23 +0000 (13:25 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Thu, 7 May 2020 15:27:47 +0000 (08:27 -0700)
Several callers acquire the lock just prior to the call. Callers
that require ->ail_lock for other purposes already check IN_AIL
state and thus don't require the additional shutdown check in the
helper. Push the lock down into xfs_trans_ail_delete(), open code
the instances that still acquire it, and remove the unnecessary ailp
parameter.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_trans_ail.c
fs/xfs/xfs_trans_priv.h

index 1f7acffc99bae54faafdb6492494c23261033c62..06e306b4928317eff4bf2f144afac9a6721bc804 100644 (file)
@@ -410,7 +410,6 @@ xfs_buf_item_unpin(
 {
        struct xfs_buf_log_item *bip = BUF_ITEM(lip);
        xfs_buf_t               *bp = bip->bli_buf;
-       struct xfs_ail          *ailp = lip->li_ailp;
        int                     stale = bip->bli_flags & XFS_BLI_STALE;
        int                     freed;
 
@@ -452,10 +451,10 @@ xfs_buf_item_unpin(
                }
 
                /*
-                * If we get called here because of an IO error, we may
-                * or may not have the item on the AIL. xfs_trans_ail_delete()
-                * will take care of that situation.
-                * xfs_trans_ail_delete() drops the AIL lock.
+                * If we get called here because of an IO error, we may or may
+                * not have the item on the AIL. xfs_trans_ail_delete() will
+                * take care of that situation. xfs_trans_ail_delete() drops
+                * the AIL lock.
                 */
                if (bip->bli_flags & XFS_BLI_STALE_INODE) {
                        xfs_buf_do_callbacks(bp);
@@ -463,8 +462,7 @@ xfs_buf_item_unpin(
                        list_del_init(&bp->b_li_list);
                        bp->b_iodone = NULL;
                } else {
-                       spin_lock(&ailp->ail_lock);
-                       xfs_trans_ail_delete(ailp, lip, SHUTDOWN_LOG_IO_ERROR);
+                       xfs_trans_ail_delete(lip, SHUTDOWN_LOG_IO_ERROR);
                        xfs_buf_item_relse(bp);
                        ASSERT(bp->b_log_item == NULL);
                }
@@ -1205,22 +1203,19 @@ xfs_buf_iodone(
        struct xfs_buf          *bp,
        struct xfs_log_item     *lip)
 {
-       struct xfs_ail          *ailp = lip->li_ailp;
-
        ASSERT(BUF_ITEM(lip)->bli_buf == bp);
 
        xfs_buf_rele(bp);
 
        /*
-        * If we are forcibly shutting down, this may well be
-        * off the AIL already. That's because we simulate the
-        * log-committed callbacks to unpin these buffers. Or we may never
-        * have put this item on AIL because of the transaction was
-        * aborted forcibly. xfs_trans_ail_delete() takes care of these.
+        * If we are forcibly shutting down, this may well be off the AIL
+        * already. That's because we simulate the log-committed callbacks to
+        * unpin these buffers. Or we may never have put this item on AIL
+        * because of the transaction was aborted forcibly.
+        * xfs_trans_ail_delete() takes care of these.
         *
         * Either way, AIL is useless if we're forcing a shutdown.
         */
-       spin_lock(&ailp->ail_lock);
-       xfs_trans_ail_delete(ailp, lip, SHUTDOWN_CORRUPT_INCORE);
+       xfs_trans_ail_delete(lip, SHUTDOWN_CORRUPT_INCORE);
        xfs_buf_item_free(BUF_ITEM(lip));
 }
index ffe607733c50d722748dc2c92f835127fcfb864d..5fb65f43b980f8404efa6eb6f7ec18a57a37e837 100644 (file)
@@ -1021,6 +1021,7 @@ xfs_qm_dqflush_done(
        struct xfs_dq_logitem   *qip = (struct xfs_dq_logitem *)lip;
        struct xfs_dquot        *dqp = qip->qli_dquot;
        struct xfs_ail          *ailp = lip->li_ailp;
+       xfs_lsn_t               tail_lsn;
 
        /*
         * We only want to pull the item from the AIL if its
@@ -1034,10 +1035,11 @@ xfs_qm_dqflush_done(
            ((lip->li_lsn == qip->qli_flush_lsn) ||
             test_bit(XFS_LI_FAILED, &lip->li_flags))) {
 
-               /* xfs_trans_ail_delete() drops the AIL lock. */
                spin_lock(&ailp->ail_lock);
                if (lip->li_lsn == qip->qli_flush_lsn) {
-                       xfs_trans_ail_delete(ailp, lip, SHUTDOWN_CORRUPT_INCORE);
+                       /* xfs_ail_update_finish() drops the AIL lock */
+                       tail_lsn = xfs_ail_delete_one(ailp, lip);
+                       xfs_ail_update_finish(ailp, tail_lsn);
                } else {
                        /*
                         * Clear the failed state since we are about to drop the
index 2574d01e4a834c6b6404acca87f1f273bc540e2d..cfba691664c7f64d5ba17640938809e2cb362b0c 100644 (file)
@@ -864,13 +864,14 @@ xfs_ail_delete_one(
  */
 void
 xfs_trans_ail_delete(
-       struct xfs_ail          *ailp,
        struct xfs_log_item     *lip,
        int                     shutdown_type)
 {
+       struct xfs_ail          *ailp = lip->li_ailp;
        struct xfs_mount        *mp = ailp->ail_mount;
        xfs_lsn_t               tail_lsn;
 
+       spin_lock(&ailp->ail_lock);
        if (!test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
                spin_unlock(&ailp->ail_lock);
                if (!XFS_FORCED_SHUTDOWN(mp)) {
index 35655eac01a65f83a2d76a4b41970710b07db7f4..e4362fb8d48325a1b35792a9165895e94cbb1ab2 100644 (file)
@@ -94,8 +94,7 @@ xfs_trans_ail_update(
 xfs_lsn_t xfs_ail_delete_one(struct xfs_ail *ailp, struct xfs_log_item *lip);
 void xfs_ail_update_finish(struct xfs_ail *ailp, xfs_lsn_t old_lsn)
                        __releases(ailp->ail_lock);
-void xfs_trans_ail_delete(struct xfs_ail *ailp, struct xfs_log_item *lip,
-               int shutdown_type);
+void xfs_trans_ail_delete(struct xfs_log_item *lip, int shutdown_type);
 
 static inline void
 xfs_trans_ail_remove(
@@ -103,13 +102,16 @@ xfs_trans_ail_remove(
        int                     shutdown_type)
 {
        struct xfs_ail          *ailp = lip->li_ailp;
+       xfs_lsn_t               tail_lsn;
 
        spin_lock(&ailp->ail_lock);
-       /* xfs_trans_ail_delete() drops the AIL lock */
-       if (test_bit(XFS_LI_IN_AIL, &lip->li_flags))
-               xfs_trans_ail_delete(ailp, lip, shutdown_type);
-       else
+       /* xfs_ail_update_finish() drops the AIL lock */
+       if (test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
+               tail_lsn = xfs_ail_delete_one(ailp, lip);
+               xfs_ail_update_finish(ailp, tail_lsn);
+       } else {
                spin_unlock(&ailp->ail_lock);
+       }
 }
 
 void                   xfs_ail_push(struct xfs_ail *, xfs_lsn_t);