Whamcloud - gitweb
LU-992 kernel: deprecate RHEL5 server support for master
[fs/lustre-release.git] / lustre / kernel_patches / patches / jbd-stats-2.6-rhel5.patch
diff --git a/lustre/kernel_patches/patches/jbd-stats-2.6-rhel5.patch b/lustre/kernel_patches/patches/jbd-stats-2.6-rhel5.patch
deleted file mode 100644 (file)
index 67832a6..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-Index: linux-2.6.18-128.1.6/include/linux/jbd.h
-===================================================================
---- linux-2.6.18-128.1.6.orig/include/linux/jbd.h      2009-06-02 23:22:50.000000000 -0600
-+++ linux-2.6.18-128.1.6/include/linux/jbd.h   2009-06-02 23:24:00.000000000 -0600
-@@ -428,6 +428,16 @@
- };
-+/*
-+ * Some stats for checkpoint phase
-+ */
-+struct transaction_chp_stats_s {
-+      unsigned long           cs_chp_time;
-+      unsigned long           cs_forced_to_close;
-+      unsigned long           cs_written;
-+      unsigned long           cs_dropped;
-+};
-+
- /* The transaction_t type is the guts of the journaling mechanism.  It
-  * tracks a compound transaction through its various states:
-  *
-@@ -565,6 +575,21 @@
-       spinlock_t              t_handle_lock;
-       /*
-+       * Longest time some handle had to wait for running transaction
-+       */
-+      unsigned long           t_max_wait;
-+
-+      /*
-+       * When transaction started
-+       */
-+      unsigned long           t_start;
-+
-+      /*
-+       * Checkpointing stats [j_checkpoint_sem]
-+       */
-+      struct transaction_chp_stats_s t_chp_stats;
-+
-+      /*
-        * Number of outstanding updates running on this transaction
-        * [t_handle_lock]
-        */
-@@ -604,6 +629,57 @@
-       struct list_head        t_jcb;
- };
-+struct transaction_run_stats_s {
-+      unsigned long           rs_wait;
-+      unsigned long           rs_running;
-+      unsigned long           rs_locked;
-+      unsigned long           rs_flushing;
-+      unsigned long           rs_logging;
-+
-+      unsigned long           rs_handle_count;
-+      unsigned long           rs_blocks;
-+      unsigned long           rs_blocks_logged;
-+};
-+
-+struct transaction_stats_s
-+{
-+      int                     ts_type;
-+      unsigned long           ts_tid;
-+      union {
-+              struct transaction_run_stats_s run;
-+              struct transaction_chp_stats_s chp;
-+      } u;
-+};
-+
-+#define JBD_STATS_RUN         1
-+#define JBD_STATS_CHECKPOINT  2
-+
-+#define ts_wait                       u.run.rs_wait
-+#define ts_running            u.run.rs_running
-+#define ts_locked             u.run.rs_locked
-+#define ts_flushing           u.run.rs_flushing
-+#define ts_logging            u.run.rs_logging
-+#define ts_handle_count               u.run.rs_handle_count
-+#define ts_blocks             u.run.rs_blocks
-+#define ts_blocks_logged      u.run.rs_blocks_logged
-+
-+#define ts_chp_time           u.chp.cs_chp_time
-+#define ts_forced_to_close    u.chp.cs_forced_to_close
-+#define ts_written            u.chp.cs_written
-+#define ts_dropped            u.chp.cs_dropped
-+
-+#define CURRENT_MSECS         (jiffies_to_msecs(jiffies))
-+
-+static inline unsigned int
-+jbd_time_diff(unsigned int start, unsigned int end)
-+{
-+      if (unlikely(start > end))
-+              end = end + (~0UL - start);
-+      else
-+              end -= start;
-+      return end;
-+}
-+
- /**
-  * struct journal_s - The journal_s type is the concrete type associated with
-  *     journal_t.
-@@ -857,6 +933,16 @@
-       pid_t                   j_last_sync_writer;
-       /*
-+       *
-+       */
-+      struct transaction_stats_s *j_history;
-+      int                     j_history_max;
-+      int                     j_history_cur;
-+      spinlock_t              j_history_lock;
-+      struct proc_dir_entry   *j_proc_entry;
-+      struct transaction_stats_s j_stats;
-+
-+      /*
-        * An opaque pointer to fs-private information.  ext3 puts its
-        * superblock pointer here
-        */
-Index: linux-2.6.18-128.1.6/fs/jbd/transaction.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/jbd/transaction.c     2009-06-02 23:22:50.000000000 -0600
-+++ linux-2.6.18-128.1.6/fs/jbd/transaction.c  2009-06-02 23:24:00.000000000 -0600
-@@ -60,6 +60,8 @@
-       J_ASSERT(journal->j_running_transaction == NULL);
-       journal->j_running_transaction = transaction;
-+      transaction->t_max_wait = 0;
-+      transaction->t_start = CURRENT_MSECS;
-       return transaction;
- }
-@@ -86,6 +88,7 @@
-       int nblocks = handle->h_buffer_credits;
-       transaction_t *new_transaction = NULL;
-       int ret = 0;
-+      unsigned long ts = CURRENT_MSECS;
-       if (nblocks > journal->j_max_transaction_buffers) {
-               printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n",
-@@ -219,6 +222,12 @@
-       /* OK, account for the buffers that this operation expects to
-        * use and add the handle to the running transaction. */
-+      if (time_after(transaction->t_start, ts)) {
-+              ts = jbd_time_diff(ts, transaction->t_start);
-+              if (ts > transaction->t_max_wait)
-+                      transaction->t_max_wait= ts;
-+      }
-+
-       handle->h_transaction = transaction;
-       transaction->t_outstanding_credits += nblocks;
-       transaction->t_updates++;
-Index: linux-2.6.18-128.1.6/fs/jbd/journal.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/jbd/journal.c 2009-06-02 23:23:03.000000000 -0600
-+++ linux-2.6.18-128.1.6/fs/jbd/journal.c      2009-06-02 23:24:00.000000000 -0600
-@@ -36,6 +36,7 @@
- #include <linux/kthread.h>
- #include <linux/poison.h>
- #include <linux/proc_fs.h>
-+#include <linux/seq_file.h>
- #include <asm/uaccess.h>
- #include <asm/page.h>
-@@ -638,6 +639,300 @@
-       return journal_add_journal_head(bh);
- }
-+struct jbd_stats_proc_session {
-+      journal_t *journal;
-+      struct transaction_stats_s *stats;
-+      int start;
-+      int max;
-+};
-+
-+static void *jbd_history_skip_empty(struct jbd_stats_proc_session *s,
-+                                      struct transaction_stats_s *ts,
-+                                      int first)
-+{
-+      if (ts == s->stats + s->max)
-+              ts = s->stats;
-+      if (!first && ts == s->stats + s->start)
-+              return NULL;
-+      while (ts->ts_type == 0) {
-+              ts++;
-+              if (ts == s->stats + s->max)
-+                      ts = s->stats;
-+              if (ts == s->stats + s->start)
-+                      return NULL;
-+      }
-+      return ts;
-+
-+}
-+
-+static void *jbd_seq_history_start(struct seq_file *seq, loff_t *pos)
-+{
-+      struct jbd_stats_proc_session *s = seq->private;
-+      struct transaction_stats_s *ts;
-+      int l = *pos;
-+
-+      if (l == 0)
-+              return SEQ_START_TOKEN;
-+      ts = jbd_history_skip_empty(s, s->stats + s->start, 1);
-+      if (!ts)
-+              return NULL;
-+      while (--l && (ts = jbd_history_skip_empty(s, ++ts, 0)) != NULL);
-+      return ts;
-+}
-+
-+static void *jbd_seq_history_next(struct seq_file *seq, void *v, loff_t *pos)
-+{
-+      struct jbd_stats_proc_session *s = seq->private;
-+      struct transaction_stats_s *ts = v;
-+
-+      ++*pos;
-+      if (v == SEQ_START_TOKEN)
-+              return jbd_history_skip_empty(s, s->stats + s->start, 1);
-+      else
-+              return jbd_history_skip_empty(s, ++ts, 0);
-+}
-+
-+static int jbd_seq_history_show(struct seq_file *seq, void *v)
-+{
-+      struct transaction_stats_s *ts = v;
-+      if (v == SEQ_START_TOKEN) {
-+              seq_printf(seq, "%-4s %-5s %-5s %-5s %-5s %-5s %-5s %-6s %-5s "
-+                              "%-5s %-5s %-5s %-5s %-5s\n", "R/C", "tid",
-+                              "wait", "run", "lock", "flush", "log", "hndls",
-+                              "block", "inlog", "ctime", "write", "drop",
-+                              "close");
-+              return 0;
-+      }
-+      if (ts->ts_type == JBD_STATS_RUN)
-+              seq_printf(seq, "%-4s %-5lu %-5lu %-5lu %-5lu %-5lu %-5lu "
-+                              "%-6lu %-5lu %-5lu\n", "R", ts->ts_tid,
-+                              ts->ts_wait, ts->ts_running, ts->ts_locked,
-+                              ts->ts_flushing, ts->ts_logging,
-+                              ts->ts_handle_count, ts->ts_blocks,
-+                              ts->ts_blocks_logged);
-+      else if (ts->ts_type == JBD_STATS_CHECKPOINT)
-+              seq_printf(seq, "%-4s %-5lu %48s %-5lu %-5lu %-5lu %-5lu\n",
-+                              "C", ts->ts_tid, " ", ts->ts_chp_time,
-+                              ts->ts_written, ts->ts_dropped,
-+                              ts->ts_forced_to_close);
-+      else
-+              J_ASSERT(0);
-+      return 0;
-+}
-+
-+static void jbd_seq_history_stop(struct seq_file *seq, void *v)
-+{
-+}
-+
-+static struct seq_operations jbd_seq_history_ops = {
-+      .start  = jbd_seq_history_start,
-+      .next   = jbd_seq_history_next,
-+      .stop   = jbd_seq_history_stop,
-+      .show   = jbd_seq_history_show,
-+};
-+
-+static int jbd_seq_history_open(struct inode *inode, struct file *file)
-+{
-+      journal_t *journal = PDE(inode)->data;
-+      struct jbd_stats_proc_session *s;
-+      int rc, size;
-+
-+      s = kmalloc(sizeof(*s), GFP_KERNEL);
-+      if (s == NULL)
-+              return -EIO;
-+      size = sizeof(struct transaction_stats_s) * journal->j_history_max;
-+      s->stats = kmalloc(size, GFP_KERNEL);
-+      if (s->stats == NULL) {
-+              kfree(s);
-+              return -EIO;
-+      }
-+      spin_lock(&journal->j_history_lock);
-+      memcpy(s->stats, journal->j_history, size);
-+      s->max = journal->j_history_max;
-+      s->start = journal->j_history_cur % s->max;
-+      spin_unlock(&journal->j_history_lock);
-+
-+      rc = seq_open(file, &jbd_seq_history_ops);
-+      if (rc == 0) {
-+              struct seq_file *m = (struct seq_file *)file->private_data;
-+              m->private = s;
-+      } else {
-+              kfree(s->stats);
-+              kfree(s);
-+      }
-+      return rc;
-+
-+}
-+
-+static int jbd_seq_history_release(struct inode *inode, struct file *file)
-+{
-+      struct seq_file *seq = (struct seq_file *)file->private_data;
-+      struct jbd_stats_proc_session *s = seq->private;
-+      kfree(s->stats);
-+      kfree(s);
-+      return seq_release(inode, file);
-+}
-+
-+static struct file_operations jbd_seq_history_fops = {
-+      .owner          = THIS_MODULE,
-+      .open           = jbd_seq_history_open,
-+      .read           = seq_read,
-+      .llseek         = seq_lseek,
-+      .release        = jbd_seq_history_release,
-+};
-+
-+static void *jbd_seq_info_start(struct seq_file *seq, loff_t *pos)
-+{
-+      return *pos ? NULL : SEQ_START_TOKEN;
-+}
-+
-+static void *jbd_seq_info_next(struct seq_file *seq, void *v, loff_t *pos)
-+{
-+      return NULL;
-+}
-+
-+static int jbd_seq_info_show(struct seq_file *seq, void *v)
-+{
-+      struct jbd_stats_proc_session *s = seq->private;
-+      if (v != SEQ_START_TOKEN)
-+              return 0;
-+      seq_printf(seq, "%lu transaction, each upto %u blocks\n",
-+                      s->stats->ts_tid,
-+                      s->journal->j_max_transaction_buffers);
-+      if (s->stats->ts_tid == 0)
-+              return 0;
-+      seq_printf(seq, "average: \n  %lums waiting for transaction\n",
-+                      s->stats->ts_wait / s->stats->ts_tid);
-+      seq_printf(seq, "  %lums running transaction\n",
-+                      s->stats->ts_running / s->stats->ts_tid);
-+      seq_printf(seq, "  %lums transaction was being locked\n",
-+                      s->stats->ts_locked / s->stats->ts_tid);
-+      seq_printf(seq, "  %lums flushing data (in ordered mode)\n",
-+                      s->stats->ts_flushing / s->stats->ts_tid);
-+      seq_printf(seq, "  %lums logging transaction\n",
-+                      s->stats->ts_logging / s->stats->ts_tid);
-+      seq_printf(seq, "  %lu handles per transaction\n",
-+                      s->stats->ts_handle_count / s->stats->ts_tid);
-+      seq_printf(seq, "  %lu blocks per transaction\n",
-+                      s->stats->ts_blocks / s->stats->ts_tid);
-+      seq_printf(seq, "  %lu logged blocks per transaction\n",
-+                      s->stats->ts_blocks_logged / s->stats->ts_tid);
-+      return 0;
-+}
-+
-+static void jbd_seq_info_stop(struct seq_file *seq, void *v)
-+{
-+}
-+
-+static struct seq_operations jbd_seq_info_ops = {
-+      .start  = jbd_seq_info_start,
-+      .next   = jbd_seq_info_next,
-+      .stop   = jbd_seq_info_stop,
-+      .show   = jbd_seq_info_show,
-+};
-+
-+static int jbd_seq_info_open(struct inode *inode, struct file *file)
-+{
-+      journal_t *journal = PDE(inode)->data;
-+      struct jbd_stats_proc_session *s;
-+      int rc, size;
-+
-+      s = kmalloc(sizeof(*s), GFP_KERNEL);
-+      if (s == NULL)
-+              return -EIO;
-+      size = sizeof(struct transaction_stats_s);
-+      s->stats = kmalloc(size, GFP_KERNEL);
-+      if (s->stats == NULL) {
-+              kfree(s);
-+              return -EIO;
-+      }
-+      spin_lock(&journal->j_history_lock);
-+      memcpy(s->stats, &journal->j_stats, size);
-+      s->journal = journal;
-+      spin_unlock(&journal->j_history_lock);
-+
-+      rc = seq_open(file, &jbd_seq_info_ops);
-+      if (rc == 0) {
-+              struct seq_file *m = (struct seq_file *)file->private_data;
-+              m->private = s;
-+      } else {
-+              kfree(s->stats);
-+              kfree(s);
-+      }
-+      return rc;
-+
-+}
-+
-+static int jbd_seq_info_release(struct inode *inode, struct file *file)
-+{
-+      struct seq_file *seq = (struct seq_file *)file->private_data;
-+      struct jbd_stats_proc_session *s = seq->private;
-+      kfree(s->stats);
-+      kfree(s);
-+      return seq_release(inode, file);
-+}
-+
-+static struct file_operations jbd_seq_info_fops = {
-+      .owner          = THIS_MODULE,
-+      .open           = jbd_seq_info_open,
-+      .read           = seq_read,
-+      .llseek         = seq_lseek,
-+      .release        = jbd_seq_info_release,
-+};
-+
-+static struct proc_dir_entry *proc_jbd_stats = NULL;
-+
-+static void jbd_stats_proc_init(journal_t *journal)
-+{
-+      char name[64];
-+
-+      snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
-+      journal->j_proc_entry = proc_mkdir(name, proc_jbd_stats);
-+      if (journal->j_proc_entry) {
-+              struct proc_dir_entry *p;
-+              p = create_proc_entry("history", S_IRUGO,
-+                              journal->j_proc_entry);
-+              if (p) {
-+                      p->proc_fops = &jbd_seq_history_fops;
-+                      p->data = journal;
-+                      p = create_proc_entry("info", S_IRUGO,
-+                                              journal->j_proc_entry);
-+                      if (p) {
-+                              p->proc_fops = &jbd_seq_info_fops;
-+                              p->data = journal;
-+                      }
-+              }
-+      }
-+}
-+
-+static void jbd_stats_proc_exit(journal_t *journal)
-+{
-+      char name[64];
-+
-+      snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
-+      remove_proc_entry("info", journal->j_proc_entry);
-+      remove_proc_entry("history", journal->j_proc_entry);
-+      remove_proc_entry(name, proc_jbd_stats);
-+}
-+
-+static void journal_init_stats(journal_t *journal)
-+{
-+      int size;
-+
-+      if (proc_jbd_stats == NULL)
-+              return;
-+
-+      journal->j_history_max = 100;
-+      size = sizeof(struct transaction_stats_s) * journal->j_history_max;
-+      journal->j_history = kmalloc(size, GFP_KERNEL);
-+      if (journal->j_history == NULL) {
-+              journal->j_history_max = 0;
-+              return;
-+      }
-+      memset(journal->j_history, 0, size);
-+      spin_lock_init(&journal->j_history_lock);
-+}
-+
- /*
-  * Management for journal control blocks: functions to create and
-  * destroy journal_t structures, and to initialise and read existing
-@@ -680,6 +975,9 @@
-               kfree(journal);
-               goto fail;
-       }
-+
-+      journal_init_stats(journal);
-+
-       return journal;
- fail:
-       return NULL;
-@@ -723,6 +1021,7 @@
-       journal->j_blk_offset = start;
-       journal->j_maxlen = len;
-       journal->j_blocksize = blocksize;
-+      jbd_stats_proc_init(journal);
-       bh = __getblk(journal->j_dev, start, journal->j_blocksize);
-       J_ASSERT(bh != NULL);
-@@ -772,6 +1071,7 @@
-       journal->j_maxlen = inode->i_size >> inode->i_sb->s_blocksize_bits;
-       journal->j_blocksize = inode->i_sb->s_blocksize;
-+      jbd_stats_proc_init(journal);
-       /* journal descriptor can store up to n blocks -bzzz */
-       n = journal->j_blocksize / sizeof(journal_block_tag_t);
-@@ -1168,6 +1468,8 @@
-               brelse(journal->j_sb_buffer);
-       }
-+      if (journal->j_proc_entry)
-+              jbd_stats_proc_exit(journal);
-       if (journal->j_inode)
-               iput(journal->j_inode);
-       if (journal->j_revoke)
-@@ -2015,6 +2317,28 @@
- #endif
-+#if defined(CONFIG_PROC_FS)
-+
-+#define JBD_STATS_PROC_NAME "fs/jbd"
-+
-+static void __init create_jbd_stats_proc_entry(void)
-+{
-+      proc_jbd_stats = proc_mkdir(JBD_STATS_PROC_NAME, NULL);
-+}
-+
-+static void __exit remove_jbd_stats_proc_entry(void)
-+{
-+      if (proc_jbd_stats)
-+              remove_proc_entry(JBD_STATS_PROC_NAME, NULL);
-+}
-+
-+#else
-+
-+#define create_jbd_stats_proc_entry() do {} while (0)
-+#define remove_jbd_stats_proc_entry() do {} while (0)
-+
-+#endif
-+
- kmem_cache_t *jbd_handle_cache;
- static int __init journal_init_handle_cache(void)
-@@ -2078,6 +2402,7 @@
-       if (ret != 0)
-               journal_destroy_caches();
-       create_jbd_proc_entry();
-+      create_jbd_stats_proc_entry();
-       return ret;
- }
-@@ -2089,6 +2414,7 @@
-               printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n);
- #endif
-       remove_jbd_proc_entry();
-+      remove_jbd_stats_proc_entry();
-       journal_destroy_caches();
- }
-Index: linux-2.6.18-128.1.6/fs/jbd/checkpoint.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/jbd/checkpoint.c      2009-06-02 23:22:50.000000000 -0600
-+++ linux-2.6.18-128.1.6/fs/jbd/checkpoint.c   2009-06-02 23:24:00.000000000 -0600
-@@ -242,7 +242,7 @@
-  * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
-  */
- static int __process_buffer(journal_t *journal, struct journal_head *jh,
--                      struct buffer_head **bhs, int *batch_count)
-+                      struct buffer_head **bhs, int *batch_count, transaction_t *transaction)
- {
-       struct buffer_head *bh = jh2bh(jh);
-       int ret = 0;
-@@ -260,6 +260,7 @@
-               transaction_t *t = jh->b_transaction;
-               tid_t tid = t->t_tid;
-+              transaction->t_chp_stats.cs_forced_to_close++;
-               spin_unlock(&journal->j_list_lock);
-               jbd_unlock_bh_state(bh);
-               log_start_commit(journal, tid);
-@@ -291,6 +292,7 @@
-               bhs[*batch_count] = bh;
-               __buffer_relink_io(jh);
-               jbd_unlock_bh_state(bh);
-+              transaction->t_chp_stats.cs_written++;
-               (*batch_count)++;
-               if (*batch_count == NR_BATCH) {
-                       spin_unlock(&journal->j_list_lock);
-@@ -336,6 +338,8 @@
-       if (!journal->j_checkpoint_transactions)
-               goto out;
-       transaction = journal->j_checkpoint_transactions;
-+      if (transaction->t_chp_stats.cs_chp_time == 0)
-+              transaction->t_chp_stats.cs_chp_time = CURRENT_MSECS;
-       this_tid = transaction->t_tid;
- restart:
-       /*
-@@ -360,7 +364,8 @@
-                               retry = 1;
-                               break;
-                       }
--                      retry = __process_buffer(journal, jh, bhs,&batch_count);
-+                      retry = __process_buffer(journal, jh, bhs,&batch_count,
-+                                               transaction);
-                       if (retry < 0 && !result)
-                               result = retry;
-                       if (!retry && lock_need_resched(&journal->j_list_lock)){
-@@ -692,6 +697,8 @@
- void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
- {
-+      struct transaction_stats_s stats;
-+
-       assert_spin_locked(&journal->j_list_lock);
-       if (transaction->t_cpnext) {
-               transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
-@@ -718,5 +725,25 @@
-       J_ASSERT(journal->j_running_transaction != transaction);
-       jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
-+
-+      /*
-+       * File the transaction for history
-+       */
-+      if (transaction->t_chp_stats.cs_written != 0 ||
-+                      transaction->t_chp_stats.cs_chp_time != 0) {
-+              stats.ts_type = JBD_STATS_CHECKPOINT;
-+              stats.ts_tid = transaction->t_tid;
-+              stats.u.chp = transaction->t_chp_stats;
-+              if (stats.ts_chp_time)
-+                      stats.ts_chp_time =
-+                              jbd_time_diff(stats.ts_chp_time, CURRENT_MSECS);
-+              spin_lock(&journal->j_history_lock);
-+              memcpy(journal->j_history + journal->j_history_cur, &stats,
-+                              sizeof(stats));
-+              if (++journal->j_history_cur == journal->j_history_max)
-+                      journal->j_history_cur = 0;
-+              spin_unlock(&journal->j_history_lock);
-+      }
-+
-       kfree(transaction);
- }
-Index: linux-2.6.18-128.1.6/fs/jbd/commit.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/jbd/commit.c  2009-06-02 23:22:50.000000000 -0600
-+++ linux-2.6.18-128.1.6/fs/jbd/commit.c       2009-06-02 23:24:00.000000000 -0600
-@@ -13,6 +13,7 @@
-  * part of the ext2fs journaling system.
-  */
-+#include <linux/jiffies.h>
- #include <linux/time.h>
- #include <linux/fs.h>
- #include <linux/jbd.h>
-@@ -22,6 +23,7 @@
- #include <linux/pagemap.h>
- #include <linux/smp_lock.h>
-+
- /*
-  * Default IO end handler for temporary BJ_IO buffer_heads.
-  */
-@@ -288,6 +290,7 @@
-  */
- void journal_commit_transaction(journal_t *journal)
- {
-+      struct transaction_stats_s stats;
-       transaction_t *commit_transaction;
-       struct journal_head *jh, *new_jh, *descriptor;
-       struct buffer_head **wbuf = journal->j_wbuf;
-@@ -334,6 +337,11 @@
-       spin_lock(&journal->j_state_lock);
-       commit_transaction->t_state = T_LOCKED;
-+      stats.ts_wait = commit_transaction->t_max_wait;
-+      stats.ts_locked = CURRENT_MSECS;
-+      stats.ts_running = jbd_time_diff(commit_transaction->t_start,
-+                                              stats.ts_locked);
-+
-       spin_lock(&commit_transaction->t_handle_lock);
-       while (commit_transaction->t_updates) {
-               DEFINE_WAIT(wait);
-@@ -404,6 +412,9 @@
-        */
-       journal_switch_revoke_table(journal);
-+      stats.ts_flushing = CURRENT_MSECS;
-+      stats.ts_locked = jbd_time_diff(stats.ts_locked, stats.ts_flushing);
-+
-       commit_transaction->t_state = T_FLUSH;
-       journal->j_committing_transaction = commit_transaction;
-       journal->j_running_transaction = NULL;
-@@ -484,6 +495,11 @@
-       J_ASSERT(commit_transaction->t_nr_buffers <=
-                commit_transaction->t_outstanding_credits);
-+      stats.ts_logging = CURRENT_MSECS;
-+      stats.ts_flushing = jbd_time_diff(stats.ts_flushing, stats.ts_logging);
-+      stats.ts_blocks = commit_transaction->t_outstanding_credits;
-+      stats.ts_blocks_logged = 0;
-+
-       descriptor = NULL;
-       bufs = 0;
-       while (commit_transaction->t_buffers) {
-@@ -633,6 +649,7 @@
-                               submit_bh(WRITE, bh);
-                       }
-                       cond_resched();
-+                      stats.ts_blocks_logged += bufs;
-                       /* Force a new descriptor to be generated next
-                            time round the loop. */
-@@ -832,6 +849,7 @@
-               cp_transaction = jh->b_cp_transaction;
-               if (cp_transaction) {
-                       JBUFFER_TRACE(jh, "remove from old cp transaction");
-+                      cp_transaction->t_chp_stats.cs_dropped++;
-                       __journal_remove_checkpoint(jh);
-               }
-@@ -908,6 +926,36 @@
-       J_ASSERT(commit_transaction->t_state == T_COMMIT);
-+      commit_transaction->t_start = CURRENT_MSECS;
-+      stats.ts_logging = jbd_time_diff(stats.ts_logging,
-+                                       commit_transaction->t_start);
-+
-+      /*
-+       * File the transaction for history
-+       */
-+      stats.ts_type = JBD_STATS_RUN;
-+      stats.ts_tid = commit_transaction->t_tid;
-+      stats.ts_handle_count = commit_transaction->t_handle_count;
-+      spin_lock(&journal->j_history_lock);
-+      memcpy(journal->j_history + journal->j_history_cur, &stats,
-+                      sizeof(stats));
-+      if (++journal->j_history_cur == journal->j_history_max)
-+              journal->j_history_cur = 0;
-+
-+      /*
-+       * Calculate overall stats
-+       */
-+      journal->j_stats.ts_tid++;
-+      journal->j_stats.ts_wait += stats.ts_wait;
-+      journal->j_stats.ts_running += stats.ts_running;
-+      journal->j_stats.ts_locked += stats.ts_locked;
-+      journal->j_stats.ts_flushing += stats.ts_flushing;
-+      journal->j_stats.ts_logging += stats.ts_logging;
-+      journal->j_stats.ts_handle_count += stats.ts_handle_count;
-+      journal->j_stats.ts_blocks += stats.ts_blocks;
-+      journal->j_stats.ts_blocks_logged += stats.ts_blocks_logged;
-+      spin_unlock(&journal->j_history_lock);
-+
-       commit_transaction->t_state = T_FINISHED;
-       J_ASSERT(commit_transaction == journal->j_committing_transaction);
-       journal->j_commit_sequence = commit_transaction->t_tid;