summaryrefslogtreecommitdiff
path: root/fs/gfs2/log.c
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2006-08-24 14:47:17 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-08-25 09:57:41 -0400
commit5dc39fe621ead2fa2a0439a686be4df185861eae (patch)
tree3ca539e18bae3f45f0e807165998440db0f7a033 /fs/gfs2/log.c
parenta2242db0906445491d9ac50bfa756b0de0a25d45 (diff)
[GFS2] Fix journal off-by-one error
log_refund() incorrectly assumed that if a transaction had been touched, it always committed buffers to the incore log. Thus, when you got around to flushing the log, you would need one more block than you committed, to account for the header. So it automatically set reserved to 1, which had the effect of making sdp->sd_log_blks_reserved one greater when you got to gfs2_log_flush(). However, if you don't actually commit anything to the incore log between flushes, you don't need the header, because you aren't writing anything out. With this patch, log_refund() only increments reservered to account for the header if something has been committed since the last flush. Signed-off-by: Benjamin E. Marzinski <bmarzins@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r--fs/gfs2/log.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index a591fb8fae2..af728cb3b32 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -509,7 +509,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
{
- unsigned int reserved = 1;
+ unsigned int reserved = 0;
unsigned int old;
gfs2_log_lock(sdp);
@@ -524,6 +524,8 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
if (sdp->sd_log_commited_revoke)
reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
sizeof(uint64_t));
+ if (reserved)
+ reserved++;
old = sdp->sd_log_blks_free;
sdp->sd_log_blks_free += tr->tr_reserved -