These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / fs / nilfs2 / segment.c
index c6abbad..3b65ada 100644 (file)
@@ -77,6 +77,36 @@ enum {
        NILFS_ST_DONE,
 };
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/nilfs2.h>
+
+/*
+ * nilfs_sc_cstage_inc(), nilfs_sc_cstage_set(), nilfs_sc_cstage_get() are
+ * wrapper functions of stage count (nilfs_sc_info->sc_stage.scnt). Users of
+ * the variable must use them because transition of stage count must involve
+ * trace events (trace_nilfs2_collection_stage_transition).
+ *
+ * nilfs_sc_cstage_get() isn't required for the above purpose because it doesn't
+ * produce tracepoint events. It is provided just for making the intention
+ * clear.
+ */
+static inline void nilfs_sc_cstage_inc(struct nilfs_sc_info *sci)
+{
+       sci->sc_stage.scnt++;
+       trace_nilfs2_collection_stage_transition(sci);
+}
+
+static inline void nilfs_sc_cstage_set(struct nilfs_sc_info *sci, int next_scnt)
+{
+       sci->sc_stage.scnt = next_scnt;
+       trace_nilfs2_collection_stage_transition(sci);
+}
+
+static inline int nilfs_sc_cstage_get(struct nilfs_sc_info *sci)
+{
+       return sci->sc_stage.scnt;
+}
+
 /* State flags of collection */
 #define NILFS_CF_NODE          0x0001  /* Collecting node blocks */
 #define NILFS_CF_IFILE_STARTED 0x0002  /* IFILE stage has started */
@@ -184,11 +214,18 @@ int nilfs_transaction_begin(struct super_block *sb,
 {
        struct the_nilfs *nilfs;
        int ret = nilfs_prepare_segment_lock(ti);
+       struct nilfs_transaction_info *trace_ti;
 
        if (unlikely(ret < 0))
                return ret;
-       if (ret > 0)
+       if (ret > 0) {
+               trace_ti = current->journal_info;
+
+               trace_nilfs2_transaction_transition(sb, trace_ti,
+                                   trace_ti->ti_count, trace_ti->ti_flags,
+                                   TRACE_NILFS2_TRANSACTION_BEGIN);
                return 0;
+       }
 
        sb_start_intwrite(sb);
 
@@ -199,6 +236,11 @@ int nilfs_transaction_begin(struct super_block *sb,
                ret = -ENOSPC;
                goto failed;
        }
+
+       trace_ti = current->journal_info;
+       trace_nilfs2_transaction_transition(sb, trace_ti, trace_ti->ti_count,
+                                           trace_ti->ti_flags,
+                                           TRACE_NILFS2_TRANSACTION_BEGIN);
        return 0;
 
  failed:
@@ -231,6 +273,8 @@ int nilfs_transaction_commit(struct super_block *sb)
        ti->ti_flags |= NILFS_TI_COMMIT;
        if (ti->ti_count > 0) {
                ti->ti_count--;
+               trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
+                           ti->ti_flags, TRACE_NILFS2_TRANSACTION_COMMIT);
                return 0;
        }
        if (nilfs->ns_writer) {
@@ -242,6 +286,9 @@ int nilfs_transaction_commit(struct super_block *sb)
                        nilfs_segctor_do_flush(sci, 0);
        }
        up_read(&nilfs->ns_segctor_sem);
+       trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
+                           ti->ti_flags, TRACE_NILFS2_TRANSACTION_COMMIT);
+
        current->journal_info = ti->ti_save;
 
        if (ti->ti_flags & NILFS_TI_SYNC)
@@ -260,10 +307,15 @@ void nilfs_transaction_abort(struct super_block *sb)
        BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
        if (ti->ti_count > 0) {
                ti->ti_count--;
+               trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
+                           ti->ti_flags, TRACE_NILFS2_TRANSACTION_ABORT);
                return;
        }
        up_read(&nilfs->ns_segctor_sem);
 
+       trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
+                   ti->ti_flags, TRACE_NILFS2_TRANSACTION_ABORT);
+
        current->journal_info = ti->ti_save;
        if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
                kmem_cache_free(nilfs_transaction_cachep, ti);
@@ -309,6 +361,9 @@ static void nilfs_transaction_lock(struct super_block *sb,
        current->journal_info = ti;
 
        for (;;) {
+               trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
+                           ti->ti_flags, TRACE_NILFS2_TRANSACTION_TRYLOCK);
+
                down_write(&nilfs->ns_segctor_sem);
                if (!test_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags))
                        break;
@@ -320,6 +375,9 @@ static void nilfs_transaction_lock(struct super_block *sb,
        }
        if (gcflag)
                ti->ti_flags |= NILFS_TI_GC;
+
+       trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
+                           ti->ti_flags, TRACE_NILFS2_TRANSACTION_LOCK);
 }
 
 static void nilfs_transaction_unlock(struct super_block *sb)
@@ -332,6 +390,9 @@ static void nilfs_transaction_unlock(struct super_block *sb)
 
        up_write(&nilfs->ns_segctor_sem);
        current->journal_info = ti->ti_save;
+
+       trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
+                           ti->ti_flags, TRACE_NILFS2_TRANSACTION_UNLOCK);
 }
 
 static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci,
@@ -1062,7 +1123,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
        size_t ndone;
        int err = 0;
 
-       switch (sci->sc_stage.scnt) {
+       switch (nilfs_sc_cstage_get(sci)) {
        case NILFS_ST_INIT:
                /* Pre-processes */
                sci->sc_stage.flags = 0;
@@ -1071,7 +1132,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                        sci->sc_nblk_inc = 0;
                        sci->sc_curseg->sb_sum.flags = NILFS_SS_LOGBGN;
                        if (mode == SC_LSEG_DSYNC) {
-                               sci->sc_stage.scnt = NILFS_ST_DSYNC;
+                               nilfs_sc_cstage_set(sci, NILFS_ST_DSYNC);
                                goto dsync_mode;
                        }
                }
@@ -1079,10 +1140,10 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                sci->sc_stage.dirty_file_ptr = NULL;
                sci->sc_stage.gc_inode_ptr = NULL;
                if (mode == SC_FLUSH_DAT) {
-                       sci->sc_stage.scnt = NILFS_ST_DAT;
+                       nilfs_sc_cstage_set(sci, NILFS_ST_DAT);
                        goto dat_stage;
                }
-               sci->sc_stage.scnt++;  /* Fall through */
+               nilfs_sc_cstage_inc(sci);  /* Fall through */
        case NILFS_ST_GC:
                if (nilfs_doing_gc()) {
                        head = &sci->sc_gc_inodes;
@@ -1103,7 +1164,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                        }
                        sci->sc_stage.gc_inode_ptr = NULL;
                }
-               sci->sc_stage.scnt++;  /* Fall through */
+               nilfs_sc_cstage_inc(sci);  /* Fall through */
        case NILFS_ST_FILE:
                head = &sci->sc_dirty_files;
                ii = list_prepare_entry(sci->sc_stage.dirty_file_ptr, head,
@@ -1125,10 +1186,10 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                }
                sci->sc_stage.dirty_file_ptr = NULL;
                if (mode == SC_FLUSH_FILE) {
-                       sci->sc_stage.scnt = NILFS_ST_DONE;
+                       nilfs_sc_cstage_set(sci, NILFS_ST_DONE);
                        return 0;
                }
-               sci->sc_stage.scnt++;
+               nilfs_sc_cstage_inc(sci);
                sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED;
                /* Fall through */
        case NILFS_ST_IFILE:
@@ -1136,7 +1197,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                                              &nilfs_sc_file_ops);
                if (unlikely(err))
                        break;
-               sci->sc_stage.scnt++;
+               nilfs_sc_cstage_inc(sci);
                /* Creating a checkpoint */
                err = nilfs_segctor_create_checkpoint(sci);
                if (unlikely(err))
@@ -1147,7 +1208,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                                              &nilfs_sc_file_ops);
                if (unlikely(err))
                        break;
-               sci->sc_stage.scnt++;  /* Fall through */
+               nilfs_sc_cstage_inc(sci);  /* Fall through */
        case NILFS_ST_SUFILE:
                err = nilfs_sufile_freev(nilfs->ns_sufile, sci->sc_freesegs,
                                         sci->sc_nfreesegs, &ndone);
@@ -1163,7 +1224,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                                              &nilfs_sc_file_ops);
                if (unlikely(err))
                        break;
