xfs: use direct calls for dquot IO completion
authorDave Chinner <dchinner@redhat.com>
Mon, 29 Jun 2020 21:48:59 +0000 (14:48 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Mon, 6 Jul 2020 17:46:59 +0000 (10:46 -0700)
Similar to inodes, we can call the dquot IO completion functions
directly from the buffer completion code, removing another user of
log item callbacks for IO completion processing.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@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_quota.h

index a4e416a..f46e5ec 100644 (file)
@@ -15,6 +15,9 @@
 #include "xfs_buf_item.h"
 #include "xfs_inode.h"
 #include "xfs_inode_item.h"
+#include "xfs_quota.h"
+#include "xfs_dquot_item.h"
+#include "xfs_dquot.h"
 #include "xfs_trans_priv.h"
 #include "xfs_trace.h"
 #include "xfs_log.h"
@@ -1209,7 +1212,20 @@ void
 xfs_buf_dquot_iodone(
        struct xfs_buf          *bp)
 {
-       xfs_buf_run_callbacks(bp);
+       struct xfs_buf_log_item *blip = bp->b_log_item;
+       struct xfs_log_item     *lip;
+
+       if (xfs_buf_had_callback_errors(bp))
+               return;
+
+       /* a newly allocated dquot buffer might have a log item attached */
+       if (blip) {
+               lip = &blip->bli_item;
+               lip->li_cb(bp, lip);
+               bp->b_log_item = NULL;
+       }
+
+       xfs_dquot_done(bp);
        xfs_buf_ioend_finish(bp);
 }
 
index 2e2146f..403bc4e 100644 (file)
@@ -1048,9 +1048,8 @@ xfs_qm_dqrele(
  * from the AIL if it has not been re-logged, and unlocking the dquot's
  * flush lock. This behavior is very similar to that of inodes..
  */
-STATIC void
+static void
 xfs_qm_dqflush_done(
-       struct xfs_buf          *bp,
        struct xfs_log_item     *lip)
 {
        struct xfs_dq_logitem   *qip = (struct xfs_dq_logitem *)lip;
@@ -1091,6 +1090,18 @@ xfs_qm_dqflush_done(
        xfs_dqfunlock(dqp);
 }
 
+void
+xfs_dquot_done(
+       struct xfs_buf          *bp)
+{
+       struct xfs_log_item     *lip, *n;
+
+       list_for_each_entry_safe(lip, n, &bp->b_li_list, li_bio_list) {
+               list_del_init(&lip->li_bio_list);
+               xfs_qm_dqflush_done(lip);
+       }
+}
+
 /*
  * Write a modified dquot to disk.
  * The dquot must be locked and the flush lock too taken by caller.
@@ -1180,8 +1191,7 @@ xfs_qm_dqflush(
         * AIL and release the flush lock once the dquot is synced to disk.
         */
        bp->b_flags |= _XBF_DQUOTS;
-       xfs_buf_attach_iodone(bp, xfs_qm_dqflush_done,
-                                 &dqp->q_logitem.qli_item);
+       xfs_buf_attach_iodone(bp, NULL, &dqp->q_logitem.qli_item);
 
        /*
         * If the buffer is pinned then push on the log so we won't
index aa8fc1f..c92ae5e 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 struct xfs_trans;
+struct xfs_buf;
 
 /*
  * This check is done typically without holding the inode lock;
@@ -107,6 +108,8 @@ extern void xfs_qm_mount_quotas(struct xfs_mount *);
 extern void xfs_qm_unmount(struct xfs_mount *);
 extern void xfs_qm_unmount_quotas(struct xfs_mount *);
 
+void           xfs_dquot_done(struct xfs_buf *);
+
 #else
 static inline int
 xfs_qm_vop_dqalloc(struct xfs_inode *ip, kuid_t kuid, kgid_t kgid,
@@ -148,6 +151,12 @@ static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp,
 #define xfs_qm_mount_quotas(mp)
 #define xfs_qm_unmount(mp)
 #define xfs_qm_unmount_quotas(mp)
+
+static inline void xfs_dquot_done(struct xfs_buf *bp)
+{
+       return;
+}
+
 #endif /* CONFIG_XFS_QUOTA */
 
 #define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \