1 Index: linux-2.6.9/include/linux/jbd.h
2 ===================================================================
3 --- linux-2.6.9.orig/include/linux/jbd.h 2006-03-10 18:20:03.000000000 +0300
4 +++ linux-2.6.9/include/linux/jbd.h 2006-07-28 02:32:18.000000000 +0400
5 @@ -422,6 +422,16 @@ struct handle_s
10 + * Some stats for checkpoint phase
12 +struct transaction_chp_stats_s {
13 + unsigned long cs_chp_time;
14 + unsigned long cs_forced_to_close;
15 + unsigned long cs_written;
16 + unsigned long cs_dropped;
19 /* The transaction_t type is the guts of the journaling mechanism. It
20 * tracks a compound transaction through its various states:
22 @@ -553,6 +563,21 @@ struct transaction_s
23 spinlock_t t_handle_lock;
26 + * Longest time some handle had to wait for running transaction
28 + unsigned long t_max_wait;
31 + * When transaction started
33 + unsigned long t_start;
36 + * Checkpointing stats [j_checkpoint_sem]
38 + struct transaction_chp_stats_s t_chp_stats;
41 * Number of outstanding updates running on this transaction
44 @@ -592,6 +617,57 @@ struct transaction_s
45 struct list_head t_jcb;
48 +struct transaction_run_stats_s {
49 + unsigned long rs_wait;
50 + unsigned long rs_running;
51 + unsigned long rs_locked;
52 + unsigned long rs_flushing;
53 + unsigned long rs_logging;
55 + unsigned long rs_handle_count;
56 + unsigned long rs_blocks;
57 + unsigned long rs_blocks_logged;
60 +struct transaction_stats_s
63 + unsigned long ts_tid;
65 + struct transaction_run_stats_s run;
66 + struct transaction_chp_stats_s chp;
70 +#define JBD_STATS_RUN 1
71 +#define JBD_STATS_CHECKPOINT 2
73 +#define ts_wait u.run.rs_wait
74 +#define ts_running u.run.rs_running
75 +#define ts_locked u.run.rs_locked
76 +#define ts_flushing u.run.rs_flushing
77 +#define ts_logging u.run.rs_logging
78 +#define ts_handle_count u.run.rs_handle_count
79 +#define ts_blocks u.run.rs_blocks
80 +#define ts_blocks_logged u.run.rs_blocks_logged
82 +#define ts_chp_time u.chp.cs_chp_time
83 +#define ts_forced_to_close u.chp.cs_forced_to_close
84 +#define ts_written u.chp.cs_written
85 +#define ts_dropped u.chp.cs_dropped
87 +#define CURRENT_MSECS (jiffies_to_msecs(jiffies))
89 +static inline unsigned int
90 +jbd_time_diff(unsigned int start, unsigned int end)
92 + if (unlikely(start > end))
93 + end = end + (~0UL - start);
100 * struct journal_s - The journal_s type is the concrete type associated with
102 @@ -828,6 +904,16 @@ struct journal_s
103 struct jbd_revoke_table_s *j_revoke_table[2];
108 + struct transaction_stats_s *j_history;
111 + spinlock_t j_history_lock;
112 + struct proc_dir_entry *j_proc_entry;
113 + struct transaction_stats_s j_stats;
116 * An opaque pointer to fs-private information. ext3 puts its
117 * superblock pointer here
119 Index: linux-2.6.9/fs/jbd/commit.c
120 ===================================================================
121 --- linux-2.6.9.orig/fs/jbd/commit.c 2006-03-10 18:20:39.000000000 +0300
122 +++ linux-2.6.9/fs/jbd/commit.c 2006-07-28 02:32:18.000000000 +0400
124 #include <linux/mm.h>
125 #include <linux/pagemap.h>
126 #include <linux/smp_lock.h>
127 +#include <linux/jiffies.h>
130 * Default IO end handler for temporary BJ_IO buffer_heads.
131 @@ -101,6 +102,7 @@ static int inverted_lock(journal_t *jour
133 void journal_commit_transaction(journal_t *journal)
135 + struct transaction_stats_s stats;
136 transaction_t *commit_transaction;
137 struct journal_head *jh, *new_jh, *descriptor;
138 struct buffer_head *wbuf[64];
139 @@ -147,6 +149,11 @@ void journal_commit_transaction(journal_
140 spin_lock(&journal->j_state_lock);
141 commit_transaction->t_state = T_LOCKED;
143 + stats.ts_wait = commit_transaction->t_max_wait;
144 + stats.ts_locked = CURRENT_MSECS;
145 + stats.ts_running = jbd_time_diff(commit_transaction->t_start,
148 spin_lock(&commit_transaction->t_handle_lock);
149 while (commit_transaction->t_updates) {
151 @@ -219,6 +226,9 @@ void journal_commit_transaction(journal_
153 journal_switch_revoke_table(journal);
155 + stats.ts_flushing = CURRENT_MSECS;
156 + stats.ts_locked = jbd_time_diff(stats.ts_locked, stats.ts_flushing);
158 commit_transaction->t_state = T_FLUSH;
159 journal->j_committing_transaction = commit_transaction;
160 journal->j_running_transaction = NULL;
161 @@ -365,6 +375,11 @@ write_out_data:
163 commit_transaction->t_state = T_COMMIT;
165 + stats.ts_logging = CURRENT_MSECS;
166 + stats.ts_flushing = jbd_time_diff(stats.ts_flushing, stats.ts_logging);
167 + stats.ts_blocks = commit_transaction->t_outstanding_credits;
168 + stats.ts_blocks_logged = 0;
172 while (commit_transaction->t_buffers) {
173 @@ -513,6 +528,7 @@ start_journal_io:
174 submit_bh(WRITE, bh);
177 + stats.ts_blocks_logged += bufs;
179 /* Force a new descriptor to be generated next
180 time round the loop. */
181 @@ -760,6 +776,7 @@ skip_commit: /* The journal should be un
182 cp_transaction = jh->b_cp_transaction;
183 if (cp_transaction) {
184 JBUFFER_TRACE(jh, "remove from old cp transaction");
185 + cp_transaction->t_chp_stats.cs_dropped++;
186 __journal_remove_checkpoint(jh);
189 @@ -806,6 +823,36 @@ skip_commit: /* The journal should be un
191 J_ASSERT(commit_transaction->t_state == T_COMMIT);
193 + commit_transaction->t_start = CURRENT_MSECS;
194 + stats.ts_logging = jbd_time_diff(stats.ts_logging,
195 + commit_transaction->t_start);
198 + * File the transaction for history
200 + stats.ts_type = JBD_STATS_RUN;
201 + stats.ts_tid = commit_transaction->t_tid;
202 + stats.ts_handle_count = commit_transaction->t_handle_count;
203 + spin_lock(&journal->j_history_lock);
204 + memcpy(journal->j_history + journal->j_history_cur, &stats,
206 + if (++journal->j_history_cur == journal->j_history_max)
207 + journal->j_history_cur = 0;
210 + * Calculate overall stats
212 + journal->j_stats.ts_tid++;
213 + journal->j_stats.ts_wait += stats.ts_wait;
214 + journal->j_stats.ts_running += stats.ts_running;
215 + journal->j_stats.ts_locked += stats.ts_locked;
216 + journal->j_stats.ts_flushing += stats.ts_flushing;
217 + journal->j_stats.ts_logging += stats.ts_logging;
218 + journal->j_stats.ts_handle_count += stats.ts_handle_count;
219 + journal->j_stats.ts_blocks += stats.ts_blocks;
220 + journal->j_stats.ts_blocks_logged += stats.ts_blocks_logged;
221 + spin_unlock(&journal->j_history_lock);
224 * This is a bit sleazy. We borrow j_list_lock to protect
225 * journal->j_committing_transaction in __journal_remove_checkpoint.
226 Index: linux-2.6.9/fs/jbd/checkpoint.c
227 ===================================================================
228 --- linux-2.6.9.orig/fs/jbd/checkpoint.c 2006-03-10 18:20:03.000000000 +0300
229 +++ linux-2.6.9/fs/jbd/checkpoint.c 2006-07-28 02:35:21.000000000 +0400
230 @@ -166,6 +166,7 @@ static int __cleanup_transaction(journal
231 transaction_t *t = jh->b_transaction;
232 tid_t tid = t->t_tid;
234 + transaction->t_chp_stats.cs_forced_to_close++;
235 spin_unlock(&journal->j_list_lock);
236 jbd_unlock_bh_state(bh);
237 log_start_commit(journal, tid);
238 @@ -227,7 +228,7 @@ __flush_batch(journal_t *journal, struct
240 static int __flush_buffer(journal_t *journal, struct journal_head *jh,
241 struct buffer_head **bhs, int *batch_count,
243 + int *drop_count, transaction_t *transaction)
245 struct buffer_head *bh = jh2bh(jh);
247 @@ -248,6 +249,7 @@ static int __flush_buffer(journal_t *jou
248 set_buffer_jwrite(bh);
249 bhs[*batch_count] = bh;
250 jbd_unlock_bh_state(bh);
251 + transaction->t_chp_stats.cs_written++;
253 if (*batch_count == NR_BATCH) {
254 __flush_batch(journal, bhs, batch_count);
255 @@ -316,6 +318,8 @@ int log_do_checkpoint(journal_t *journal
258 transaction = journal->j_checkpoint_transactions;
259 + if (transaction->t_chp_stats.cs_chp_time == 0)
260 + transaction->t_chp_stats.cs_chp_time = CURRENT_MSECS;
261 this_tid = transaction->t_tid;
262 jh = transaction->t_checkpoint_list;
263 last_jh = jh->b_cpprev;
264 @@ -332,7 +336,8 @@ int log_do_checkpoint(journal_t *journal
268 - retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count);
269 + retry = __flush_buffer(journal, jh, bhs, &batch_count,
270 + &drop_count, transaction);
271 } while (jh != last_jh && !retry);
274 @@ -598,6 +603,8 @@ void __journal_insert_checkpoint(struct
276 void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
278 + struct transaction_stats_s stats;
280 assert_spin_locked(&journal->j_list_lock);
281 if (transaction->t_cpnext) {
282 transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
283 @@ -623,5 +630,25 @@ void __journal_drop_transaction(journal_
284 J_ASSERT(journal->j_running_transaction != transaction);
286 jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
289 + * File the transaction for history
291 + if (transaction->t_chp_stats.cs_written != 0 ||
292 + transaction->t_chp_stats.cs_chp_time != 0) {
293 + stats.ts_type = JBD_STATS_CHECKPOINT;
294 + stats.ts_tid = transaction->t_tid;
295 + stats.u.chp = transaction->t_chp_stats;
296 + if (stats.ts_chp_time)
297 + stats.ts_chp_time =
298 + jbd_time_diff(stats.ts_chp_time, CURRENT_MSECS);
299 + spin_lock(&journal->j_history_lock);
300 + memcpy(journal->j_history + journal->j_history_cur, &stats,
302 + if (++journal->j_history_cur == journal->j_history_max)
303 + journal->j_history_cur = 0;
304 + spin_unlock(&journal->j_history_lock);
309 Index: linux-2.6.9/fs/jbd/transaction.c
310 ===================================================================
311 --- linux-2.6.9.orig/fs/jbd/transaction.c 2006-03-10 18:20:03.000000000 +0300
312 +++ linux-2.6.9/fs/jbd/transaction.c 2006-07-28 02:32:18.000000000 +0400
313 @@ -60,6 +60,8 @@ get_transaction(journal_t *journal, tran
315 J_ASSERT(journal->j_running_transaction == NULL);
316 journal->j_running_transaction = transaction;
317 + transaction->t_max_wait = 0;
318 + transaction->t_start = CURRENT_MSECS;
322 @@ -86,6 +88,7 @@ static int start_this_handle(journal_t *
323 int nblocks = handle->h_buffer_credits;
324 transaction_t *new_transaction = NULL;
326 + unsigned long ts = CURRENT_MSECS;
328 if (nblocks > journal->j_max_transaction_buffers) {
329 printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n",
330 @@ -219,6 +222,12 @@ repeat_locked:
331 /* OK, account for the buffers that this operation expects to
332 * use and add the handle to the running transaction. */
334 + if (time_after(transaction->t_start, ts)) {
335 + ts = jbd_time_diff(ts, transaction->t_start);
336 + if (ts > transaction->t_max_wait)
337 + transaction->t_max_wait= ts;
340 handle->h_transaction = transaction;
341 transaction->t_outstanding_credits += nblocks;
342 transaction->t_updates++;
343 Index: linux-2.6.9/fs/jbd/journal.c
344 ===================================================================
345 --- linux-2.6.9.orig/fs/jbd/journal.c 2006-06-19 21:31:57.000000000 +0400
346 +++ linux-2.6.9/fs/jbd/journal.c 2006-07-28 02:32:18.000000000 +0400
348 #include <asm/uaccess.h>
349 #include <asm/page.h>
350 #include <linux/proc_fs.h>
351 +#include <linux/seq_file.h>
353 EXPORT_SYMBOL(journal_start);
354 EXPORT_SYMBOL(journal_restart);
355 @@ -649,6 +650,300 @@ struct journal_head *journal_get_descrip
356 return journal_add_journal_head(bh);
359 +struct jbd_stats_proc_session {
360 + journal_t *journal;
361 + struct transaction_stats_s *stats;
366 +static void *jbd_history_skip_empty(struct jbd_stats_proc_session *s,
367 + struct transaction_stats_s *ts,
370 + if (ts == s->stats + s->max)
372 + if (!first && ts == s->stats + s->start)
374 + while (ts->ts_type == 0) {
376 + if (ts == s->stats + s->max)
378 + if (ts == s->stats + s->start)
385 +static void *jbd_seq_history_start(struct seq_file *seq, loff_t *pos)
387 + struct jbd_stats_proc_session *s = seq->private;
388 + struct transaction_stats_s *ts;
392 + return SEQ_START_TOKEN;
393 + ts = jbd_history_skip_empty(s, s->stats + s->start, 1);
396 + while (--l && (ts = jbd_history_skip_empty(s, ++ts, 0)) != NULL);
400 +static void *jbd_seq_history_next(struct seq_file *seq, void *v, loff_t *pos)
402 + struct jbd_stats_proc_session *s = seq->private;
403 + struct transaction_stats_s *ts = v;
406 + if (v == SEQ_START_TOKEN)
407 + return jbd_history_skip_empty(s, s->stats + s->start, 1);
409 + return jbd_history_skip_empty(s, ++ts, 0);
412 +static int jbd_seq_history_show(struct seq_file *seq, void *v)
414 + struct transaction_stats_s *ts = v;
415 + if (v == SEQ_START_TOKEN) {
416 + seq_printf(seq, "%-4s %-5s %-5s %-5s %-5s %-5s %-5s %-6s %-5s "
417 + "%-5s %-5s %-5s %-5s %-5s\n", "R/C", "tid",
418 + "wait", "run", "lock", "flush", "log", "hndls",
419 + "block", "inlog", "ctime", "write", "drop",
423 + if (ts->ts_type == JBD_STATS_RUN)
424 + seq_printf(seq, "%-4s %-5lu %-5lu %-5lu %-5lu %-5lu %-5lu "
425 + "%-6lu %-5lu %-5lu\n", "R", ts->ts_tid,
426 + ts->ts_wait, ts->ts_running, ts->ts_locked,
427 + ts->ts_flushing, ts->ts_logging,
428 + ts->ts_handle_count, ts->ts_blocks,
429 + ts->ts_blocks_logged);
430 + else if (ts->ts_type == JBD_STATS_CHECKPOINT)
431 + seq_printf(seq, "%-4s %-5lu %48s %-5lu %-5lu %-5lu %-5lu\n",
432 + "C", ts->ts_tid, " ", ts->ts_chp_time,
433 + ts->ts_written, ts->ts_dropped,
434 + ts->ts_forced_to_close);
440 +static void jbd_seq_history_stop(struct seq_file *seq, void *v)
444 +static struct seq_operations jbd_seq_history_ops = {
445 + .start = jbd_seq_history_start,
446 + .next = jbd_seq_history_next,
447 + .stop = jbd_seq_history_stop,
448 + .show = jbd_seq_history_show,
451 +static int jbd_seq_history_open(struct inode *inode, struct file *file)
453 + journal_t *journal = PDE(inode)->data;
454 + struct jbd_stats_proc_session *s;
457 + s = kmalloc(sizeof(*s), GFP_KERNEL);
460 + size = sizeof(struct transaction_stats_s) * journal->j_history_max;
461 + s->stats = kmalloc(size, GFP_KERNEL);
466 + spin_lock(&journal->j_history_lock);
467 + memcpy(s->stats, journal->j_history, size);
468 + s->max = journal->j_history_max;
469 + s->start = journal->j_history_cur % s->max;
470 + spin_unlock(&journal->j_history_lock);
472 + rc = seq_open(file, &jbd_seq_history_ops);
474 + struct seq_file *m = (struct seq_file *)file->private_data;
484 +static int jbd_seq_history_release(struct inode *inode, struct file *file)
486 + struct seq_file *seq = (struct seq_file *)file->private_data;
487 + struct jbd_stats_proc_session *s = seq->private;
490 + return seq_release(inode, file);
493 +static struct file_operations jbd_seq_history_fops = {
494 + .owner = THIS_MODULE,
495 + .open = jbd_seq_history_open,
497 + .llseek = seq_lseek,
498 + .release = jbd_seq_history_release,
501 +static void *jbd_seq_info_start(struct seq_file *seq, loff_t *pos)
503 + return *pos ? NULL : SEQ_START_TOKEN;
506 +static void *jbd_seq_info_next(struct seq_file *seq, void *v, loff_t *pos)
511 +static int jbd_seq_info_show(struct seq_file *seq, void *v)
513 + struct jbd_stats_proc_session *s = seq->private;
514 + if (v != SEQ_START_TOKEN)
516 + seq_printf(seq, "%lu transaction, each upto %u blocks\n",
518 + s->journal->j_max_transaction_buffers);
519 + if (s->stats->ts_tid == 0)
521 + seq_printf(seq, "average: \n %lums waiting for transaction\n",
522 + s->stats->ts_wait / s->stats->ts_tid);
523 + seq_printf(seq, " %lums running transaction\n",
524 + s->stats->ts_running / s->stats->ts_tid);
525 + seq_printf(seq, " %lums transaction was being locked\n",
526 + s->stats->ts_locked / s->stats->ts_tid);
527 + seq_printf(seq, " %lums flushing data (in ordered mode)\n",
528 + s->stats->ts_flushing / s->stats->ts_tid);
529 + seq_printf(seq, " %lums logging transaction\n",
530 + s->stats->ts_logging / s->stats->ts_tid);
531 + seq_printf(seq, " %lu handles per transaction\n",
532 + s->stats->ts_handle_count / s->stats->ts_tid);
533 + seq_printf(seq, " %lu blocks per transaction\n",
534 + s->stats->ts_blocks / s->stats->ts_tid);
535 + seq_printf(seq, " %lu logged blocks per transaction\n",
536 + s->stats->ts_blocks_logged / s->stats->ts_tid);
540 +static void jbd_seq_info_stop(struct seq_file *seq, void *v)
544 +static struct seq_operations jbd_seq_info_ops = {
545 + .start = jbd_seq_info_start,
546 + .next = jbd_seq_info_next,
547 + .stop = jbd_seq_info_stop,
548 + .show = jbd_seq_info_show,
551 +static int jbd_seq_info_open(struct inode *inode, struct file *file)
553 + journal_t *journal = PDE(inode)->data;
554 + struct jbd_stats_proc_session *s;
557 + s = kmalloc(sizeof(*s), GFP_KERNEL);
560 + size = sizeof(struct transaction_stats_s);
561 + s->stats = kmalloc(size, GFP_KERNEL);
566 + spin_lock(&journal->j_history_lock);
567 + memcpy(s->stats, &journal->j_stats, size);
568 + s->journal = journal;
569 + spin_unlock(&journal->j_history_lock);
571 + rc = seq_open(file, &jbd_seq_info_ops);
573 + struct seq_file *m = (struct seq_file *)file->private_data;
583 +static int jbd_seq_info_release(struct inode *inode, struct file *file)
585 + struct seq_file *seq = (struct seq_file *)file->private_data;
586 + struct jbd_stats_proc_session *s = seq->private;
589 + return seq_release(inode, file);
592 +static struct file_operations jbd_seq_info_fops = {
593 + .owner = THIS_MODULE,
594 + .open = jbd_seq_info_open,
596 + .llseek = seq_lseek,
597 + .release = jbd_seq_info_release,
600 +static struct proc_dir_entry *proc_jbd_stats = NULL;
602 +static void jbd_stats_proc_init(journal_t *journal)
606 + snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
607 + journal->j_proc_entry = proc_mkdir(name, proc_jbd_stats);
608 + if (journal->j_proc_entry) {
609 + struct proc_dir_entry *p;
610 + p = create_proc_entry("history", S_IRUGO,
611 + journal->j_proc_entry);
613 + p->proc_fops = &jbd_seq_history_fops;
615 + p = create_proc_entry("info", S_IRUGO,
616 + journal->j_proc_entry);
618 + p->proc_fops = &jbd_seq_info_fops;
625 +static void jbd_stats_proc_exit(journal_t *journal)
629 + snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
630 + remove_proc_entry("info", journal->j_proc_entry);
631 + remove_proc_entry("history", journal->j_proc_entry);
632 + remove_proc_entry(name, proc_jbd_stats);
635 +static void journal_init_stats(journal_t *journal)
639 + if (proc_jbd_stats == NULL)
642 + journal->j_history_max = 100;
643 + size = sizeof(struct transaction_stats_s) * journal->j_history_max;
644 + journal->j_history = kmalloc(size, GFP_KERNEL);
645 + if (journal->j_history == NULL) {
646 + journal->j_history_max = 0;
649 + memset(journal->j_history, 0, size);
650 + spin_lock_init(&journal->j_history_lock);
654 * Management for journal control blocks: functions to create and
655 * destroy journal_t structures, and to initialise and read existing
656 @@ -691,6 +986,9 @@ static journal_t * journal_init_common (
661 + journal_init_stats(journal);
666 @@ -733,6 +1031,7 @@ journal_t * journal_init_dev(struct bloc
667 journal->j_blk_offset = start;
668 journal->j_maxlen = len;
669 journal->j_blocksize = blocksize;
670 + jbd_stats_proc_init(journal);
672 bh = __getblk(journal->j_dev, start, journal->j_blocksize);
673 J_ASSERT(bh != NULL);
674 @@ -770,6 +1069,7 @@ journal_t * journal_init_inode (struct i
676 journal->j_maxlen = inode->i_size >> inode->i_sb->s_blocksize_bits;
677 journal->j_blocksize = inode->i_sb->s_blocksize;
678 + jbd_stats_proc_init(journal);
680 err = journal_bmap(journal, 0, &blocknr);
681 /* If that failed, give up */
682 @@ -1140,6 +1440,8 @@ void journal_destroy(journal_t *journal)
683 brelse(journal->j_sb_buffer);
686 + if (journal->j_proc_entry)
687 + jbd_stats_proc_exit(journal);
688 if (journal->j_inode)
689 iput(journal->j_inode);
690 if (journal->j_revoke)
691 @@ -1895,6 +2197,28 @@ static void __exit remove_jbd_proc_entry
695 +#if defined(CONFIG_PROC_FS)
697 +#define JBD_STATS_PROC_NAME "fs/jbd"
699 +static void __init create_jbd_stats_proc_entry(void)
701 + proc_jbd_stats = proc_mkdir(JBD_STATS_PROC_NAME, NULL);
704 +static void __exit remove_jbd_stats_proc_entry(void)
706 + if (proc_jbd_stats)
707 + remove_proc_entry(JBD_STATS_PROC_NAME, NULL);
712 +#define create_jbd_stats_proc_entry() do {} while (0)
713 +#define remove_jbd_stats_proc_entry() do {} while (0)
717 kmem_cache_t *jbd_handle_cache;
719 static int __init journal_init_handle_cache(void)
720 @@ -1949,6 +2273,7 @@ static int __init journal_init(void)
722 journal_destroy_caches();
723 create_jbd_proc_entry();
724 + create_jbd_stats_proc_entry();
728 @@ -1960,6 +2285,7 @@ static void __exit journal_exit(void)
729 printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n);
731 remove_jbd_proc_entry();
732 + remove_jbd_stats_proc_entry();
733 journal_destroy_caches();