Hi,

This patch just adds the capability for GFS2 to track which function
called gfs2_log_flush. This should make it easier to diagnose
problems based on the sequence of events found in the journals.

Signed-off-by: Bob Peterson <[email protected]>
---
 fs/gfs2/aops.c       |  2 +-
 fs/gfs2/file.c       |  3 ++-
 fs/gfs2/glops.c      | 13 +++++++------
 fs/gfs2/incore.h     | 22 ++++++++++++++++++++++
 fs/gfs2/log.c        | 19 +++++++++++--------
 fs/gfs2/log.h        |  3 ++-
 fs/gfs2/ops_fstype.c |  2 +-
 fs/gfs2/quota.c      |  3 ++-
 fs/gfs2/rgrp.c       |  3 ++-
 fs/gfs2/super.c      |  9 +++++----
 fs/gfs2/trans.c      |  2 +-
 11 files changed, 56 insertions(+), 25 deletions(-)

diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 658ca027cab9..10fa52321a73 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -445,7 +445,7 @@ static int gfs2_jdata_writepages(struct address_space 
*mapping,
 
        ret = gfs2_write_cache_jdata(mapping, wbc);
        if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) {
-               gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH);
+               gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH, LGF_JDATA_WPAGES);
                ret = gfs2_write_cache_jdata(mapping, wbc);
        }
        return ret;
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 58705ef8643a..e180df15e107 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -246,7 +246,8 @@ static int do_gfs2_set_flags(struct file *filp, u32 
reqflags, u32 mask)
        }
        if ((flags ^ new_flags) & GFS2_DIF_JDATA) {
                if (new_flags & GFS2_DIF_JDATA)
-                       gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH);
+                       gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH,
+                                      LGF_SET_FLAGS);
                error = filemap_fdatawrite(inode->i_mapping);
                if (error)
                        goto out;
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index cdd1c5f06f45..f661fbec259c 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -107,7 +107,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
        __gfs2_ail_flush(gl, 0, tr.tr_revokes);
 
        gfs2_trans_end(sdp);
-       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
+       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH, LGF_AIL_EMPTY_GL);
 }
 
 void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
@@ -128,7 +128,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
                return;
        __gfs2_ail_flush(gl, fsync, max_revokes);
        gfs2_trans_end(sdp);
-       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
+       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH, LGF_AIL_FLUSH);
 }
 
 /**
@@ -157,7 +157,7 @@ static void rgrp_go_sync(struct gfs2_glock *gl)
                return;
        GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
 
-       gfs2_log_flush(sdp, gl, NORMAL_FLUSH);
+       gfs2_log_flush(sdp, gl, NORMAL_FLUSH, LGF_RGRP_GO_SYNC);
        filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
        error = filemap_fdatawait_range(mapping, gl->gl_vm.start, 
gl->gl_vm.end);
        mapping_set_error(mapping, error);
@@ -252,7 +252,7 @@ static void inode_go_sync(struct gfs2_glock *gl)
 
        GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
 
-       gfs2_log_flush(gl->gl_name.ln_sbd, gl, NORMAL_FLUSH);
+       gfs2_log_flush(gl->gl_name.ln_sbd, gl, NORMAL_FLUSH, LGF_INODE_GO_SYNC);
        filemap_fdatawrite(metamapping);
        if (isreg) {
                struct address_space *mapping = ip->i_inode.i_mapping;
@@ -303,7 +303,8 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
        }
 
        if (ip == GFS2_I(gl->gl_name.ln_sbd->sd_rindex)) {
-               gfs2_log_flush(gl->gl_name.ln_sbd, NULL, NORMAL_FLUSH);
+               gfs2_log_flush(gl->gl_name.ln_sbd, NULL, NORMAL_FLUSH,
+                              LGF_INODE_GO_INVAL);
                gl->gl_name.ln_sbd->sd_rindex_uptodate = 0;
        }
        if (ip && S_ISREG(ip->i_inode.i_mode))
@@ -495,7 +496,7 @@ static void freeze_go_sync(struct gfs2_glock *gl)
                        gfs2_assert_withdraw(sdp, 0);
                }
                queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work);
-               gfs2_log_flush(sdp, NULL, FREEZE_FLUSH);
+               gfs2_log_flush(sdp, NULL, FREEZE_FLUSH, LGF_FREEZE_GO_SYNC);
        }
 }
 
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 6e18e9793ec4..1e07fa2468f9 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -134,6 +134,28 @@ enum gfs2_state_bits {
        BH_Zeronew = BH_PrivateStart + 2,
 };
 
+enum gfs2_log_flushers {
+       LGF_SHUTDOWN            = 0x701,
+       LGF_JDATA_WPAGES        = 0x702,
+       LGF_SET_FLAGS           = 0x703,
+       LGF_AIL_EMPTY_GL        = 0x704,
+       LGF_AIL_FLUSH           = 0x705,
+       LGF_RGRP_GO_SYNC        = 0x706,
+       LGF_INODE_GO_SYNC       = 0x707,
+       LGF_INODE_GO_INVAL      = 0x708,
+       LGF_FREEZE_GO_SYNC      = 0x709,
+       LGF_KILL_SB             = 0x70a,
+       LGF_DO_SYNC             = 0x70b,
+       LGF_INPLACE_RESERVE     = 0x70c,
+       LGF_WRITE_INODE         = 0x70d,
+       LGF_MAKE_FS_RO          = 0x70e,
+       LGF_SYNC_FS             = 0x70f,
+       LGF_EVICT_INODE         = 0x710,
+       LGF_TRANS_END           = 0x711,
+       LGF_LOGD_JFLUSH_REQD    = 0x712,
+       LGF_LOGD_AIL_FLUSH_REQD = 0x712,
+};
+
 BUFFER_FNS(Pinned, pinned)
 TAS_BUFFER_FNS(Pinned, pinned)
 BUFFER_FNS(Escaped, escaped)
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 311e22ec6716..b62f866220ee 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -654,7 +654,7 @@ void gfs2_write_revokes(struct gfs2_sbd *sdp)
  * Returns: the initialized log buffer descriptor
  */
 
