]> git.baikalelectronics.ru Git - kernel.git/commitdiff
GFS2: Log the reason for log flushes in every log header
authorBob Peterson <rpeterso@redhat.com>
Mon, 8 Jan 2018 15:34:17 +0000 (10:34 -0500)
committerBob Peterson <rpeterso@redhat.com>
Tue, 23 Jan 2018 14:39:20 +0000 (07:39 -0700)
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 <rpeterso@redhat.com>
Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/aops.c
fs/gfs2/file.c
fs/gfs2/glops.c
fs/gfs2/log.c
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c
fs/gfs2/rgrp.c
fs/gfs2/super.c
fs/gfs2/trace_gfs2.h
fs/gfs2/trans.c
include/uapi/linux/gfs2_ondisk.h

index 462c3fd55929171c421c3c4740124905f10d674d..2f725b4a386b38321e0031687fce3db1807ddc2c 100644 (file)
@@ -448,7 +448,8 @@ 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, GFS2_LOG_HEAD_FLUSH_NORMAL);
+               gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                              GFS2_LFC_JDATA_WPAGES);
                ret = gfs2_write_cache_jdata(mapping, wbc);
        }
        return ret;
index 7a02b4e6e9f38d21c9437244b8ed19bcef5d9d95..4f88e201b3f0c810ada56711b20c132556a7ca44 100644 (file)
@@ -247,7 +247,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,
-                                      GFS2_LOG_HEAD_FLUSH_NORMAL);
+                                      GFS2_LOG_HEAD_FLUSH_NORMAL |
+                                      GFS2_LFC_SET_FLAGS);
                error = filemap_fdatawrite(inode->i_mapping);
                if (error)
                        goto out;
index 2daab13a9e0b49d7359c6786846f330148d43669..d8782a7a1e7dd250aa332c21c8d9b479fa11b317 100644 (file)
@@ -107,7 +107,8 @@ 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, GFS2_LOG_HEAD_FLUSH_NORMAL);
+       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                      GFS2_LFC_AIL_EMPTY_GL);
 }
 
 void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
@@ -128,7 +129,8 @@ 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, GFS2_LOG_HEAD_FLUSH_NORMAL);
+       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                      GFS2_LFC_AIL_FLUSH);
 }
 
 /**
@@ -157,7 +159,8 @@ 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, GFS2_LOG_HEAD_FLUSH_NORMAL);
+       gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                      GFS2_LFC_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 +255,8 @@ 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, GFS2_LOG_HEAD_FLUSH_NORMAL);
+       gfs2_log_flush(gl->gl_name.ln_sbd, gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                      GFS2_LFC_INODE_GO_SYNC);
        filemap_fdatawrite(metamapping);
        if (isreg) {
                struct address_space *mapping = ip->i_inode.i_mapping;
@@ -304,7 +308,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,
-                              GFS2_LOG_HEAD_FLUSH_NORMAL);
+                              GFS2_LOG_HEAD_FLUSH_NORMAL |
+                              GFS2_LFC_INODE_GO_INVAL);
                gl->gl_name.ln_sbd->sd_rindex_uptodate = 0;
        }
        if (ip && S_ISREG(ip->i_inode.i_mode))
@@ -496,7 +501,8 @@ 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, GFS2_LOG_HEAD_FLUSH_FREEZE);
+               gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
+                              GFS2_LFC_FREEZE_GO_SYNC);
        }
 }
 
index a2eb13c045917bf17874388b43c69d1105f8c472..cf6b46247df47826b9ea6763f14866124efa2977 100644 (file)
@@ -757,7 +757,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
  * gfs2_log_flush - flush incore transaction(s)
  * @sdp: the filesystem
  * @gl: The glock structure to flush.  If NULL, flush the whole incore log
- * @flags: The log header flags: GFS2_LOG_HEAD_FLUSH_*
+ * @flags: The log header flags: GFS2_LOG_HEAD_FLUSH_* and debug flags
  *
  */
 
@@ -773,7 +773,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
                up_write(&sdp->sd_log_flush_lock);
                return;
        }
