]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.suse/ocfs2-track-local-alloc-state-via-debugfs.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / ocfs2-track-local-alloc-state-via-debugfs.patch
1 From: Mark Fasheh <mfasheh@suse.com>
2 Subject: ocfs2: track local alloc state via debugfs
3 Patch-mainline: 2.6.28
4
5 A per-mount debugfs file, "local_alloc" is created which when read will
6 expose live state of the nodes local alloc file. Performance impact is
7 minimal, only a bit of memory overhead per mount point. Still, the code is
8 hidden behind CONFIG_OCFS2_FS_STATS. This feature will help us debug
9 local alloc performance problems on a live system.
10
11 Signed-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;