diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-09-30 00:32:06 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-09-30 00:32:06 -0400 |
commit | bf6993276f74d46776f35c45ddef29b981b1d1c6 (patch) | |
tree | 5c9cb128fed29a83add1932b12443edaa6fd06cc /fs | |
parent | 296c355cd6443d89fa251885a8d78778fe111dc4 (diff) |
jbd2: Use tracepoints for history file
The /proc/fs/jbd2/<dev>/history was maintained manually; by using
tracepoints, we can get all of the existing functionality of the /proc
file plus extra capabilities thanks to the ftrace infrastructure. We
save memory as a bonus.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/jbd2/checkpoint.c | 7 | ||||
-rw-r--r-- | fs/jbd2/commit.c | 59 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 187 |
3 files changed, 45 insertions, 208 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 5d70b3e6d49b..ca0f5eb62b20 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
@@ -643,6 +643,7 @@ out: | |||
643 | 643 | ||
644 | int __jbd2_journal_remove_checkpoint(struct journal_head *jh) | 644 | int __jbd2_journal_remove_checkpoint(struct journal_head *jh) |
645 | { | 645 | { |
646 | struct transaction_chp_stats_s *stats; | ||
646 | transaction_t *transaction; | 647 | transaction_t *transaction; |
647 | journal_t *journal; | 648 | journal_t *journal; |
648 | int ret = 0; | 649 | int ret = 0; |
@@ -679,6 +680,12 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) | |||
679 | 680 | ||
680 | /* OK, that was the last buffer for the transaction: we can now | 681 | /* OK, that was the last buffer for the transaction: we can now |
681 | safely remove this transaction from the log */ | 682 | safely remove this transaction from the log */ |
683 | stats = &transaction->t_chp_stats; | ||
684 | if (stats->cs_chp_time) | ||
685 | stats->cs_chp_time = jbd2_time_diff(stats->cs_chp_time, | ||
686 | jiffies); | ||
687 | trace_jbd2_checkpoint_stats(journal->j_fs_dev->bd_dev, | ||
688 | transaction->t_tid, stats); | ||
682 | 689 | ||
683 | __jbd2_journal_drop_transaction(journal, transaction); | 690 | __jbd2_journal_drop_transaction(journal, transaction); |
684 | kfree(transaction); | 691 | kfree(transaction); |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 26d991ddc1e6..d4cfd6d2779e 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -410,10 +410,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
410 | if (commit_transaction->t_synchronous_commit) | 410 | if (commit_transaction->t_synchronous_commit) |
411 | write_op = WRITE_SYNC_PLUG; | 411 | write_op = WRITE_SYNC_PLUG; |
412 | trace_jbd2_commit_locking(journal, commit_transaction); | 412 | trace_jbd2_commit_locking(journal, commit_transaction); |
413 | stats.u.run.rs_wait = commit_transaction->t_max_wait; | 413 | stats.run.rs_wait = commit_transaction->t_max_wait; |
414 | stats.u.run.rs_locked = jiffies; | 414 | stats.run.rs_locked = jiffies; |
415 | stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start, | 415 | stats.run.rs_running = jbd2_time_diff(commit_transaction->t_start, |
416 | stats.u.run.rs_locked); | 416 | stats.run.rs_locked); |
417 | 417 | ||
418 | spin_lock(&commit_transaction->t_handle_lock); | 418 | spin_lock(&commit_transaction->t_handle_lock); |
419 | while (commit_transaction->t_updates) { | 419 | while (commit_transaction->t_updates) { |
@@ -486,9 +486,9 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
486 | jbd2_journal_switch_revoke_table(journal); | 486 | jbd2_journal_switch_revoke_table(journal); |
487 | 487 | ||
488 | trace_jbd2_commit_flushing(journal, commit_transaction); | 488 | trace_jbd2_commit_flushing(journal, commit_transaction); |
489 | stats.u.run.rs_flushing = jiffies; | 489 | stats.run.rs_flushing = jiffies; |
490 | stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked, | 490 | stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked, |
491 | stats.u.run.rs_flushing); | 491 | stats.run.rs_flushing); |
492 | 492 | ||
493 | commit_transaction->t_state = T_FLUSH; | 493 | commit_transaction->t_state = T_FLUSH; |
494 | journal->j_committing_transaction = commit_transaction; | 494 | journal->j_committing_transaction = commit_transaction; |
@@ -523,11 +523,11 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
523 | spin_unlock(&journal->j_state_lock); | 523 | spin_unlock(&journal->j_state_lock); |
524 | 524 | ||
525 | trace_jbd2_commit_logging(journal, commit_transaction); | 525 | trace_jbd2_commit_logging(journal, commit_transaction); |
526 | stats.u.run.rs_logging = jiffies; | 526 | stats.run.rs_logging = jiffies; |
527 | stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, | 527 | stats.run.rs_flushing = jbd2_time_diff(stats.run.rs_flushing, |
528 | stats.u.run.rs_logging); | 528 | stats.run.rs_logging); |
529 | stats.u.run.rs_blocks = commit_transaction->t_outstanding_credits; | 529 | stats.run.rs_blocks = commit_transaction->t_outstanding_credits; |
530 | stats.u.run.rs_blocks_logged = 0; | 530 | stats.run.rs_blocks_logged = 0; |
531 | 531 | ||
532 | J_ASSERT(commit_transaction->t_nr_buffers <= | 532 | J_ASSERT(commit_transaction->t_nr_buffers <= |
533 | commit_transaction->t_outstanding_credits); | 533 | commit_transaction->t_outstanding_credits); |
@@ -695,7 +695,7 @@ start_journal_io: | |||
695 | submit_bh(write_op, bh); | 695 | submit_bh(write_op, bh); |
696 | } | 696 | } |
697 | cond_resched(); | 697 | cond_resched(); |
698 | stats.u.run.rs_blocks_logged += bufs; | 698 | stats.run.rs_blocks_logged += bufs; |
699 | 699 | ||
700 | /* Force a new descriptor to be generated next | 700 | /* Force a new descriptor to be generated next |
701 | time round the loop. */ | 701 | time round the loop. */ |
@@ -988,33 +988,30 @@ restart_loop: | |||
988 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | 988 | J_ASSERT(commit_transaction->t_state == T_COMMIT); |
989 | 989 | ||
990 | commit_transaction->t_start = jiffies; | 990 | commit_transaction->t_start = jiffies; |
991 | stats.u.run.rs_logging = jbd2_time_diff(stats.u.run.rs_logging, | 991 | stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, |
992 | commit_transaction->t_start); | 992 | commit_transaction->t_start); |
993 | 993 | ||
994 | /* | 994 | /* |
995 | * File the transaction for history | 995 | * File the transaction statistics |
996 | */ | 996 | */ |
997 | stats.ts_type = JBD2_STATS_RUN; | ||
998 | stats.ts_tid = commit_transaction->t_tid; | 997 | stats.ts_tid = commit_transaction->t_tid; |
999 | stats.u.run.rs_handle_count = commit_transaction->t_handle_count; | 998 | stats.run.rs_handle_count = commit_transaction->t_handle_count; |
1000 | spin_lock(&journal->j_history_lock); | 999 | trace_jbd2_run_stats(journal->j_fs_dev->bd_dev, |
1001 | memcpy(journal->j_history + journal->j_history_cur, &stats, | 1000 | commit_transaction->t_tid, &stats.run); |
1002 | sizeof(stats)); | ||
1003 | if (++journal->j_history_cur == journal->j_history_max) | ||
1004 | journal->j_history_cur = 0; | ||
1005 | 1001 | ||
1006 | /* | 1002 | /* |
1007 | * Calculate overall stats | 1003 | * Calculate overall stats |
1008 | */ | 1004 | */ |
1005 | spin_lock(&journal->j_history_lock); | ||
1009 | journal->j_stats.ts_tid++; | 1006 | journal->j_stats.ts_tid++; |
1010 | journal->j_stats.u.run.rs_wait += stats.u.run.rs_wait; | 1007 | journal->j_stats.run.rs_wait += stats.run.rs_wait; |
1011 | journal->j_stats.u.run.rs_running += stats.u.run.rs_running; | 1008 | journal->j_stats.run.rs_running += stats.run.rs_running; |
1012 | journal->j_stats.u.run.rs_locked += stats.u.run.rs_locked; | 1009 | journal->j_stats.run.rs_locked += stats.run.rs_locked; |
1013 | journal->j_stats.u.run.rs_flushing += stats.u.run.rs_flushing; | 1010 | journal->j_stats.run.rs_flushing += stats.run.rs_flushing; |
1014 | journal->j_stats.u.run.rs_logging += stats.u.run.rs_logging; | 1011 | journal->j_stats.run.rs_logging += stats.run.rs_logging; |
1015 | journal->j_stats.u.run.rs_handle_count += stats.u.run.rs_handle_count; | 1012 | journal->j_stats.run.rs_handle_count += stats.run.rs_handle_count; |
1016 | journal->j_stats.u.run.rs_blocks += stats.u.run.rs_blocks; | 1013 | journal->j_stats.run.rs_blocks += stats.run.rs_blocks; |
1017 | journal->j_stats.u.run.rs_blocks_logged += stats.u.run.rs_blocks_logged; | 1014 | journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged; |
1018 | spin_unlock(&journal->j_history_lock); | 1015 | spin_unlock(&journal->j_history_lock); |
1019 | 1016 | ||
1020 | commit_transaction->t_state = T_FINISHED; | 1017 | commit_transaction->t_state = T_FINISHED; |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 977a8dafb76d..761af77491f5 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -676,153 +676,6 @@ struct jbd2_stats_proc_session { | |||
676 | int max; | 676 | int max; |
677 | }; | 677 | }; |
678 | 678 | ||
679 | static void *jbd2_history_skip_empty(struct jbd2_stats_proc_session *s, | ||
680 | struct transaction_stats_s *ts, | ||
681 | int first) | ||
682 | { | ||
683 | if (ts == s->stats + s->max) | ||
684 | ts = s->stats; | ||
685 | if (!first && ts == s->stats + s->start) | ||
686 | return NULL; | ||
687 | while (ts->ts_type == 0) { | ||
688 | ts++; | ||
689 | if (ts == s->stats + s->max) | ||
690 | ts = s->stats; | ||
691 | if (ts == s->stats + s->start) | ||
692 | return NULL; | ||
693 | } | ||
694 | return ts; | ||
695 | |||
696 | } | ||
697 | |||
698 | static void *jbd2_seq_history_start(struct seq_file *seq, loff_t *pos) | ||
699 | { | ||
700 | struct jbd2_stats_proc_session *s = seq->private; | ||
701 | struct transaction_stats_s *ts; | ||
702 | int l = *pos; | ||
703 | |||
704 | if (l == 0) | ||
705 | return SEQ_START_TOKEN; | ||
706 | ts = jbd2_history_skip_empty(s, s->stats + s->start, 1); | ||
707 | if (!ts) | ||
708 | return NULL; | ||
709 | l--; | ||
710 | while (l) { | ||
711 | ts = jbd2_history_skip_empty(s, ++ts, 0); | ||
712 | if (!ts) | ||
713 | break; | ||
714 | l--; | ||
715 | } | ||
716 | return ts; | ||
717 | } | ||
718 | |||
719 | static void *jbd2_seq_history_next(struct seq_file *seq, void *v, loff_t *pos) | ||
720 | { | ||
721 | struct jbd2_stats_proc_session *s = seq->private; | ||
722 | struct transaction_stats_s *ts = v; | ||
723 | |||
724 | ++*pos; | ||
725 | if (v == SEQ_START_TOKEN) | ||
726 | return jbd2_history_skip_empty(s, s->stats + s->start, 1); | ||
727 | else | ||
728 | return jbd2_history_skip_empty(s, ++ts, 0); | ||
729 | } | ||
730 | |||
731 | static int jbd2_seq_history_show(struct seq_file *seq, void *v) | ||
732 | { | ||
733 | struct transaction_stats_s *ts = v; | ||
734 | if (v == SEQ_START_TOKEN) { | ||
735 | seq_printf(seq, "%-4s %-5s %-5s %-5s %-5s %-5s %-5s %-6s %-5s " | ||
736 | "%-5s %-5s %-5s %-5s %-5s\n", "R/C", "tid", | ||
737 | "wait", "run", "lock", "flush", "log", "hndls", | ||
738 | "block", "inlog", "ctime", "write", "drop", | ||
739 | "close"); | ||
740 | return 0; | ||
741 | } | ||
742 | if (ts->ts_type == JBD2_STATS_RUN) | ||
743 | seq_printf(seq, "%-4s %-5lu %-5u %-5u %-5u %-5u %-5u " | ||
744 | "%-6lu %-5lu %-5lu\n", "R", ts->ts_tid, | ||
745 | jiffies_to_msecs(ts->u.run.rs_wait), | ||
746 | jiffies_to_msecs(ts->u.run.rs_running), | ||
747 | jiffies_to_msecs(ts->u.run.rs_locked), | ||
748 | jiffies_to_msecs(ts->u.run.rs_flushing), | ||
749 | jiffies_to_msecs(ts->u.run.rs_logging), | ||
750 | ts->u.run.rs_handle_count, | ||
751 | ts->u.run.rs_blocks, | ||
752 | ts->u.run.rs_blocks_logged); | ||
753 | else if (ts->ts_type == JBD2_STATS_CHECKPOINT) | ||
754 | seq_printf(seq, "%-4s %-5lu %48s %-5u %-5lu %-5lu %-5lu\n", | ||
755 | "C", ts->ts_tid, " ", | ||
756 | jiffies_to_msecs(ts->u.chp.cs_chp_time), | ||
757 | ts->u.chp.cs_written, ts->u.chp.cs_dropped, | ||
758 | ts->u.chp.cs_forced_to_close); | ||
759 | else | ||
760 | J_ASSERT(0); | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static void jbd2_seq_history_stop(struct seq_file *seq, void *v) | ||
765 | { | ||
766 | } | ||
767 | |||
768 | static const struct seq_operations jbd2_seq_history_ops = { | ||
769 | .start = jbd2_seq_history_start, | ||
770 | .next = jbd2_seq_history_next, | ||
771 | .stop = jbd2_seq_history_stop, | ||
772 | .show = jbd2_seq_history_show, | ||
773 | }; | ||
774 | |||
775 | static int jbd2_seq_history_open(struct inode *inode, struct file *file) | ||
776 | { | ||
777 | journal_t *journal = PDE(inode)->data; | ||
778 | struct jbd2_stats_proc_session *s; | ||
779 | int rc, size; | ||
780 | |||
781 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
782 | if (s == NULL) | ||
783 | return -ENOMEM; | ||
784 | size = sizeof(struct transaction_stats_s) * journal->j_history_max; | ||
785 | s->stats = kmalloc(size, GFP_KERNEL); | ||
786 | if (s->stats == NULL) { | ||
787 | kfree(s); | ||
788 | return -ENOMEM; | ||
789 | } | ||
790 | spin_lock(&journal->j_history_lock); | ||
791 | memcpy(s->stats, journal->j_history, size); | ||
792 | s->max = journal->j_history_max; | ||
793 | s->start = journal->j_history_cur % s->max; | ||
794 | spin_unlock(&journal->j_history_lock); | ||
795 | |||
796 | rc = seq_open(file, &jbd2_seq_history_ops); | ||
797 | if (rc == 0) { | ||
798 | struct seq_file *m = file->private_data; | ||
799 | m->private = s; | ||
800 | } else { | ||
801 | kfree(s->stats); | ||
802 | kfree(s); | ||
803 | } | ||
804 | return rc; | ||
805 | |||
806 | } | ||
807 | |||
808 | static int jbd2_seq_history_release(struct inode *inode, struct file *file) | ||
809 | { | ||
810 | struct seq_file *seq = file->private_data; | ||
811 | struct jbd2_stats_proc_session *s = seq->private; | ||
812 | |||
813 | kfree(s->stats); | ||
814 | kfree(s); | ||
815 | return seq_release(inode, file); | ||
816 | } | ||
817 | |||
818 | static struct file_operations jbd2_seq_history_fops = { | ||
819 | .owner = THIS_MODULE, | ||
820 | .open = jbd2_seq_history_open, | ||
821 | .read = seq_read, | ||
822 | .llseek = seq_lseek, | ||
823 | .release = jbd2_seq_history_release, | ||
824 | }; | ||
825 | |||
826 | static void *jbd2_seq_info_start(struct seq_file *seq, loff_t *pos) | 679 | static void *jbd2_seq_info_start(struct seq_file *seq, loff_t *pos) |
827 | { | 680 | { |
828 | return *pos ? NULL : SEQ_START_TOKEN; | 681 | return *pos ? NULL : SEQ_START_TOKEN; |
@@ -839,29 +692,29 @@ static int jbd2_seq_info_show(struct seq_file *seq, void *v) | |||
839 | 692 | ||
840 | if (v != SEQ_START_TOKEN) | 693 | if (v != SEQ_START_TOKEN) |
841 | return 0; | 694 | return 0; |
842 | seq_printf(seq, "%lu transaction, each upto %u blocks\n", | 695 | seq_printf(seq, "%lu transaction, each up to %u blocks\n", |
843 | s->stats->ts_tid, | 696 | s->stats->ts_tid, |
844 | s->journal->j_max_transaction_buffers); | 697 | s->journal->j_max_transaction_buffers); |
845 | if (s->stats->ts_tid == 0) | 698 | if (s->stats->ts_tid == 0) |
846 | return 0; | 699 | return 0; |
847 | seq_printf(seq, "average: \n %ums waiting for transaction\n", | 700 | seq_printf(seq, "average: \n %ums waiting for transaction\n", |
848 | jiffies_to_msecs(s->stats->u.run.rs_wait / s->stats->ts_tid)); | 701 | jiffies_to_msecs(s->stats->run.rs_wait / s->stats->ts_tid)); |
849 | seq_printf(seq, " %ums running transaction\n", | 702 | seq_printf(seq, " %ums running transaction\n", |
850 | jiffies_to_msecs(s->stats->u.run.rs_running / s->stats->ts_tid)); | 703 | jiffies_to_msecs(s->stats->run.rs_running / s->stats->ts_tid)); |
851 | seq_printf(seq, " %ums transaction was being locked\n", | 704 | seq_printf(seq, " %ums transaction was being locked\n", |
852 | jiffies_to_msecs(s->stats->u.run.rs_locked / s->stats->ts_tid)); | 705 | jiffies_to_msecs(s->stats->run.rs_locked / s->stats->ts_tid)); |
853 | seq_printf(seq, " %ums flushing data (in ordered mode)\n", | 706 | seq_printf(seq, " %ums flushing data (in ordered mode)\n", |
854 | jiffies_to_msecs(s->stats->u.run.rs_flushing / s->stats->ts_tid)); | 707 | jiffies_to_msecs(s->stats->run.rs_flushing / s->stats->ts_tid)); |
855 | seq_printf(seq, " %ums logging transaction\n", | 708 | seq_printf(seq, " %ums logging transaction\n", |
856 | jiffies_to_msecs(s->stats->u.run.rs_logging / s->stats->ts_tid)); | 709 | jiffies_to_msecs(s->stats->run.rs_logging / s->stats->ts_tid)); |
857 | seq_printf(seq, " %lluus average transaction commit time\n", | 710 | seq_printf(seq, " %lluus average transaction commit time\n", |
858 | div_u64(s->journal->j_average_commit_time, 1000)); | 711 | div_u64(s->journal->j_average_commit_time, 1000)); |
859 | seq_printf(seq, " %lu handles per transaction\n", | 712 | seq_printf(seq, " %lu handles per transaction\n", |
860 | s->stats->u.run.rs_handle_count / s->stats->ts_tid); | 713 | s->stats->run.rs_handle_count / s->stats->ts_tid); |
861 | seq_printf(seq, " %lu blocks per transaction\n", | 714 | seq_printf(seq, " %lu blocks per transaction\n", |
862 | s->stats->u.run.rs_blocks / s->stats->ts_tid); | 715 | s->stats->run.rs_blocks / s->stats->ts_tid); |
863 | seq_printf(seq, " %lu logged blocks per transaction\n", | 716 | seq_printf(seq, " %lu logged blocks per transaction\n", |
864 | s->stats->u.run.rs_blocks_logged / s->stats->ts_tid); | 717 | s->stats->run.rs_blocks_logged / s->stats->ts_tid); |
865 | return 0; | 718 | return 0; |
866 | } | 719 | } |
867 | 720 | ||
@@ -931,8 +784,6 @@ static void jbd2_stats_proc_init(journal_t *journal) | |||
931 | { | 784 | { |
932 | journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats); | 785 | journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats); |
933 | if (journal->j_proc_entry) { | 786 | if (journal->j_proc_entry) { |
934 | proc_create_data("history", S_IRUGO, journal->j_proc_entry, | ||
935 | &jbd2_seq_history_fops, journal); | ||
936 | proc_create_data("info", S_IRUGO, journal->j_proc_entry, | 787 | proc_create_data("info", S_IRUGO, journal->j_proc_entry, |
937 | &jbd2_seq_info_fops, journal); | 788 | &jbd2_seq_info_fops, journal); |
938 | } | 789 | } |
@@ -941,27 +792,9 @@ static void jbd2_stats_proc_init(journal_t *journal) | |||
941 | static void jbd2_stats_proc_exit(journal_t *journal) | 792 | static void jbd2_stats_proc_exit(journal_t *journal) |
942 | { | 793 | { |
943 | remove_proc_entry("info", journal->j_proc_entry); | 794 | remove_proc_entry("info", journal->j_proc_entry); |
944 | remove_proc_entry("history", journal->j_proc_entry); | ||
945 | remove_proc_entry(journal->j_devname, proc_jbd2_stats); | 795 | remove_proc_entry(journal->j_devname, proc_jbd2_stats); |
946 | } | 796 | } |
947 | 797 | ||
948 | static void journal_init_stats(journal_t *journal) | ||
949 | { | ||
950 | int size; | ||
951 | |||
952 | if (!proc_jbd2_stats) | ||
953 | return; | ||
954 | |||
955 | journal->j_history_max = 100; | ||
956 | size = sizeof(struct transaction_stats_s) * journal->j_history_max; | ||
957 | journal->j_history = kzalloc(size, GFP_KERNEL); | ||
958 | if (!journal->j_history) { | ||
959 | journal->j_history_max = 0; | ||
960 | return; | ||
961 | } | ||
962 | spin_lock_init(&journal->j_history_lock); | ||
963 | } | ||
964 | |||
965 | /* | 798 | /* |
966 | * Management for journal control blocks: functions to create and | 799 | * Management for journal control blocks: functions to create and |
967 | * destroy journal_t structures, and to initialise and read existing | 800 | * destroy journal_t structures, and to initialise and read existing |
@@ -1006,7 +839,7 @@ static journal_t * journal_init_common (void) | |||
1006 | goto fail; | 839 | goto fail; |
1007 | } | 840 | } |
1008 | 841 | ||
1009 | journal_init_stats(journal); | 842 | spin_lock_init(&journal->j_history_lock); |
1010 | 843 | ||
1011 | return journal; | 844 | return journal; |
1012 | fail: | 845 | fail: |