@@ -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);
}
@@ -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
@@ -174,6 +174,7 @@ void xfs_qm_dqput(struct xfs_dquot *dqp);
void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *);
void xfs_dquot_set_prealloc_limits(struct xfs_dquot *);
+void xfs_dquot_done(struct xfs_buf *);
static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp)
{