]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.suse/dlm-add-new-debugfs-entry.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / dlm-add-new-debugfs-entry.patch
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
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
12 Signed-off-by: David Teigland <teigland@redhat.com>
13 Signed-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;