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