Useful for tracking down where specific IOs are being issued from. Signed-off-by: Dave Chinner <dchin...@redhat.com> --- fs/gfs2/log.c | 6 ++++++ fs/gfs2/lops.c | 6 ++++++ fs/gfs2/trace_gfs2.h | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 4511b08..bd26dff 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -121,6 +121,7 @@ __acquires(&sdp->sd_log_lock) lock_buffer(bh); if (test_clear_buffer_dirty(bh)) { bh->b_end_io = end_buffer_write_sync; + trace_gfs2_submit_bh(bh, WRITE_SYNC_PLUG, __func__); submit_bh(WRITE_SYNC_PLUG, bh); } else { unlock_buffer(bh); @@ -610,6 +611,8 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) goto skip_barrier; get_bh(bh); + trace_gfs2_submit_bh(bh, WRITE_SYNC | (1 << BIO_RW_BARRIER) | (1 << + BIO_RW_META), __func__); submit_bh(WRITE_SYNC | (1 << BIO_RW_BARRIER) | (1 << BIO_RW_META), bh); wait_on_buffer(bh); if (buffer_eopnotsupp(bh)) { @@ -619,6 +622,8 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) lock_buffer(bh); skip_barrier: get_bh(bh); + trace_gfs2_submit_bh(bh, WRITE_SYNC | (1 << BIO_RW_META), + __func__); submit_bh(WRITE_SYNC | (1 << BIO_RW_META), bh); wait_on_buffer(bh); } @@ -670,6 +675,7 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp) lock_buffer(bh); if (buffer_mapped(bh) && test_clear_buffer_dirty(bh)) { bh->b_end_io = end_buffer_write_sync; + trace_gfs2_submit_bh(bh, WRITE_SYNC_PLUG, __func__); submit_bh(WRITE_SYNC_PLUG, bh); } else { unlock_buffer(bh); diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index de97632..5708edf 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -198,6 +198,7 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) } gfs2_log_unlock(sdp); + trace_gfs2_submit_bh(bh, WRITE_SYNC_PLUG, __func__); submit_bh(WRITE_SYNC_PLUG, bh); gfs2_log_lock(sdp); @@ -208,6 +209,7 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) gfs2_log_unlock(sdp); lock_buffer(bd2->bd_bh); bh = gfs2_log_fake_buf(sdp, bd2->bd_bh); + trace_gfs2_submit_bh(bh, WRITE_SYNC_PLUG, __func__); submit_bh(WRITE_SYNC_PLUG, bh); gfs2_log_lock(sdp); if (++n >= num) @@ -350,6 +352,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) sdp->sd_log_num_revoke--; if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { + trace_gfs2_submit_bh(bh, WRITE_SYNC_PLUG, __func__); submit_bh(WRITE_SYNC_PLUG, bh); bh = gfs2_log_get_buf(sdp); @@ -367,6 +370,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) } gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); + trace_gfs2_submit_bh(bh, WRITE_SYNC_PLUG, __func__); submit_bh(WRITE_SYNC_PLUG, bh); } @@ -569,6 +573,7 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh, ptr = bh_log_ptr(bh); get_bh(bh); + trace_gfs2_submit_bh(bh, WRITE_SYNC_PLUG, __func__); submit_bh(WRITE_SYNC_PLUG, bh); gfs2_log_lock(sdp); while(!list_empty(list)) { @@ -595,6 +600,7 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh, } else { bh1 = gfs2_log_fake_buf(sdp, bd->bd_bh); } + trace_gfs2_submit_bh(bh1, WRITE_SYNC_PLUG, __func__); submit_bh(WRITE_SYNC_PLUG, bh1); gfs2_log_lock(sdp); ptr += 2; diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h index 148d55c..e9a231d 100644 --- a/fs/gfs2/trace_gfs2.h +++ b/fs/gfs2/trace_gfs2.h @@ -397,6 +397,47 @@ TRACE_EVENT(gfs2_block_alloc, block_state_name(__entry->block_state)) ); +#include <linux/fs.h> +#include <linux/bio.h> + +#define BH_IO_TYPE \ + { READ, "read" }, \ + { WRITE, "write" }, \ + { READA, "readahead" }, \ + { SWRITE, "swrite" }, \ + { READ_SYNC, "read sync" }, \ + { READ_META, "read meta" }, \ + { WRITE_SYNC, "write sync" }, \ + { WRITE_SYNC_PLUG, "write sync plug" }, \ + { WRITE_META, "write meta" }, \ + { WRITE_BARRIER, "write barrier" } + +TRACE_EVENT(gfs2_submit_bh, + TP_PROTO(struct buffer_head *bh, int rw, const char * func), + TP_ARGS(bh, rw, func), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned long long, bno) + __field(unsigned long long, len) + __field(int, rw) + __field(const char *, func) + ), + TP_fast_assign( + __entry->dev = bh->b_bdev->bd_dev; + __entry->bno = bh->b_blocknr; + __entry->len = bh->b_size; + __entry->rw = rw; + __entry->func = func; + ), + TP_printk("dev %d:%d %s bno %llu len %llu caller %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_symbolic(__entry->rw, BH_IO_TYPE), + __entry->bno, + __entry->len, + __entry->func) +); + + #endif /* _TRACE_GFS2_H */ /* This part must be outside protection */ -- 1.6.5