-               sci->sc_stage.scnt++;  /* Fall through */
+               nilfs_sc_cstage_inc(sci);  /* Fall through */
        case NILFS_ST_DAT:
  dat_stage:
                err = nilfs_segctor_scan_file(sci, nilfs->ns_dat,
@@ -1171,10 +1232,10 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                if (unlikely(err))
                        break;
                if (mode == SC_FLUSH_DAT) {
-                       sci->sc_stage.scnt = NILFS_ST_DONE;
+                       nilfs_sc_cstage_set(sci, NILFS_ST_DONE);
                        return 0;
                }
-               sci->sc_stage.scnt++;  /* Fall through */
+               nilfs_sc_cstage_inc(sci);  /* Fall through */
        case NILFS_ST_SR:
                if (mode == SC_LSEG_SR) {
                        /* Appending a super root */
@@ -1184,7 +1245,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                }
                /* End of a logical segment */
                sci->sc_curseg->sb_sum.flags |= NILFS_SS_LOGEND;
-               sci->sc_stage.scnt = NILFS_ST_DONE;
+               nilfs_sc_cstage_set(sci, NILFS_ST_DONE);
                return 0;
        case NILFS_ST_DSYNC:
  dsync_mode:
@@ -1197,7 +1258,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                if (unlikely(err))
                        break;
                sci->sc_curseg->sb_sum.flags |= NILFS_SS_LOGEND;
-               sci->sc_stage.scnt = NILFS_ST_DONE;
+               nilfs_sc_cstage_set(sci, NILFS_ST_DONE);
                return 0;
        case NILFS_ST_DONE:
                return 0;
@@ -1442,7 +1503,8 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
                        goto failed;
 
                /* The current segment is filled up */
-               if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE)
+               if (mode != SC_LSEG_SR ||
+                   nilfs_sc_cstage_get(sci) < NILFS_ST_CPFILE)
                        break;
 
                nilfs_clear_logs(&sci->sc_segbufs);
@@ -1946,7 +2008,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
        struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
        int err;
 
-       sci->sc_stage.scnt = NILFS_ST_INIT;
+       nilfs_sc_cstage_set(sci, NILFS_ST_INIT);
        sci->sc_cno = nilfs->ns_cno;
 
        err = nilfs_segctor_collect_dirty_files(sci, nilfs);
@@ -1974,7 +2036,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                        goto failed;
 
                /* Avoid empty segment */
-               if (sci->sc_stage.scnt == NILFS_ST_DONE &&
+               if (nilfs_sc_cstage_get(sci) == NILFS_ST_DONE &&
                    nilfs_segbuf_empty(sci->sc_curseg)) {
                        nilfs_segctor_abort_construction(sci, nilfs, 1);
                        goto out;
@@ -1988,7 +2050,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                        nilfs_segctor_fill_in_file_bmap(sci);
 
                if (mode == SC_LSEG_SR &&
-                   sci->sc_stage.scnt >= NILFS_ST_CPFILE) {
+                   nilfs_sc_cstage_get(sci) >= NILFS_ST_CPFILE) {
                        err = nilfs_segctor_fill_in_checkpoint(sci);
                        if (unlikely(err))
                                goto failed_to_write;
@@ -2007,7 +2069,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                if (unlikely(err))
                        goto failed_to_write;
 
-               if (sci->sc_stage.scnt == NILFS_ST_DONE ||
+               if (nilfs_sc_cstage_get(sci) == NILFS_ST_DONE ||
                    nilfs->ns_blocksize_bits != PAGE_CACHE_SHIFT) {
                        /*
                         * At this point, we avoid double buffering
@@ -2020,7 +2082,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                        if (err)
                                goto failed_to_write;
                }
-       } while (sci->sc_stage.scnt != NILFS_ST_DONE);
+       } while (nilfs_sc_cstage_get(sci) != NILFS_ST_DONE);
 
  out:
        nilfs_segctor_drop_written_files(sci, nilfs);
@@ -2430,7 +2492,6 @@ static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode)
 static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *sci)
 {
        int mode = 0;
-       int err;
 
        spin_lock(&sci->sc_state_lock);
        mode = (sci->sc_flush_request & FLUSH_DAT_BIT) ?
@@ -2438,7 +2499,7 @@ static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *sci)
        spin_unlock(&sci->sc_state_lock);
 
        if (mode) {
-               err = nilfs_segctor_do_construct(sci, mode);
+               nilfs_segctor_do_construct(sci, mode);
 
                spin_lock(&sci->sc_state_lock);
                sci->sc_flush_request &= (mode == SC_FLUSH_FILE) ?