1 From: David Teigland <teigland@redhat.com>
2 commit d022509d1c54be4918e7fc8f1195ee8c392e9a57
3 Author: David Teigland <teigland@redhat.com>
4 Date: Tue Dec 16 14:53:23 2008 -0600
5 Subject: dlm: add new debugfs entry
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
12 Signed-off-by: David Teigland <teigland@redhat.com>
13 Signed-off-by: Coly Li <coly.li@suse.de>
16 fs/dlm/debug_fs.c | 296 +++++++++++++++++++++++++++++++++++++++++---------
17 fs/dlm/dlm_internal.h | 1
18 2 files changed, 247 insertions(+), 50 deletions(-)
20 --- a/fs/dlm/debug_fs.c
21 +++ b/fs/dlm/debug_fs.c
23 /******************************************************************************
24 *******************************************************************************
26 -** Copyright (C) 2005 Red Hat, Inc. All rights reserved.
27 +** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
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;
39 struct list_head *next;
40 @@ -60,8 +60,8 @@ static char *print_lockmode(int mode)
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)
49 seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode));
51 @@ -83,7 +83,7 @@ static void print_resource_lock(struct s
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)
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);
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);
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);
77 if (list_empty(&res->res_lookup))
79 @@ -160,7 +160,8 @@ static int print_resource(struct dlm_rsb
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,
89 @@ -193,20 +194,108 @@ static void print_lock(struct seq_file *
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)
100 list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue)
101 - print_lock(s, lkb, r);
102 + print_format2_lock(s, lkb, r);
104 list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue)
105 - print_lock(s, lkb, r);
106 + print_format2_lock(s, lkb, r);
108 list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue)
109 - print_lock(s, lkb, r);
110 + print_format2_lock(s, lkb, r);
116 +static void print_format3_lock(struct seq_file *s, struct dlm_lkb *lkb,
121 + if (lkb->lkb_flags & DLM_IFL_USER) {
123 + xid = lkb->lkb_ua->xid;
126 + seq_printf(s, "lkb %x %d %x %u %llu %x %x %d %d %d %d %d %d %u %llu %llu\n",
131 + (unsigned long long)xid,
139 + lkb->lkb_wait_type,
141 + (unsigned long long)ktime_to_ns(lkb->lkb_timestamp),
142 + (unsigned long long)ktime_to_ns(lkb->lkb_time_bast));
145 +static int print_format3(struct dlm_rsb *r, struct seq_file *s)
147 + struct dlm_lkb *lkb;
148 + int i, lvblen = r->res_ls->ls_lvblen;
149 + int print_name = 1;
153 + seq_printf(s, "rsb %p %d %x %lx %d %d %u %d ",
158 + !list_empty(&r->res_root_list),
159 + !list_empty(&r->res_recover_list),
160 + r->res_recover_locks_count,
163 + for (i = 0; i < r->res_length; i++) {
164 + if (!isascii(r->res_name[i]) || !isprint(r->res_name[i]))
168 + seq_printf(s, "%s", print_name ? "str " : "hex");
170 + for (i = 0; i < r->res_length; i++) {
172 + seq_printf(s, "%c", r->res_name[i]);
174 + seq_printf(s, " %02x", (unsigned char)r->res_name[i]);
176 + seq_printf(s, "\n");
178 + if (!r->res_lvbptr)
181 + seq_printf(s, "lvb %u %d", r->res_lvbseq, lvblen);
183 + for (i = 0; i < lvblen; i++)
184 + seq_printf(s, " %02x", (unsigned char)r->res_lvbptr[i]);
185 + seq_printf(s, "\n");
188 + list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue)
189 + print_format3_lock(s, lkb, 0);
191 + list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue)
192 + print_format3_lock(s, lkb, 0);
194 + list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue)
195 + print_format3_lock(s, lkb, 0);
197 + list_for_each_entry(lkb, &r->res_lookup, lkb_rsb_lookup)
198 + print_format3_lock(s, lkb, 1);
202 @@ -231,7 +320,7 @@ static int rsb_iter_next(struct rsb_iter
205 read_unlock(&ls->ls_rsbtbl[i].lock);
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);
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
226 if (rsb_iter_next(ri)) {
228 @@ -325,16 +415,26 @@ static int rsb_seq_show(struct seq_file
230 struct rsb_iter *ri = iter_ptr;
233 + switch (ri->format) {
235 + print_format1(ri->rsb, file);
239 - seq_printf(file, "id nodeid remid pid xid exflags flags "
240 - "sts grmode rqmode time_ms r_nodeid "
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");
247 - print_locks(ri->rsb, file);
249 - print_resource(ri->rsb, file);
250 + print_format2(ri->rsb, file);
254 + seq_printf(file, "version rsb 1.1 lvb 1.1 lkb 1.1\n");
257 + print_format3(ri->rsb, file);
262 @@ -385,7 +485,7 @@ static struct rsb_iter *locks_iter_init(
271 @@ -448,6 +548,84 @@ static const struct file_operations lock
275 + * Dump all rsb/lvb/lkb state in compact listing, more complete than _locks
276 + * This can replace both formats 1 and 2 eventually.
279 +static struct rsb_iter *all_iter_init(struct dlm_ls *ls, loff_t *pos)
281 + struct rsb_iter *ri;
283 + ri = kzalloc(sizeof *ri, GFP_KERNEL);
295 + if (rsb_iter_next(ri)) {
303 +static void *all_seq_start(struct seq_file *file, loff_t *pos)
305 + struct rsb_iter *ri;
308 + ri = all_iter_init(file->private, pos);
313 + if (rsb_iter_next(ri)) {
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,
329 +static int all_open(struct inode *inode, struct file *file)
331 + struct seq_file *seq;
334 + ret = seq_open(file, &all_seq_ops);
338 + seq = file->private_data;
339 + seq->private = inode->i_private;
344 +static const struct file_operations all_fops = {
345 + .owner = THIS_MODULE,
348 + .llseek = seq_lseek,
349 + .release = seq_release
353 * dump lkb's on the ls_waiters list
356 @@ -489,30 +667,33 @@ static const struct file_operations wait
360 +void dlm_delete_debug_file(struct dlm_ls *ls)
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);
372 int dlm_create_debug_file(struct dlm_ls *ls)
374 char name[DLM_LOCKSPACE_LEN+8];
378 ls->ls_debug_rsb_dentry = debugfs_create_file(ls->ls_name,
383 if (!ls->ls_debug_rsb_dentry)
387 - memset(name, 0, sizeof(name));
388 - snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name);
390 - ls->ls_debug_waiters_dentry = debugfs_create_file(name,
395 - if (!ls->ls_debug_waiters_dentry) {
396 - debugfs_remove(ls->ls_debug_rsb_dentry);
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
407 - if (!ls->ls_debug_locks_dentry) {
408 - debugfs_remove(ls->ls_debug_waiters_dentry);
409 - debugfs_remove(ls->ls_debug_rsb_dentry);
412 + if (!ls->ls_debug_locks_dentry)
417 + memset(name, 0, sizeof(name));
418 + snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_all", ls->ls_name);
420 + ls->ls_debug_all_dentry = debugfs_create_file(name,
425 + if (!ls->ls_debug_all_dentry)
428 + memset(name, 0, sizeof(name));
429 + snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name);
431 + ls->ls_debug_waiters_dentry = debugfs_create_file(name,
436 + if (!ls->ls_debug_waiters_dentry)
442 -void dlm_delete_debug_file(struct dlm_ls *ls)
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);
451 + dlm_delete_debug_file(ls);
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 */
464 wait_queue_head_t ls_uevent_wait; /* user part of join/leave */
465 int ls_uevent_result;