⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jbd-stats-2.6-sles10.patch

📁 非常经典的一个分布式系统
💻 PATCH
📖 第 1 页 / 共 2 页
字号:
Index: linux-2.6.16.46-0.14/include/linux/jbd.h===================================================================--- linux-2.6.16.46-0.14.orig/include/linux/jbd.h+++ linux-2.6.16.46-0.14/include/linux/jbd.h@@ -422,6 +422,16 @@ struct handle_s  };  +/*+ * 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:  *@@ -553,6 +563,21 @@ struct transaction_s  	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] 	 */@@ -592,6 +617,57 @@ struct transaction_s  	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.@@ -845,6 +921,16 @@ struct journal_s 	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.16.46-0.14/fs/jbd/transaction.c===================================================================--- linux-2.6.16.46-0.14.orig/fs/jbd/transaction.c+++ linux-2.6.16.46-0.14/fs/jbd/transaction.c@@ -60,6 +60,8 @@ get_transaction(journal_t *journal, tran  	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 @@ static int start_this_handle(journal_t * 	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 @@ repeat_locked: 	/* 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.16.46-0.14/fs/jbd/journal.c===================================================================--- linux-2.6.16.46-0.14.orig/fs/jbd/journal.c+++ linux-2.6.16.46-0.14/fs/jbd/journal.c@@ -36,6 +36,7 @@ #include <asm/uaccess.h> #include <asm/page.h> #include <linux/proc_fs.h>+#include <linux/seq_file.h>  EXPORT_SYMBOL(journal_start); EXPORT_SYMBOL(journal_restart);@@ -637,6 +638,300 @@ struct journal_head *journal_get_descrip 	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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -