aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jbd2/checkpoint.c5
-rw-r--r--fs/jbd2/commit.c13
-rw-r--r--fs/jbd2/journal.c69
-rw-r--r--include/linux/jbd2.h6
-rw-r--r--include/trace/events/jbd2.h168
5 files changed, 252 insertions, 9 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index 17159cacbd9e..5d70b3e6d49b 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -20,9 +20,9 @@
20#include <linux/time.h> 20#include <linux/time.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/jbd2.h> 22#include <linux/jbd2.h>
23#include <linux/marker.h>
24#include <linux/errno.h> 23#include <linux/errno.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
25#include <trace/events/jbd2.h>
26 26
27/* 27/*
28 * Unlink a buffer from a transaction checkpoint list. 28 * Unlink a buffer from a transaction checkpoint list.
@@ -358,8 +358,7 @@ int jbd2_log_do_checkpoint(journal_t *journal)
358 * journal straight away. 358 * journal straight away.
359 */ 359 */
360 result = jbd2_cleanup_journal_tail(journal); 360 result = jbd2_cleanup_journal_tail(journal);
361 trace_mark(jbd2_checkpoint, "dev %s need_checkpoint %d", 361 trace_jbd2_checkpoint(journal, result);
362 journal->j_devname, result);
363 jbd_debug(1, "cleanup_journal_tail returned %d\n", result); 362 jbd_debug(1, "cleanup_journal_tail returned %d\n", result);
364 if (result <= 0) 363 if (result <= 0)
365 return result; 364 return result;
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 0b7d3b8226fd..7b4088b2364d 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -16,7 +16,6 @@
16#include <linux/time.h> 16#include <linux/time.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/jbd2.h> 18#include <linux/jbd2.h>
19#include <linux/marker.h>
20#include <linux/errno.h> 19#include <linux/errno.h>
21#include <linux/slab.h> 20#include <linux/slab.h>
22#include <linux/mm.h> 21#include <linux/mm.h>
@@ -26,6 +25,7 @@
26#include <linux/writeback.h> 25#include <linux/writeback.h>
27#include <linux/backing-dev.h> 26#include <linux/backing-dev.h>
28#include <linux/bio.h> 27#include <linux/bio.h>
28#include <trace/events/jbd2.h>
29 29
30/* 30/*
31 * Default IO end handler for temporary BJ_IO buffer_heads. 31 * Default IO end handler for temporary BJ_IO buffer_heads.
@@ -253,6 +253,7 @@ static int journal_submit_data_buffers(journal_t *journal,
253 * block allocation with delalloc. We need to write 253 * block allocation with delalloc. We need to write
254 * only allocated blocks here. 254 * only allocated blocks here.
255 */ 255 */
256 trace_jbd2_submit_inode_data(jinode->i_vfs_inode);
256 err = journal_submit_inode_data_buffers(mapping); 257 err = journal_submit_inode_data_buffers(mapping);
257 if (!ret) 258 if (!ret)
258 ret = err; 259 ret = err;
@@ -394,8 +395,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
394 commit_transaction = journal->j_running_transaction; 395 commit_transaction = journal->j_running_transaction;
395 J_ASSERT(commit_transaction->t_state == T_RUNNING); 396 J_ASSERT(commit_transaction->t_state == T_RUNNING);
396 397
397 trace_mark(jbd2_start_commit, "dev %s transaction %d", 398 trace_jbd2_start_commit(journal, commit_transaction);
398 journal->j_devname, commit_transaction->t_tid);
399 jbd_debug(1, "JBD: starting commit of transaction %d\n", 399 jbd_debug(1, "JBD: starting commit of transaction %d\n",
400 commit_transaction->t_tid); 400 commit_transaction->t_tid);
401 401
@@ -409,6 +409,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
409 */ 409 */
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 stats.u.run.rs_wait = commit_transaction->t_max_wait; 413 stats.u.run.rs_wait = commit_transaction->t_max_wait;
413 stats.u.run.rs_locked = jiffies; 414 stats.u.run.rs_locked = jiffies;
414 stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start, 415 stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start,
@@ -484,6 +485,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
484 */ 485 */
485 jbd2_journal_switch_revoke_table(journal); 486 jbd2_journal_switch_revoke_table(journal);
486 487
488 trace_jbd2_commit_flushing(journal, commit_transaction);
487 stats.u.run.rs_flushing = jiffies; 489 stats.u.run.rs_flushing = jiffies;
488 stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked, 490 stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked,
489 stats.u.run.rs_flushing); 491 stats.u.run.rs_flushing);
@@ -520,6 +522,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
520 commit_transaction->t_state = T_COMMIT; 522 commit_transaction->t_state = T_COMMIT;
521 spin_unlock(&journal->j_state_lock); 523 spin_unlock(&journal->j_state_lock);
522 524
525 trace_jbd2_commit_logging(journal, commit_transaction);
523 stats.u.run.rs_logging = jiffies; 526 stats.u.run.rs_logging = jiffies;
524 stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, 527 stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing,
525 stats.u.run.rs_logging); 528 stats.u.run.rs_logging);
@@ -1054,9 +1057,7 @@ restart_loop:
1054 if (journal->j_commit_callback) 1057 if (journal->j_commit_callback)
1055 journal->j_commit_callback(journal, commit_transaction); 1058 journal->j_commit_callback(journal, commit_transaction);
1056 1059
1057 trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", 1060 trace_jbd2_end_commit(journal, commit_transaction);
1058 journal->j_devname, commit_transaction->t_tid,
1059 journal->j_tail_sequence);
1060 jbd_debug(1, "JBD: commit %d complete, head %d\n", 1061 jbd_debug(1, "JBD: commit %d complete, head %d\n",
1061 journal->j_commit_sequence, journal->j_tail_sequence); 1062 journal->j_commit_sequence, journal->j_tail_sequence);
1062 if (to_free) 1063 if (to_free)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 62be7d294ec2..18bfd5dab642 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -38,6 +38,10 @@
38#include <linux/debugfs.h> 38#include <linux/debugfs.h>
39#include <linux/seq_file.h> 39#include <linux/seq_file.h>
40#include <linux/math64.h> 40#include <linux/math64.h>
41#include <linux/hash.h>
42
43#define CREATE_TRACE_POINTS
44#include <trace/events/jbd2.h>
41 45
42#include <asm/uaccess.h> 46#include <asm/uaccess.h>
43#include <asm/page.h> 47#include <asm/page.h>
@@ -2377,6 +2381,71 @@ static void __exit journal_exit(void)
2377 jbd2_journal_destroy_caches(); 2381 jbd2_journal_destroy_caches();
2378} 2382}
2379 2383
2384/*
2385 * jbd2_dev_to_name is a utility function used by the jbd2 and ext4
2386 * tracing infrastructure to map a dev_t to a device name.
2387 *
2388 * The caller should use rcu_read_lock() in order to make sure the
2389 * device name stays valid until its done with it. We use
2390 * rcu_read_lock() as well to make sure we're safe in case the caller
2391 * gets sloppy, and because rcu_read_lock() is cheap and can be safely
2392 * nested.
2393 */
2394struct devname_cache {
2395 struct rcu_head rcu;
2396 dev_t device;
2397 char devname[BDEVNAME_SIZE];
2398};
2399#define CACHE_SIZE_BITS 6
2400static struct devname_cache *devcache[1 << CACHE_SIZE_BITS];
2401static DEFINE_SPINLOCK(devname_cache_lock);
2402
2403static void free_devcache(struct rcu_head *rcu)
2404{
2405 kfree(rcu);
2406}
2407
2408const char *jbd2_dev_to_name(dev_t device)
2409{
2410 int i = hash_32(device, CACHE_SIZE_BITS);
2411 char *ret;
2412 struct block_device *bd;
2413
2414 rcu_read_lock();
2415 if (devcache[i] && devcache[i]->device == device) {
2416 ret = devcache[i]->devname;
2417 rcu_read_unlock();
2418 return ret;
2419 }
2420 rcu_read_unlock();
2421
2422 spin_lock(&devname_cache_lock);
2423 if (devcache[i]) {
2424 if (devcache[i]->device == device) {
2425 ret = devcache[i]->devname;
2426 spin_unlock(&devname_cache_lock);
2427 return ret;
2428 }
2429 call_rcu(&devcache[i]->rcu, free_devcache);
2430 }
2431 devcache[i] = kmalloc(sizeof(struct devname_cache), GFP_KERNEL);
2432 if (!devcache[i]) {
2433 spin_unlock(&devname_cache_lock);
2434 return "NODEV-ALLOCFAILURE"; /* Something non-NULL */
2435 }
2436 devcache[i]->device = device;
2437 bd = bdget(device);
2438 if (bd) {
2439 bdevname(bd, devcache[i]->devname);
2440 bdput(bd);
2441 } else
2442 __bdevname(device, devcache[i]->devname);
2443 ret = devcache[i]->devname;
2444 spin_unlock(&devname_cache_lock);
2445 return ret;
2446}
2447EXPORT_SYMBOL(jbd2_dev_to_name);
2448
2380MODULE_LICENSE("GPL"); 2449MODULE_LICENSE("GPL");
2381module_init(journal_init); 2450module_init(journal_init);
2382module_exit(journal_exit); 2451module_exit(journal_exit);
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index cc02393bfce8..d97eb652d6ca 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1315,6 +1315,12 @@ extern int jbd_blocks_per_page(struct inode *inode);
1315#define BUFFER_TRACE2(bh, bh2, info) do {} while (0) 1315#define BUFFER_TRACE2(bh, bh2, info) do {} while (0)
1316#define JBUFFER_TRACE(jh, info) do {} while (0) 1316#define JBUFFER_TRACE(jh, info) do {} while (0)
1317 1317
1318/*
1319 * jbd2_dev_to_name is a utility function used by the jbd2 and ext4
1320 * tracing infrastructure to map a dev_t to a device name.
1321 */
1322extern const char *jbd2_dev_to_name(dev_t device);
1323
1318#endif /* __KERNEL__ */ 1324#endif /* __KERNEL__ */
1319 1325
1320#endif /* _LINUX_JBD2_H */ 1326#endif /* _LINUX_JBD2_H */
diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h
new file mode 100644
index 000000000000..845b0b4b48fd
--- /dev/null
+++ b/include/trace/events/jbd2.h
@@ -0,0 +1,168 @@
1#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ)
2#define _TRACE_JBD2_H
3
4#include <linux/jbd2.h>
5#include <linux/tracepoint.h>
6
7#undef TRACE_SYSTEM
8#define TRACE_SYSTEM jbd2
9
10TRACE_EVENT(jbd2_checkpoint,
11
12 TP_PROTO(journal_t *journal, int result),
13
14 TP_ARGS(journal, result),
15
16 TP_STRUCT__entry(
17 __field( dev_t, dev )
18 __field( int, result )
19 ),
20
21 TP_fast_assign(
22 __entry->dev = journal->j_fs_dev->bd_dev;
23 __entry->result = result;
24 ),
25
26 TP_printk("dev %s result %d",
27 jbd2_dev_to_name(__entry->dev), __entry->result)
28);
29
30TRACE_EVENT(jbd2_start_commit,
31
32 TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
33
34 TP_ARGS(journal, commit_transaction),
35
36 TP_STRUCT__entry(
37 __field( dev_t, dev )
38 __field( char, sync_commit )
39 __field( int, transaction )
40 ),
41
42 TP_fast_assign(
43 __entry->dev = journal->j_fs_dev->bd_dev;
44 __entry->sync_commit = commit_transaction->t_synchronous_commit;
45 __entry->transaction = commit_transaction->t_tid;
46 ),
47
48 TP_printk("dev %s transaction %d sync %d",
49 jbd2_dev_to_name(__entry->dev), __entry->transaction,
50 __entry->sync_commit)
51);
52
53TRACE_EVENT(jbd2_commit_locking,
54
55 TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
56
57 TP_ARGS(journal, commit_transaction),
58
59 TP_STRUCT__entry(
60 __field( dev_t, dev )
61 __field( char, sync_commit )
62 __field( int, transaction )
63 ),
64
65 TP_fast_assign(
66 __entry->dev = journal->j_fs_dev->bd_dev;
67 __entry->sync_commit = commit_transaction->t_synchronous_commit;
68 __entry->transaction = commit_transaction->t_tid;
69 ),
70
71 TP_printk("dev %s transaction %d sync %d",
72 jbd2_dev_to_name(__entry->dev), __entry->transaction,
73 __entry->sync_commit)
74);
75
76TRACE_EVENT(jbd2_commit_flushing,
77
78 TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
79
80 TP_ARGS(journal, commit_transaction),
81
82 TP_STRUCT__entry(
83 __field( dev_t, dev )
84 __field( char, sync_commit )
85 __field( int, transaction )
86 ),
87
88 TP_fast_assign(
89 __entry->dev = journal->j_fs_dev->bd_dev;
90 __entry->sync_commit = commit_transaction->t_synchronous_commit;
91 __entry->transaction = commit_transaction->t_tid;
92 ),
93
94 TP_printk("dev %s transaction %d sync %d",
95 jbd2_dev_to_name(__entry->dev), __entry->transaction,
96 __entry->sync_commit)
97);
98
99TRACE_EVENT(jbd2_commit_logging,
100
101 TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
102
103 TP_ARGS(journal, commit_transaction),
104
105 TP_STRUCT__entry(
106 __field( dev_t, dev )
107 __field( char, sync_commit )
108 __field( int, transaction )
109 ),
110
111 TP_fast_assign(
112 __entry->dev = journal->j_fs_dev->bd_dev;
113 __entry->sync_commit = commit_transaction->t_synchronous_commit;
114 __entry->transaction = commit_transaction->t_tid;
115 ),
116
117 TP_printk("dev %s transaction %d sync %d",
118 jbd2_dev_to_name(__entry->dev), __entry->transaction,
119 __entry->sync_commit)
120);
121
122TRACE_EVENT(jbd2_end_commit,
123 TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
124
125 TP_ARGS(journal, commit_transaction),
126
127 TP_STRUCT__entry(
128 __field( dev_t, dev )
129 __field( char, sync_commit )
130 __field( int, transaction )
131 __field( int, head )
132 ),
133
134 TP_fast_assign(
135 __entry->dev = journal->j_fs_dev->bd_dev;
136 __entry->sync_commit = commit_transaction->t_synchronous_commit;
137 __entry->transaction = commit_transaction->t_tid;
138 __entry->head = journal->j_tail_sequence;
139 ),
140
141 TP_printk("dev %s transaction %d sync %d head %d",
142 jbd2_dev_to_name(__entry->dev), __entry->transaction,
143 __entry->sync_commit, __entry->head)
144);
145
146TRACE_EVENT(jbd2_submit_inode_data,
147 TP_PROTO(struct inode *inode),
148
149 TP_ARGS(inode),
150
151 TP_STRUCT__entry(
152 __field( dev_t, dev )
153 __field( ino_t, ino )
154 ),
155
156 TP_fast_assign(
157 __entry->dev = inode->i_sb->s_dev;
158 __entry->ino = inode->i_ino;
159 ),
160
161 TP_printk("dev %s ino %lu",
162 jbd2_dev_to_name(__entry->dev), __entry->ino)
163);
164
165#endif /* _TRACE_JBD2_H */
166
167/* This part must be outside protection */
168#include <trace/define_trace.h>