📄 jbd-stats-2.6-sles10.patch
字号:
+ 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@@ -679,6 +974,9 @@ static journal_t * journal_init_common ( kfree(journal); goto fail; }++ journal_init_stats(journal);+ return journal; fail: return NULL;@@ -722,6 +1020,7 @@ journal_t * journal_init_dev(struct bloc 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);@@ -771,6 +1070,7 @@ journal_t * journal_init_inode (struct i 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);@@ -1152,6 +1452,8 @@ void journal_destroy(journal_t *journal) 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)@@ -1920,6 +2222,28 @@ static void __exit remove_jbd_proc_entry #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)@@ -1982,6 +2306,7 @@ static int __init journal_init(void) if (ret != 0) journal_destroy_caches(); create_jbd_proc_entry();+ create_jbd_stats_proc_entry(); return ret; } @@ -1993,6 +2318,7 @@ static void __exit journal_exit(void) 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.16.46-0.14/fs/jbd/checkpoint.c===================================================================--- linux-2.6.16.46-0.14.orig/fs/jbd/checkpoint.c+++ linux-2.6.16.46-0.14/fs/jbd/checkpoint.c@@ -166,6 +166,7 @@ static int __cleanup_transaction(journal 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);@@ -226,7 +227,7 @@ __flush_batch(journal_t *journal, struct */ static int __flush_buffer(journal_t *journal, struct journal_head *jh, struct buffer_head **bhs, int *batch_count,- int *drop_count)+ int *drop_count, transaction_t *transaction) { struct buffer_head *bh = jh2bh(jh); int ret = 0;@@ -247,6 +248,7 @@ static int __flush_buffer(journal_t *jou set_buffer_jwrite(bh); bhs[*batch_count] = bh; jbd_unlock_bh_state(bh);+ transaction->t_chp_stats.cs_written++; (*batch_count)++; if (*batch_count == NR_BATCH) { __flush_batch(journal, bhs, batch_count);@@ -315,6 +317,8 @@ int log_do_checkpoint(journal_t *journal tid_t this_tid; 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; jh = transaction->t_checkpoint_list; last_jh = jh->b_cpprev;@@ -331,7 +335,8 @@ int log_do_checkpoint(journal_t *journal retry = 1; break; }- retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count);+ retry = __flush_buffer(journal, jh, bhs, &batch_count,+ &drop_count, transaction); if (cond_resched_lock(&journal->j_list_lock)) { retry = 1; break;@@ -609,6 +614,8 @@ void __journal_insert_checkpoint(struct 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;@@ -634,5 +641,25 @@ void __journal_drop_transaction(journal_ 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.16.46-0.14/fs/jbd/commit.c===================================================================--- linux-2.6.16.46-0.14.orig/fs/jbd/commit.c+++ linux-2.6.16.46-0.14/fs/jbd/commit.c@@ -21,6 +21,7 @@ #include <linux/mm.h> #include <linux/pagemap.h> #include <linux/smp_lock.h>+#include <linux/jiffies.h> /* * Default IO end handler for temporary BJ_IO buffer_heads.@@ -168,6 +169,7 @@ static int journal_write_commit_record(j */ 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;@@ -214,6 +216,11 @@ void journal_commit_transaction(journal_ 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);@@ -284,6 +291,9 @@ void journal_commit_transaction(journal_ */ 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;@@ -442,6 +452,11 @@ write_out_data: */ commit_transaction->t_state = T_COMMIT; + 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) {@@ -590,6 +605,7 @@ start_journal_io: submit_bh(WRITE, bh); } cond_resched();+ stats.ts_blocks_logged += bufs; /* Force a new descriptor to be generated next time round the loop. */@@ -784,6 +800,7 @@ restart_loop: 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); } @@ -858,6 +875,36 @@ restart_loop: 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -