gfs2: Remove active journal side effect from gfs2_write_log_header
authorAndreas Gruenbacher <agruenba@redhat.com>
Wed, 28 Aug 2019 20:21:34 +0000 (22:21 +0200)
committerAndreas Gruenbacher <agruenba@redhat.com>
Tue, 12 Nov 2019 14:17:53 +0000 (15:17 +0100)
Function gfs2_write_log_header can be used to write a log header into any of
the journals of a filesystem.  When used on the node's own journal,
gfs2_write_log_header advances the current position in the log
(sdp->sd_log_flush_head) as a side effect, through function gfs2_log_bmap.

This is confusing, and it also means that we can't use gfs2_log_bmap for other
journals even if they have an extent map.  So clean this mess up by not
advancing sdp->sd_log_flush_head in gfs2_write_log_header or gfs2_log_bmap
anymore and making that a responsibility of the callers instead.

This is related to commit 7c70b896951c ("gfs2: clean_journal improperly set
sd_log_flush_head").

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/log.c
fs/gfs2/lops.c
fs/gfs2/lops.h
fs/gfs2/recovery.c

index 58e237fba565060b4677d59a50739c8e44c8add8..162246fafc2ec55d9c5839c24c79c4b978239452 100644 (file)
@@ -707,7 +707,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
        lh->lh_nsec = cpu_to_be32(tv.tv_nsec);
        lh->lh_sec = cpu_to_be64(tv.tv_sec);
        if (!list_empty(&jd->extent_list))
-               dblock = gfs2_log_bmap(sdp);
+               dblock = gfs2_log_bmap(jd, lblock);
        else {
                int ret = gfs2_lblk_to_dblk(jd->jd_inode, lblock, &dblock);
                if (gfs2_assert_withdraw(sdp, ret == 0))
@@ -768,6 +768,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
        sdp->sd_log_idle = (tail == sdp->sd_log_flush_head);
        gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail,
                              sdp->sd_log_flush_head, flags, op_flags);
+       gfs2_log_incr_head(sdp);
 
        if (sdp->sd_log_tail != tail)
                log_pull_tail(sdp, tail);
index 5b17979af5396ee6e5eb0d85bc94bb293e75bc47..313b83ef665722fab6a355982ed04983e82cfa75 100644 (file)
@@ -129,7 +129,7 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
        atomic_dec(&sdp->sd_log_pinned);
 }
 
-static void gfs2_log_incr_head(struct gfs2_sbd *sdp)
+void gfs2_log_incr_head(struct gfs2_sbd *sdp)
 {
        BUG_ON((sdp->sd_log_flush_head == sdp->sd_log_tail) &&
               (sdp->sd_log_flush_head != sdp->sd_log_head));
@@ -138,18 +138,13 @@ static void gfs2_log_incr_head(struct gfs2_sbd *sdp)
                sdp->sd_log_flush_head = 0;
 }
 
-u64 gfs2_log_bmap(struct gfs2_sbd *sdp)
+u64 gfs2_log_bmap(struct gfs2_jdesc *jd, unsigned int lblock)
 {
-       unsigned int lbn = sdp->sd_log_flush_head;
        struct gfs2_journal_extent *je;
-       u64 block;
 
-       list_for_each_entry(je, &sdp->sd_jdesc->extent_list, list) {
-               if ((lbn >= je->lblock) && (lbn < (je->lblock + je->blocks))) {
-                       block = je->dblock + lbn - je->lblock;
-                       gfs2_log_incr_head(sdp);
-                       return block;
-               }
+       list_for_each_entry(je, &jd->extent_list, list) {
+               if (lblock >= je->lblock && lblock < je->lblock + je->blocks)
+                       return je->dblock + lblock - je->lblock;
        }
 
        return -1;
@@ -351,8 +346,11 @@ void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page,
 
 static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh)
 {
-       gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh),
-                      gfs2_log_bmap(sdp));
+       u64 dblock;
+
+       dblock = gfs2_log_bmap(sdp->sd_jdesc, sdp->sd_log_flush_head);
+       gfs2_log_incr_head(sdp);
+       gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh), dblock);
 }
 
 /**
@@ -369,8 +367,11 @@ static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh)
 void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page)
 {
        struct super_block *sb = sdp->sd_vfs;
-       gfs2_log_write(sdp, page, sb->s_blocksize, 0,
-                      gfs2_log_bmap(sdp));
+       u64 dblock;
+
+       dblock = gfs2_log_bmap(sdp->sd_jdesc, sdp->sd_log_flush_head);
+       gfs2_log_incr_head(sdp);
+       gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock);
 }
 
 /**
index 9c059957a73326584b4097a2cb9b4e9219b2051f..9c5e4e491e03d871cd60aa17b459c72d226d6a82 100644 (file)
@@ -18,7 +18,8 @@
         ~(2 * sizeof(__be64) - 1))
 
 extern const struct gfs2_log_operations *gfs2_log_ops[];
-extern u64 gfs2_log_bmap(struct gfs2_sbd *sdp);
+extern void gfs2_log_incr_head(struct gfs2_sbd *sdp);
+extern u64 gfs2_log_bmap(struct gfs2_jdesc *jd, unsigned int lbn);
 extern void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page,
                           unsigned size, unsigned offset, u64 blkno);
 extern void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page);
index f4aa8551277be361db5c88d013f9606e560b72d3..85f830e56945877c83c58911d1674b5f1f5e96ba 100644 (file)
@@ -263,11 +263,13 @@ static void clean_journal(struct gfs2_jdesc *jd,
        u32 lblock = head->lh_blkno;
 
        gfs2_replay_incr_blk(jd, &lblock);
-       if (jd->jd_jid == sdp->sd_lockstruct.ls_jid)
-               sdp->sd_log_flush_head = lblock;
        gfs2_write_log_header(sdp, jd, head->lh_sequence + 1, 0, lblock,
                              GFS2_LOG_HEAD_UNMOUNT | GFS2_LOG_HEAD_RECOVERY,
                              REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC);
+       if (jd->jd_jid == sdp->sd_lockstruct.ls_jid) {
+               sdp->sd_log_flush_head = lblock;
+               gfs2_log_incr_head(sdp);
+       }
 }