In gfs2_trans_end -> gfs2_log_commit -> gfs2_log_refund, if we don't have a
system transaction, always attach the new transaction even if it only accounts
for revokes.  That way, tr_num_revoke - tr_num_revoke_rm in the system 
transaction
(sdp->sd_log_tr) will be the number of revokes committed so far, and we can use
that in calc_reserved instead.

Signed-off-by: Andreas Gruenbacher <agrue...@redhat.com>
---
 fs/gfs2/incore.h |  1 -
 fs/gfs2/log.c    | 27 ++++++++++-----------------
 2 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index fdf4d942bb1d..3589d02d1df9 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -820,7 +820,6 @@ struct gfs2_sbd {
 
        struct gfs2_trans *sd_log_tr;
        unsigned int sd_log_blks_reserved;
-       int sd_log_committed_revoke;
 
        atomic_t sd_log_pinned;
        unsigned int sd_log_num_revoke;
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 1fdc3b0dee5e..1ce4300aa81a 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -564,21 +564,15 @@ static inline unsigned int log_distance(struct gfs2_sbd 
*sdp, unsigned int newer
 static unsigned int calc_reserved(struct gfs2_sbd *sdp)
 {
        unsigned int reserved = 0;
-       unsigned int mbuf;
-       unsigned int dbuf;
+       unsigned int blocks;
        struct gfs2_trans *tr = sdp->sd_log_tr;
 
-       if (tr) {
-               mbuf = tr->tr_num_buf_new - tr->tr_num_buf_rm;
-               dbuf = tr->tr_num_databuf_new - tr->tr_num_databuf_rm;
-               reserved = mbuf + dbuf;
-               /* Account for header blocks */
-               reserved += DIV_ROUND_UP(mbuf, buf_limit(sdp));
-               reserved += DIV_ROUND_UP(dbuf, databuf_limit(sdp));
-       }
-
-       if (sdp->sd_log_committed_revoke > 0)
-               reserved += gfs2_struct2blk(sdp, sdp->sd_log_committed_revoke);
+       blocks = tr->tr_num_buf_new - tr->tr_num_buf_rm;
+       reserved += blocks + DIV_ROUND_UP(blocks, buf_limit(sdp));
+       blocks = tr->tr_num_databuf_new - tr->tr_num_databuf_rm;
+       reserved += blocks + DIV_ROUND_UP(blocks, databuf_limit(sdp));
+       if (tr->tr_num_revoke - tr->tr_num_revoke_rm)
+               reserved += gfs2_struct2blk(sdp, tr->tr_num_revoke - 
tr->tr_num_revoke_rm);
        /* One for the overall header */
        if (reserved)
                reserved++;
@@ -997,7 +991,8 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock 
*gl, u32 flags)
                if (gfs2_assert_withdraw_delayed(sdp, !sdp->sd_log_num_revoke))
                        goto out_withdraw;
        if (gfs2_assert_withdraw_delayed(sdp,
-                       sdp->sd_log_num_revoke == sdp->sd_log_committed_revoke))
+                       sdp->sd_log_num_revoke ==
+                       (tr ? tr->tr_num_revoke - tr->tr_num_revoke_rm : 0)))
                goto out_withdraw;
 
        gfs2_ordered_write(sdp);
@@ -1025,7 +1020,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct 
gfs2_glock *gl, u32 flags)
        gfs2_log_lock(sdp);
        gfs2_log_update_head(sdp);
        sdp->sd_log_blks_reserved = 0;
-       sdp->sd_log_committed_revoke = 0;
 
        spin_lock(&sdp->sd_ail_lock);
        if (tr && !list_empty(&tr->tr_ail1_list)) {
@@ -1116,12 +1110,11 @@ static void log_refund(struct gfs2_sbd *sdp, struct 
gfs2_trans *tr)
 
        if (sdp->sd_log_tr) {
                gfs2_merge_trans(sdp, tr);
-       } else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) {
+       } else {
                sdp->sd_log_tr = tr;
                set_bit(TR_ATTACHED, &tr->tr_flags);
        }
 
-       sdp->sd_log_committed_revoke += tr->tr_num_revoke - 
tr->tr_num_revoke_rm;
        reserved = calc_reserved(sdp);
        maxres = sdp->sd_log_blks_reserved + tr->tr_reserved;
        gfs2_assert_withdraw(sdp, maxres >= reserved);
-- 
2.26.2

Reply via email to