]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/dlm-add-new-debugfs-entry.patch
Imported linux-2.6.27.39 suse/xen patches.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / dlm-add-new-debugfs-entry.patch
CommitLineData
2cb7cef9
BS
1From: David Teigland <teigland@redhat.com>
2commit d022509d1c54be4918e7fc8f1195ee8c392e9a57
3Author: David Teigland <teigland@redhat.com>
4Date: Tue Dec 16 14:53:23 2008 -0600
5Subject: dlm: add new debugfs entry
6
7 The new debugfs entry dumps all rsb and lkb structures, and includes
8 a lot more information than has been available before. This includes
9 the new timestamps added by a previous patch for debugging callback
10 issues.
11
12Signed-off-by: David Teigland <teigland@redhat.com>
13Signed-off-by: Coly Li <coly.li@suse.de>
14
15---
16 fs/dlm/debug_fs.c | 296 +++++++++++++++++++++++++++++++++++++++++---------
17 fs/dlm/dlm_internal.h | 1
18 2 files changed, 247 insertions(+), 50 deletions(-)
19
20--- a/fs/dlm/debug_fs.c
21+++ b/fs/dlm/debug_fs.c
22@@ -1,7 +1,7 @@
23 /******************************************************************************
24 *******************************************************************************
25 **
26-** Copyright (C) 2005 Red Hat, Inc. All rights reserved.
27+** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
28 **
29 ** This copyrighted material is made available to anyone wishing to use,
30 ** modify, copy, or redistribute it subject to the terms and conditions
31@@ -27,7 +27,7 @@ static struct dentry *dlm_root;
32
33 struct rsb_iter {
34 int entry;
35- int locks;
36+ int format;
37 int header;
38 struct dlm_ls *ls;
39 struct list_head *next;
40@@ -60,8 +60,8 @@ static char *print_lockmode(int mode)
41 }
42 }
43
44-static void print_resource_lock(struct seq_file *s, struct dlm_lkb *lkb,
45- struct dlm_rsb *res)
46+static void print_format1_lock(struct seq_file *s, struct dlm_lkb *lkb,
47+ struct dlm_rsb *res)
48 {
49 seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode));
50
51@@ -83,7 +83,7 @@ static void print_resource_lock(struct s
52 seq_printf(s, "\n");
53 }
54
55-static int print_resource(struct dlm_rsb *res, struct seq_file *s)
56+static int print_format1(struct dlm_rsb *res, struct seq_file *s)
57 {
58 struct dlm_lkb *lkb;
59 int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list;
60@@ -134,15 +134,15 @@ static int print_resource(struct dlm_rsb
61 /* Print the locks attached to this resource */
62 seq_printf(s, "Granted Queue\n");
63 list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue)
64- print_resource_lock(s, lkb, res);
65+ print_format1_lock(s, lkb, res);
66
67 seq_printf(s, "Conversion Queue\n");
68 list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue)
69- print_resource_lock(s, lkb, res);
70+ print_format1_lock(s, lkb, res);
71
72 seq_printf(s, "Waiting Queue\n");
73 list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue)
74- print_resource_lock(s, lkb, res);
75+ print_format1_lock(s, lkb, res);
76
77 if (list_empty(&res->res_lookup))
78 goto out;
79@@ -160,7 +160,8 @@ static int print_resource(struct dlm_rsb
80 return 0;
81 }
82
83-static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r)
84+static void print_format2_lock(struct seq_file *s, struct dlm_lkb *lkb,
85+ struct dlm_rsb *r)
86 {
87 u64 xid = 0;
88 u64 us;
89@@ -193,20 +194,108 @@ static void print_lock(struct seq_file *
90 r->res_name);
91 }
92
93-static int print_locks(struct dlm_rsb *r, struct seq_file *s)
94+static int print_format2(struct dlm_rsb *r, struct seq_file *s)
95 {
96 struct dlm_lkb *lkb;
97
98 lock_rsb(r);
99
100 list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue)
101- print_lock(s, lkb, r);
102+ print_format2_lock(s, lkb, r);
103
104 list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue)
105- print_lock(s, lkb, r);
106+ print_format2_lock(s, lkb, r);
107
108 list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue)
109- print_lock(s, lkb, r);
110+ print_format2_lock(s, lkb, r);
111+
112+ unlock_rsb(r);
113+ return 0;
114+}
115+
116+static void print_format3_lock(struct seq_file *s, struct dlm_lkb *lkb,
117+ int rsb_lookup)
118+{
119+ u64 xid = 0;
120+
121+ if (lkb->lkb_flags & DLM_IFL_USER) {
122+ if (lkb->lkb_ua)
123+ xid = lkb->lkb_ua->xid;
124+ }
125+
126+ seq_printf(s, "lkb %x %d %x %u %llu %x %x %d %d %d %d %d %d %u %llu %llu\n",
127+ lkb->lkb_id,
128+ lkb->lkb_nodeid,
129+ lkb->lkb_remid,
130+ lkb->lkb_ownpid,
131+ (unsigned long long)xid,
132+ lkb->lkb_exflags,
133+ lkb->lkb_flags,
134+ lkb->lkb_status,
135+ lkb->lkb_grmode,
136+ lkb->lkb_rqmode,
137+ lkb->lkb_highbast,
138+ rsb_lookup,
139+ lkb->lkb_wait_type,
140+ lkb->lkb_lvbseq,
141+ (unsigned long long)ktime_to_ns(lkb->lkb_timestamp),
142+ (unsigned long long)ktime_to_ns(lkb->lkb_time_bast));
143+}
144+
145+static int print_format3(struct dlm_rsb *r, struct seq_file *s)
146+{
147+ struct dlm_lkb *lkb;
148+ int i, lvblen = r->res_ls->ls_lvblen;
149+ int print_name = 1;
150+
151+ lock_rsb(r);
152+
153+ seq_printf(s, "rsb %p %d %x %lx %d %d %u %d ",
154+ r,
155+ r->res_nodeid,
156+ r->res_first_lkid,
157+ r->res_flags,
158+ !list_empty(&r->res_root_list),
159+ !list_empty(&r->res_recover_list),
160+ r->res_recover_locks_count,
161+ r->res_length);
162+
163+ for (i = 0; i < r->res_length; i++) {
164+ if (!isascii(r->res_name[i]) || !isprint(r->res_name[i]))
165+ print_name = 0;
166+ }
167+
168+ seq_printf(s, "%s", print_name ? "str " : "hex");
169+
170+ for (i = 0; i < r->res_length; i++) {
171+ if (print_name)
172+ seq_printf(s, "%c", r->res_name[i]);
173+ else
174+ seq_printf(s, " %02x", (unsigned char)r->res_name[i]);
175+ }
176+ seq_printf(s, "\n");
177+
178+ if (!r->res_lvbptr)
179+ goto do_locks;
180+
181+ seq_printf(s, "lvb %u %d", r->res_lvbseq, lvblen);
182+
183+ for (i = 0; i < lvblen; i++)
184+ seq_printf(s, " %02x", (unsigned char)r->res_lvbptr[i]);
185+ seq_printf(s, "\n");
186+
187+ do_locks:
188+ list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue)
189+ print_format3_lock(s, lkb, 0);
190+
191+ list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue)
192+ print_format3_lock(s, lkb, 0);
193+
194+ list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue)
195+ print_format3_lock(s, lkb, 0);
196+
197+ list_for_each_entry(lkb, &r->res_lookup, lkb_rsb_lookup)
198+ print_format3_lock(s, lkb, 1);
199
200 unlock_rsb(r);
201 return 0;
202@@ -231,7 +320,7 @@ static int rsb_iter_next(struct rsb_iter
203 break;
204 }
205 read_unlock(&ls->ls_rsbtbl[i].lock);
206- }
207+ }
208 ri->entry = i;
209
210 if (ri->entry >= ls->ls_rsbtbl_size)
211@@ -248,7 +337,7 @@ static int rsb_iter_next(struct rsb_iter
212 read_unlock(&ls->ls_rsbtbl[i].lock);
213 dlm_put_rsb(old);
214 goto top;
215- }
216+ }
217 ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
218 dlm_hold_rsb(ri->rsb);
219 read_unlock(&ls->ls_rsbtbl[i].lock);
220@@ -274,6 +363,7 @@ static struct rsb_iter *rsb_iter_init(st
221 ri->ls = ls;
222 ri->entry = 0;
223 ri->next = NULL;
224+ ri->format = 1;
225
226 if (rsb_iter_next(ri)) {
227 rsb_iter_free(ri);
228@@ -325,16 +415,26 @@ static int rsb_seq_show(struct seq_file
229 {
230 struct rsb_iter *ri = iter_ptr;
231
232- if (ri->locks) {
233+ switch (ri->format) {
234+ case 1:
235+ print_format1(ri->rsb, file);
236+ break;
237+ case 2:
238 if (ri->header) {
239- seq_printf(file, "id nodeid remid pid xid exflags flags "
240- "sts grmode rqmode time_ms r_nodeid "
241- "r_len r_name\n");
242+ seq_printf(file, "id nodeid remid pid xid exflags "
243+ "flags sts grmode rqmode time_ms "
244+ "r_nodeid r_len r_name\n");
245 ri->header = 0;
246 }
247- print_locks(ri->rsb, file);
248- } else {
249- print_resource(ri->rsb, file);
250+ print_format2(ri->rsb, file);
251+ break;
252+ case 3:
253+ if (ri->header) {
254+ seq_printf(file, "version rsb 1.1 lvb 1.1 lkb 1.1\n");
255+ ri->header = 0;
256+ }
257+ print_format3(ri->rsb, file);
258+ break;
259 }
260
261 return 0;
262@@ -385,7 +485,7 @@ static struct rsb_iter *locks_iter_init(
263 ri->ls = ls;
264 ri->entry = 0;
265 ri->next = NULL;
266- ri->locks = 1;
267+ ri->format = 2;
268
269 if (*pos == 0)
270 ri->header = 1;
271@@ -448,6 +548,84 @@ static const struct file_operations lock
272 };
273
274 /*
275+ * Dump all rsb/lvb/lkb state in compact listing, more complete than _locks
276+ * This can replace both formats 1 and 2 eventually.
277+ */
278+
279+static struct rsb_iter *all_iter_init(struct dlm_ls *ls, loff_t *pos)
280+{
281+ struct rsb_iter *ri;
282+
283+ ri = kzalloc(sizeof *ri, GFP_KERNEL);
284+ if (!ri)
285+ return NULL;
286+
287+ ri->ls = ls;
288+ ri->entry = 0;
289+ ri->next = NULL;
290+ ri->format = 3;
291+
292+ if (*pos == 0)
293+ ri->header = 1;
294+
295+ if (rsb_iter_next(ri)) {
296+ rsb_iter_free(ri);
297+ return NULL;
298+ }
299+
300+ return ri;
301+}
302+
303+static void *all_seq_start(struct seq_file *file, loff_t *pos)
304+{
305+ struct rsb_iter *ri;
306+ loff_t n = *pos;
307+
308+ ri = all_iter_init(file->private, pos);
309+ if (!ri)
310+ return NULL;
311+
312+ while (n--) {
313+ if (rsb_iter_next(ri)) {
314+ rsb_iter_free(ri);
315+ return NULL;
316+ }
317+ }
318+
319+ return ri;
320+}
321+
322+static struct seq_operations all_seq_ops = {
323+ .start = all_seq_start,
324+ .next = rsb_seq_next,
325+ .stop = rsb_seq_stop,
326+ .show = rsb_seq_show,
327+};
328+
329+static int all_open(struct inode *inode, struct file *file)
330+{
331+ struct seq_file *seq;
332+ int ret;
333+
334+ ret = seq_open(file, &all_seq_ops);
335+ if (ret)
336+ return ret;
337+
338+ seq = file->private_data;
339+ seq->private = inode->i_private;
340+
341+ return 0;
342+}
343+
344+static const struct file_operations all_fops = {
345+ .owner = THIS_MODULE,
346+ .open = all_open,
347+ .read = seq_read,
348+ .llseek = seq_lseek,
349+ .release = seq_release
350+};
351+
352+/*
353 * dump lkb's on the ls_waiters list
354 */
355
356@@ -489,30 +667,33 @@ static const struct file_operations wait
357 .read = waiters_read
358 };
359
360+void dlm_delete_debug_file(struct dlm_ls *ls)
361+{
362+ if (ls->ls_debug_rsb_dentry)
363+ debugfs_remove(ls->ls_debug_rsb_dentry);
364+ if (ls->ls_debug_waiters_dentry)
365+ debugfs_remove(ls->ls_debug_waiters_dentry);
366+ if (ls->ls_debug_locks_dentry)
367+ debugfs_remove(ls->ls_debug_locks_dentry);
368+ if (ls->ls_debug_all_dentry)
369+ debugfs_remove(ls->ls_debug_all_dentry);
370+}
371+
372 int dlm_create_debug_file(struct dlm_ls *ls)
373 {
374 char name[DLM_LOCKSPACE_LEN+8];
375
376+ /* format 1 */
377+
378 ls->ls_debug_rsb_dentry = debugfs_create_file(ls->ls_name,
379 S_IFREG | S_IRUGO,
380 dlm_root,
381 ls,
382 &rsb_fops);
383 if (!ls->ls_debug_rsb_dentry)
384- return -ENOMEM;
385+ goto fail;
386
387- memset(name, 0, sizeof(name));
388- snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name);
389-
390- ls->ls_debug_waiters_dentry = debugfs_create_file(name,
391- S_IFREG | S_IRUGO,
392- dlm_root,
393- ls,
394- &waiters_fops);
395- if (!ls->ls_debug_waiters_dentry) {
396- debugfs_remove(ls->ls_debug_rsb_dentry);
397- return -ENOMEM;
398- }
399+ /* format 2 */
400
401 memset(name, 0, sizeof(name));
402 snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_locks", ls->ls_name);
403@@ -522,23 +703,38 @@ int dlm_create_debug_file(struct dlm_ls
404 dlm_root,
405 ls,
406 &locks_fops);
407- if (!ls->ls_debug_locks_dentry) {
408- debugfs_remove(ls->ls_debug_waiters_dentry);
409- debugfs_remove(ls->ls_debug_rsb_dentry);
410- return -ENOMEM;
411- }
412+ if (!ls->ls_debug_locks_dentry)
413+ goto fail;
414+
415+ /* format 3 */
416+
417+ memset(name, 0, sizeof(name));
418+ snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_all", ls->ls_name);
419+
420+ ls->ls_debug_all_dentry = debugfs_create_file(name,
421+ S_IFREG | S_IRUGO,
422+ dlm_root,
423+ ls,
424+ &all_fops);
425+ if (!ls->ls_debug_all_dentry)
426+ goto fail;
427+
428+ memset(name, 0, sizeof(name));
429+ snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name);
430+
431+ ls->ls_debug_waiters_dentry = debugfs_create_file(name,
432+ S_IFREG | S_IRUGO,
433+ dlm_root,
434+ ls,
435+ &waiters_fops);
436+ if (!ls->ls_debug_waiters_dentry)
437+ goto fail;
438
439 return 0;
440-}
441
442-void dlm_delete_debug_file(struct dlm_ls *ls)
443-{
444- if (ls->ls_debug_rsb_dentry)
445- debugfs_remove(ls->ls_debug_rsb_dentry);
446- if (ls->ls_debug_waiters_dentry)
447- debugfs_remove(ls->ls_debug_waiters_dentry);
448- if (ls->ls_debug_locks_dentry)
449- debugfs_remove(ls->ls_debug_locks_dentry);
450+ fail:
451+ dlm_delete_debug_file(ls);
452+ return -ENOMEM;
453 }
454
455 int __init dlm_register_debugfs(void)
456--- a/fs/dlm/dlm_internal.h
457+++ b/fs/dlm/dlm_internal.h
458@@ -481,6 +481,7 @@ struct dlm_ls {
459 struct dentry *ls_debug_rsb_dentry; /* debugfs */
460 struct dentry *ls_debug_waiters_dentry; /* debugfs */
461 struct dentry *ls_debug_locks_dentry; /* debugfs */
462+ struct dentry *ls_debug_all_dentry; /* debugfs */
463
464 wait_queue_head_t ls_uevent_wait; /* user part of join/leave */
465 int ls_uevent_result;