-       trace_gfs2_log_flush(sdp, 1);
+       trace_gfs2_log_flush(sdp, 1, flags);
 
        if (flags & GFS2_LOG_HEAD_FLUSH_SHUTDOWN)
                clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
@@ -841,7 +841,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
                        atomic_set(&sdp->sd_freeze_state, SFS_FROZEN);
        }
 
-       trace_gfs2_log_flush(sdp, 0);
+       trace_gfs2_log_flush(sdp, 0, flags);
        up_write(&sdp->sd_log_flush_lock);
 
        kfree(tr);
@@ -937,7 +937,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 | GFS2_LFC_SHUTDOWN);
 
        gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail);
        gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list));
@@ -993,7 +993,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, GFS2_LOG_HEAD_FLUSH_NORMAL);
+                       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                                      GFS2_LFC_LOGD_JFLUSH_REQD);
                        did_flush = true;
                }
 
@@ -1001,7 +1002,8 @@ int gfs2_logd(void *data)
                        gfs2_ail1_start(sdp);
                        gfs2_ail1_wait(sdp);
                        gfs2_ail1_empty(sdp);
-                       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL);
+                       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                                      GFS2_LFC_LOGD_AIL_FLUSH_REQD);
                        did_flush = true;
                }
 
index d6e620beb9db9e8e5366c18e6ff8ddaf77c3b36d..e6a0a8a89ea7e5696ea262b2d1d047b0e9962c00 100644 (file)
@@ -1382,7 +1382,7 @@ static void gfs2_kill_sb(struct super_block *sb)
                return;
        }
 
-       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SYNC);
+       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SYNC | GFS2_LFC_KILL_SB);
        dput(sdp->sd_root_dir);
        dput(sdp->sd_master_dir);
        sdp->sd_root_dir = NULL;
index 2092df19e43348aa44cadce9e290aed8fa0a2621..7a98abd340ee96bdc4ce1cc7816e9c437700b0cc 100644 (file)
@@ -956,7 +956,7 @@ out:
        inode_unlock(&ip->i_inode);
        kfree(ghs);
        gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl,
-                      GFS2_LOG_HEAD_FLUSH_NORMAL);
+                      GFS2_LOG_HEAD_FLUSH_NORMAL | GFS2_LFC_DO_SYNC);
        return error;
 }
 
index 00eab6c0525c8c0d0ccbdb320d6ccdc84c56cb5e..078b002e0a68fd2adbda6b7b846bd7d6394d279d 100644 (file)
@@ -2093,7 +2093,8 @@ next_rgrp:
                }
                /* Flushing the log may release space */
                if (loops == 2)
-                       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL);
+                       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                                      GFS2_LFC_INPLACE_RESERVE);
        }
 
        return -ENOSPC;
index fa3a19eaf0ebf652cdd8808767005cc3f4b43251..50a297b920fcf81e3c04546690c81da578705dae 100644 (file)
@@ -758,7 +758,8 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc)
 
        if (flush_all)
                gfs2_log_flush(GFS2_SB(inode), ip->i_gl,
-                              GFS2_LOG_HEAD_FLUSH_NORMAL);
+                              GFS2_LOG_HEAD_FLUSH_NORMAL |
+                              GFS2_LFC_WRITE_INODE);
        if (bdi->wb.dirty_exceeded)
                gfs2_ail1_flush(sdp, wbc);
        else
@@ -854,7 +855,8 @@ 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, GFS2_LOG_HEAD_FLUSH_SHUTDOWN);
+       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SHUTDOWN |
+                      GFS2_LFC_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);
 
@@ -947,7 +949,8 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
 
        gfs2_quota_sync(sb, -1);
        if (wait)
-               gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL);
+               gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                              GFS2_LFC_SYNC_FS);
        return sdp->sd_log_error;
 }
 
@@ -1651,7 +1654,8 @@ alloc_failed:
        goto out_unlock;
 
 out_truncate:
-       gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL);
+       gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                      GFS2_LFC_EVICT_INODE);
        metamapping = gfs2_glock2aspace(ip->i_gl);
        if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) {
                filemap_fdatawrite(metamapping);
index f67a709589d3afd874de06fde79f92e982d953ce..b9318b49ff8f55bb43c5196b7e299a120e7fa9b2 100644 (file)
@@ -353,26 +353,29 @@ TRACE_EVENT(gfs2_pin,
 /* Flushing the log */
 TRACE_EVENT(gfs2_log_flush,
 
-       TP_PROTO(const struct gfs2_sbd *sdp, int start),
+       TP_PROTO(const struct gfs2_sbd *sdp, int start, u32 flags),
 
-       TP_ARGS(sdp, start),
+       TP_ARGS(sdp, start, flags),
 
        TP_STRUCT__entry(
                __field(        dev_t,  dev                     )
                __field(        int,    start                   )
                __field(        u64,    log_seq                 )
+               __field(        u32,    flags                   )
        ),
 
        TP_fast_assign(
                __entry->dev            = sdp->sd_vfs->s_dev;
                __entry->start          = start;
                __entry->log_seq        = sdp->sd_log_sequence;
+               __entry->flags          = flags;
        ),
 
-       TP_printk("%u,%u log flush %s %llu",
+       TP_printk("%u,%u log flush %s %llu %llx",
                  MAJOR(__entry->dev), MINOR(__entry->dev),
                  __entry->start ? "start" : "end",
-                 (unsigned long long)__entry->log_seq)
+                 (unsigned long long)__entry->log_seq,
+                 (unsigned long long)__entry->flags)
 );
 
 /* Reserving/releasing blocks in the log */
index 7aec6d3434fa365fa612a382a17c4c405837aeea..c75cacaa349b1d11d5b2b2c92e6cf13af4f896b1 100644 (file)
@@ -117,7 +117,8 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
        up_read(&sdp->sd_log_flush_lock);
 
        if (sdp->sd_vfs->s_flags & SB_SYNCHRONOUS)
-               gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL);
+               gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
+                              GFS2_LFC_TRANS_END);
        if (alloced)
                sb_end_intwrite(sdp->sd_vfs);
 }
index 9a81d520f54ac2531bcf498180e6bdcdaea69157..2dc10a034de1adf6e489c15d31b190c0026bd56a 100644 (file)
@@ -411,6 +411,27 @@ struct gfs2_ea_header {
 #define GFS2_LOG_HEAD_RECOVERY         0x00000020 /* Journal recovery */
 #define GFS2_LOG_HEAD_USERSPACE                0x80000000 /* Written by gfs2-utils */
 
+/* Log flush callers */
+#define GFS2_LFC_SHUTDOWN              0x00000100
+#define GFS2_LFC_JDATA_WPAGES          0x00000200
+#define GFS2_LFC_SET_FLAGS             0x00000400
+#define GFS2_LFC_AIL_EMPTY_GL          0x00000800
+#define GFS2_LFC_AIL_FLUSH             0x00001000
+#define GFS2_LFC_RGRP_GO_SYNC          0x00002000
+#define GFS2_LFC_INODE_GO_SYNC         0x00004000
+#define GFS2_LFC_INODE_GO_INVAL                0x00008000
+#define GFS2_LFC_FREEZE_GO_SYNC                0x00010000
+#define GFS2_LFC_KILL_SB               0x00020000
+#define GFS2_LFC_DO_SYNC               0x00040000
+#define GFS2_LFC_INPLACE_RESERVE       0x00080000
+#define GFS2_LFC_WRITE_INODE           0x00100000
+#define GFS2_LFC_MAKE_FS_RO            0x00200000
+#define GFS2_LFC_SYNC_FS               0x00400000
+#define GFS2_LFC_EVICT_INODE           0x00800000
+#define GFS2_LFC_TRANS_END             0x01000000
+#define GFS2_LFC_LOGD_JFLUSH_REQD      0x02000000
+#define GFS2_LFC_LOGD_AIL_FLUSH_REQD   0x04000000
+
 #define LH_V1_SIZE (offsetofend(struct gfs2_log_header, lh_hash))
 
 struct gfs2_log_header {