-static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
+static void log_write_header(struct gfs2_sbd *sdp, u32 flags, u32 flusher)
 {
        struct gfs2_log_header_v2 *lh2;
        struct gfs2_log_header *lh;
@@ -692,6 +692,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 
flags)
        lh2->lh_jinode = 
cpu_to_be64(GFS2_I(sdp->sd_jdesc->jd_inode)->i_no_addr);
        lh2->lh_statfs_addr = cpu_to_be64(GFS2_I(sdp->sd_sc_inode)->i_no_addr);
        lh2->lh_quota_addr = cpu_to_be64(GFS2_I(sdp->sd_qc_inode)->i_no_addr);
+       lh2->lh_log_flusher = cpu_to_be32(flusher);
 
        spin_lock(&sdp->sd_statfs_spin);
        lh2->lh_local_total = cpu_to_be64(l_sc->sc_total);
@@ -722,7 +723,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 
flags)
  */
 
 void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
-                   enum gfs2_flush_type type)
+                   enum gfs2_flush_type type, enum gfs2_log_flushers lgf)
 {
        struct gfs2_trans *tr;
        enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state);
@@ -761,11 +762,11 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct 
gfs2_glock *gl,
 
        if (sdp->sd_log_head != sdp->sd_log_flush_head) {
                log_flush_wait(sdp);
-               log_write_header(sdp, 0);
+               log_write_header(sdp, 0, lgf);
        } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){
                atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved 
buffer */
                trace_gfs2_log_blocks(sdp, -1);
-               log_write_header(sdp, 0);
+               log_write_header(sdp, 0, lgf);
        }
        lops_after_commit(sdp, tr);
 
@@ -792,7 +793,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock 
*gl,
                        }
                        atomic_dec(&sdp->sd_log_blks_free); /* Adjust for 
unreserved buffer */
                        trace_gfs2_log_blocks(sdp, -1);
-                       log_write_header(sdp, 0);
+                       log_write_header(sdp, 0, lgf);
                        sdp->sd_log_head = sdp->sd_log_flush_head;
                }
                if (type == SHUTDOWN_FLUSH || type == FREEZE_FLUSH)
@@ -897,7 +898,7 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
 
        sdp->sd_log_flush_head = sdp->sd_log_head;
 
-       log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT);
+       log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, LGF_SHUTDOWN);
 
        gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail);
        gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list));
@@ -953,7 +954,8 @@ int gfs2_logd(void *data)
                did_flush = false;
                if (gfs2_jrnl_flush_reqd(sdp) || t == 0) {
                        gfs2_ail1_empty(sdp);
-                       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
+                       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH,
+                                      LGF_LOGD_JFLUSH_REQD);
                        did_flush = true;
                }
 
@@ -961,7 +963,8 @@ int gfs2_logd(void *data)
                        gfs2_ail1_start(sdp);
                        gfs2_ail1_wait(sdp);
                        gfs2_ail1_empty(sdp);
-                       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
+                       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH,
+                                      LGF_LOGD_AIL_FLUSH_REQD);
                        did_flush = true;
                }
 
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h
index 9499a6049212..32779b1e8fb5 100644
--- a/fs/gfs2/log.h
+++ b/fs/gfs2/log.h
@@ -72,7 +72,8 @@ enum gfs2_flush_type {
        FREEZE_FLUSH
 };
 extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
-                          enum gfs2_flush_type type);
+                          enum gfs2_flush_type type,
+                          enum gfs2_log_flushers lgf);
 extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
 extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
 extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control 
*wbc);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index a3711f543405..d9795d2e54ea 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1382,7 +1382,7 @@ static void gfs2_kill_sb(struct super_block *sb)
                return;
        }
 
-       gfs2_log_flush(sdp, NULL, SYNC_FLUSH);
+       gfs2_log_flush(sdp, NULL, SYNC_FLUSH, LGF_KILL_SB);
        dput(sdp->sd_root_dir);
        dput(sdp->sd_master_dir);
        sdp->sd_root_dir = NULL;
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index e700fb162664..e70d9b0d848f 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -955,7 +955,8 @@ static int do_sync(unsigned int num_qd, struct 
gfs2_quota_data **qda)
                gfs2_glock_dq_uninit(&ghs[qx]);
        inode_unlock(&ip->i_inode);
        kfree(ghs);
-       gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl, NORMAL_FLUSH);
+       gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl, NORMAL_FLUSH,
+                      LGF_DO_SYNC);
        return error;
 }
 
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index b52c5c3ac445..a122181cee81 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -2072,7 +2072,8 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct 
gfs2_alloc_parms *ap)
                }
                /* Flushing the log may release space */
                if (loops == 2)
-                       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
+                       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH,
+                                      LGF_INPLACE_RESERVE);
        }
 
        return -ENOSPC;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 9cb5c9a97d69..d4af64d4551b 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -757,7 +757,8 @@ static int gfs2_write_inode(struct inode *inode, struct 
writeback_control *wbc)
        bool flush_all = (wbc->sync_mode == WB_SYNC_ALL || gfs2_is_jdata(ip));
 
        if (flush_all)
-               gfs2_log_flush(GFS2_SB(inode), ip->i_gl, NORMAL_FLUSH);
+               gfs2_log_flush(GFS2_SB(inode), ip->i_gl, NORMAL_FLUSH,
+                              LGF_WRITE_INODE);
        if (bdi->wb.dirty_exceeded)
                gfs2_ail1_flush(sdp, wbc);
        else
@@ -853,7 +854,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
        gfs2_quota_sync(sdp->sd_vfs, 0);
        gfs2_statfs_sync(sdp->sd_vfs, 0);
 
-       gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH);
+       gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH, LGF_MAKE_FS_RO);
        wait_event(sdp->sd_reserving_log_wait, 
atomic_read(&sdp->sd_reserving_log) == 0);
        gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == 
sdp->sd_jdesc->jd_blocks);
 
@@ -946,7 +947,7 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
 
        gfs2_quota_sync(sb, -1);
        if (wait)
-               gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
+               gfs2_log_flush(sdp, NULL, NORMAL_FLUSH, LGF_SYNC_FS);
        return sdp->sd_log_error;
 }
 
@@ -1650,7 +1651,7 @@ static void gfs2_evict_inode(struct inode *inode)
        goto out_unlock;
 
 out_truncate:
-       gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH);
+       gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH, LGF_EVICT_INODE);
        metamapping = gfs2_glock2aspace(ip->i_gl);
        if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) {
                filemap_fdatawrite(metamapping);
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index a85ca8b2c9ba..1f06dd9e4ff4 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -118,7 +118,7 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
        up_read(&sdp->sd_log_flush_lock);
 
        if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS)
-               gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
+               gfs2_log_flush(sdp, NULL, NORMAL_FLUSH, LGF_TRANS_END);
        if (alloced)
                sb_end_intwrite(sdp->sd_vfs);
 }

Reply via email to