]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.suse/ocfs2-track-local-alloc-state-via-debugfs.patch
Move xen patchset to new version's subdir.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / ocfs2-track-local-alloc-state-via-debugfs.patch
CommitLineData
00e5a55c
BS
1From: Mark Fasheh <mfasheh@suse.com>
2Subject: ocfs2: track local alloc state via debugfs
3Patch-mainline: 2.6.28
4
5A per-mount debugfs file, "local_alloc" is created which when read will
6expose live state of the nodes local alloc file. Performance impact is
7minimal, only a bit of memory overhead per mount point. Still, the code is
8hidden behind CONFIG_OCFS2_FS_STATS. This feature will help us debug
9local alloc performance problems on a live system.
10
11Signed-off-by: Mark Fasheh <mfasheh@suse.com>
12---
13 fs/ocfs2/localalloc.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++
14 fs/ocfs2/ocfs2.h | 5 ++
15 2 files changed, 92 insertions(+)
16
17--- a/fs/ocfs2/localalloc.c
18+++ b/fs/ocfs2/localalloc.c
19@@ -28,6 +28,7 @@
20 #include <linux/slab.h>
21 #include <linux/highmem.h>
22 #include <linux/bitops.h>
23+#include <linux/debugfs.h>
24
25 #define MLOG_MASK_PREFIX ML_DISK_ALLOC
26 #include <cluster/masklog.h>
27@@ -73,6 +74,85 @@ static int ocfs2_local_alloc_new_window(
28 static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
29 struct inode *local_alloc_inode);
30
31+#ifdef CONFIG_OCFS2_FS_STATS
32+
33+DEFINE_MUTEX(la_debug_mutex);
34+
35+static int ocfs2_la_debug_open(struct inode *inode, struct file *file)
36+{
37+ file->private_data = inode->i_private;
38+ return 0;
39+}
40+
41+#define LA_DEBUG_BUF_SZ PAGE_CACHE_SIZE
42+#define LA_DEBUG_VER 1
43+static ssize_t ocfs2_la_debug_read(struct file *file, char __user *userbuf,
44+ size_t count, loff_t *ppos)
45+{
46+ struct ocfs2_super *osb = file->private_data;
47+ int written, ret;
48+ char *buf = osb->local_alloc_debug_buf;
49+
50+ mutex_lock(&la_debug_mutex);
51+ memset(buf, 0, LA_DEBUG_BUF_SZ);
52+
53+ written = snprintf(buf, LA_DEBUG_BUF_SZ,
54+ "0x%x\t0x%llx\t%u\t%u\t0x%x\n",
55+ LA_DEBUG_VER,
56+ (unsigned long long)osb->la_last_gd,
57+ osb->local_alloc_default_bits,
58+ osb->local_alloc_bits, osb->local_alloc_state);
59+
60+ ret = simple_read_from_buffer(userbuf, count, ppos, buf, written);
61+
62+ mutex_unlock(&la_debug_mutex);
63+ return ret;
64+}
65+
66+static const struct file_operations ocfs2_la_debug_fops = {
67+ .open = ocfs2_la_debug_open,
68+ .read = ocfs2_la_debug_read,
69+};
70+
71+static void ocfs2_init_la_debug(struct ocfs2_super *osb)
72+{
73+ osb->local_alloc_debug_buf = kmalloc(LA_DEBUG_BUF_SZ, GFP_NOFS);
74+ if (!osb->local_alloc_debug_buf)
75+ return;
76+
77+ osb->local_alloc_debug = debugfs_create_file("local_alloc_stats",
78+ S_IFREG|S_IRUSR,
79+ osb->osb_debug_root,
80+ osb,
81+ &ocfs2_la_debug_fops);
82+ if (!osb->local_alloc_debug) {
83+ kfree(osb->local_alloc_debug_buf);
84+ osb->local_alloc_debug_buf = NULL;
85+ }
86+}
87+
88+static void ocfs2_shutdown_la_debug(struct ocfs2_super *osb)
89+{
90+ if (osb->local_alloc_debug)
91+ debugfs_remove(osb->local_alloc_debug);
92+
93+ if (osb->local_alloc_debug_buf)
94+ kfree(osb->local_alloc_debug_buf);
95+
96+ osb->local_alloc_debug_buf = NULL;
97+ osb->local_alloc_debug = NULL;
98+}
99+#else /* CONFIG_OCFS2_FS_STATS */
100+static void ocfs2_init_la_debug(struct ocfs2_super *osb)
101+{
102+ return;
103+}
104+static void ocfs2_shutdown_la_debug(struct ocfs2_super *osb)
105+{
106+ return;
107+}
108+#endif
109+
110 static inline int ocfs2_la_state_enabled(struct ocfs2_super *osb)
111 {
112 return (osb->local_alloc_state == OCFS2_LA_THROTTLED ||
113@@ -146,6 +226,8 @@ int ocfs2_load_local_alloc(struct ocfs2_
114
115 mlog_entry_void();
116
117+ ocfs2_init_la_debug(osb);
118+
119 if (osb->local_alloc_bits == 0)
120 goto bail;
121
122@@ -218,6 +300,9 @@ bail:
123 if (inode)
124 iput(inode);
125
126+ if (status < 0)
127+ ocfs2_shutdown_la_debug(osb);
128+
129 mlog(0, "Local alloc window bits = %d\n", osb->local_alloc_bits);
130
131 mlog_exit(status);
132@@ -247,6 +332,8 @@ void ocfs2_shutdown_local_alloc(struct o
133 cancel_delayed_work(&osb->la_enable_wq);
134 flush_workqueue(ocfs2_wq);
135
136+ ocfs2_shutdown_la_debug(osb);
137+
138 if (osb->local_alloc_state == OCFS2_LA_UNUSED)
139 goto out;
140
141--- a/fs/ocfs2/ocfs2.h
142+++ b/fs/ocfs2/ocfs2.h
143@@ -281,6 +281,11 @@ struct ocfs2_super
144
145 u64 la_last_gd;
146
147+#ifdef CONFIG_OCFS2_FS_STATS
148+ struct dentry *local_alloc_debug;
149+ char *local_alloc_debug_buf;
150+#endif
151+
152 /* Next two fields are for local node slot recovery during
153 * mount. */
154 int dirty;