diff options
Diffstat (limited to 'fs/dlm/debug_fs.c')
-rw-r--r-- | fs/dlm/debug_fs.c | 103 |
1 files changed, 96 insertions, 7 deletions
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 1c9b08095f98..b969deef9ebb 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c | |||
@@ -344,6 +344,45 @@ static int print_format3(struct dlm_rsb *r, struct seq_file *s) | |||
344 | return rv; | 344 | return rv; |
345 | } | 345 | } |
346 | 346 | ||
347 | static int print_format4(struct dlm_rsb *r, struct seq_file *s) | ||
348 | { | ||
349 | int our_nodeid = dlm_our_nodeid(); | ||
350 | int print_name = 1; | ||
351 | int i, rv; | ||
352 | |||
353 | lock_rsb(r); | ||
354 | |||
355 | rv = seq_printf(s, "rsb %p %d %d %d %d %lu %lx %d ", | ||
356 | r, | ||
357 | r->res_nodeid, | ||
358 | r->res_master_nodeid, | ||
359 | r->res_dir_nodeid, | ||
360 | our_nodeid, | ||
361 | r->res_toss_time, | ||
362 | r->res_flags, | ||
363 | r->res_length); | ||
364 | if (rv) | ||
365 | goto out; | ||
366 | |||
367 | for (i = 0; i < r->res_length; i++) { | ||
368 | if (!isascii(r->res_name[i]) || !isprint(r->res_name[i])) | ||
369 | print_name = 0; | ||
370 | } | ||
371 | |||
372 | seq_printf(s, "%s", print_name ? "str " : "hex"); | ||
373 | |||
374 | for (i = 0; i < r->res_length; i++) { | ||
375 | if (print_name) | ||
376 | seq_printf(s, "%c", r->res_name[i]); | ||
377 | else | ||
378 | seq_printf(s, " %02x", (unsigned char)r->res_name[i]); | ||
379 | } | ||
380 | rv = seq_printf(s, "\n"); | ||
381 | out: | ||
382 | unlock_rsb(r); | ||
383 | return rv; | ||
384 | } | ||
385 | |||
347 | struct rsbtbl_iter { | 386 | struct rsbtbl_iter { |
348 | struct dlm_rsb *rsb; | 387 | struct dlm_rsb *rsb; |
349 | unsigned bucket; | 388 | unsigned bucket; |
@@ -382,6 +421,13 @@ static int table_seq_show(struct seq_file *seq, void *iter_ptr) | |||
382 | } | 421 | } |
383 | rv = print_format3(ri->rsb, seq); | 422 | rv = print_format3(ri->rsb, seq); |
384 | break; | 423 | break; |
424 | case 4: | ||
425 | if (ri->header) { | ||
426 | seq_printf(seq, "version 4 rsb 2\n"); | ||
427 | ri->header = 0; | ||
428 | } | ||
429 | rv = print_format4(ri->rsb, seq); | ||
430 | break; | ||
385 | } | 431 | } |
386 | 432 | ||
387 | return rv; | 433 | return rv; |
@@ -390,15 +436,18 @@ static int table_seq_show(struct seq_file *seq, void *iter_ptr) | |||
390 | static const struct seq_operations format1_seq_ops; | 436 | static const struct seq_operations format1_seq_ops; |
391 | static const struct seq_operations format2_seq_ops; | 437 | static const struct seq_operations format2_seq_ops; |
392 | static const struct seq_operations format3_seq_ops; | 438 | static const struct seq_operations format3_seq_ops; |
439 | static const struct seq_operations format4_seq_ops; | ||
393 | 440 | ||
394 | static void *table_seq_start(struct seq_file *seq, loff_t *pos) | 441 | static void *table_seq_start(struct seq_file *seq, loff_t *pos) |
395 | { | 442 | { |
443 | struct rb_root *tree; | ||
396 | struct rb_node *node; | 444 | struct rb_node *node; |
397 | struct dlm_ls *ls = seq->private; | 445 | struct dlm_ls *ls = seq->private; |
398 | struct rsbtbl_iter *ri; | 446 | struct rsbtbl_iter *ri; |
399 | struct dlm_rsb *r; | 447 | struct dlm_rsb *r; |
400 | loff_t n = *pos; | 448 | loff_t n = *pos; |
401 | unsigned bucket, entry; | 449 | unsigned bucket, entry; |
450 | int toss = (seq->op == &format4_seq_ops); | ||
402 | 451 | ||
403 | bucket = n >> 32; | 452 | bucket = n >> 32; |
404 | entry = n & ((1LL << 32) - 1); | 453 | entry = n & ((1LL << 32) - 1); |
@@ -417,11 +466,14 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos) | |||
417 | ri->format = 2; | 466 | ri->format = 2; |
418 | if (seq->op == &format3_seq_ops) | 467 | if (seq->op == &format3_seq_ops) |
419 | ri->format = 3; | 468 | ri->format = 3; |
469 | if (seq->op == &format4_seq_ops) | ||
470 | ri->format = 4; | ||
471 | |||
472 | tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep; | ||
420 | 473 | ||
421 | spin_lock(&ls->ls_rsbtbl[bucket].lock); | 474 | spin_lock(&ls->ls_rsbtbl[bucket].lock); |
422 | if (!RB_EMPTY_ROOT(&ls->ls_rsbtbl[bucket].keep)) { | 475 | if (!RB_EMPTY_ROOT(tree)) { |
423 | for (node = rb_first(&ls->ls_rsbtbl[bucket].keep); node; | 476 | for (node = rb_first(tree); node; node = rb_next(node)) { |
424 | node = rb_next(node)) { | ||
425 | r = rb_entry(node, struct dlm_rsb, res_hashnode); | 477 | r = rb_entry(node, struct dlm_rsb, res_hashnode); |
426 | if (!entry--) { | 478 | if (!entry--) { |
427 | dlm_hold_rsb(r); | 479 | dlm_hold_rsb(r); |
@@ -449,10 +501,11 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos) | |||
449 | kfree(ri); | 501 | kfree(ri); |
450 | return NULL; | 502 | return NULL; |
451 | } | 503 | } |
504 | tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep; | ||
452 | 505 | ||
453 | spin_lock(&ls->ls_rsbtbl[bucket].lock); | 506 | spin_lock(&ls->ls_rsbtbl[bucket].lock); |
454 | if (!RB_EMPTY_ROOT(&ls->ls_rsbtbl[bucket].keep)) { | 507 | if (!RB_EMPTY_ROOT(tree)) { |
455 | node = rb_first(&ls->ls_rsbtbl[bucket].keep); | 508 | node = rb_first(tree); |
456 | r = rb_entry(node, struct dlm_rsb, res_hashnode); | 509 | r = rb_entry(node, struct dlm_rsb, res_hashnode); |
457 | dlm_hold_rsb(r); | 510 | dlm_hold_rsb(r); |
458 | ri->rsb = r; | 511 | ri->rsb = r; |
@@ -469,10 +522,12 @@ static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos) | |||
469 | { | 522 | { |
470 | struct dlm_ls *ls = seq->private; | 523 | struct dlm_ls *ls = seq->private; |
471 | struct rsbtbl_iter *ri = iter_ptr; | 524 | struct rsbtbl_iter *ri = iter_ptr; |
525 | struct rb_root *tree; | ||
472 | struct rb_node *next; | 526 | struct rb_node *next; |
473 | struct dlm_rsb *r, *rp; | 527 | struct dlm_rsb *r, *rp; |
474 | loff_t n = *pos; | 528 | loff_t n = *pos; |
475 | unsigned bucket; | 529 | unsigned bucket; |
530 | int toss = (seq->op == &format4_seq_ops); | ||
476 | 531 | ||
477 | bucket = n >> 32; | 532 | bucket = n >> 32; |
478 | 533 | ||
@@ -511,10 +566,11 @@ static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos) | |||
511 | kfree(ri); | 566 | kfree(ri); |
512 | return NULL; | 567 | return NULL; |
513 | } | 568 | } |
569 | tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep; | ||
514 | 570 | ||
515 | spin_lock(&ls->ls_rsbtbl[bucket].lock); | 571 | spin_lock(&ls->ls_rsbtbl[bucket].lock); |
516 | if (!RB_EMPTY_ROOT(&ls->ls_rsbtbl[bucket].keep)) { | 572 | if (!RB_EMPTY_ROOT(tree)) { |
517 | next = rb_first(&ls->ls_rsbtbl[bucket].keep); | 573 | next = rb_first(tree); |
518 | r = rb_entry(next, struct dlm_rsb, res_hashnode); | 574 | r = rb_entry(next, struct dlm_rsb, res_hashnode); |
519 | dlm_hold_rsb(r); | 575 | dlm_hold_rsb(r); |
520 | ri->rsb = r; | 576 | ri->rsb = r; |
@@ -558,9 +614,17 @@ static const struct seq_operations format3_seq_ops = { | |||
558 | .show = table_seq_show, | 614 | .show = table_seq_show, |
559 | }; | 615 | }; |
560 | 616 | ||
617 | static const struct seq_operations format4_seq_ops = { | ||
618 | .start = table_seq_start, | ||
619 | .next = table_seq_next, | ||
620 | .stop = table_seq_stop, | ||
621 | .show = table_seq_show, | ||
622 | }; | ||
623 | |||
561 | static const struct file_operations format1_fops; | 624 | static const struct file_operations format1_fops; |
562 | static const struct file_operations format2_fops; | 625 | static const struct file_operations format2_fops; |
563 | static const struct file_operations format3_fops; | 626 | static const struct file_operations format3_fops; |
627 | static const struct file_operations format4_fops; | ||
564 | 628 | ||
565 | static int table_open(struct inode *inode, struct file *file) | 629 | static int table_open(struct inode *inode, struct file *file) |
566 | { | 630 | { |
@@ -573,6 +637,8 @@ static int table_open(struct inode *inode, struct file *file) | |||
573 | ret = seq_open(file, &format2_seq_ops); | 637 | ret = seq_open(file, &format2_seq_ops); |
574 | else if (file->f_op == &format3_fops) | 638 | else if (file->f_op == &format3_fops) |
575 | ret = seq_open(file, &format3_seq_ops); | 639 | ret = seq_open(file, &format3_seq_ops); |
640 | else if (file->f_op == &format4_fops) | ||
641 | ret = seq_open(file, &format4_seq_ops); | ||
576 | 642 | ||
577 | if (ret) | 643 | if (ret) |
578 | return ret; | 644 | return ret; |
@@ -606,6 +672,14 @@ static const struct file_operations format3_fops = { | |||
606 | .release = seq_release | 672 | .release = seq_release |
607 | }; | 673 | }; |
608 | 674 | ||
675 | static const struct file_operations format4_fops = { | ||
676 | .owner = THIS_MODULE, | ||
677 | .open = table_open, | ||
678 | .read = seq_read, | ||
679 | .llseek = seq_lseek, | ||
680 | .release = seq_release | ||
681 | }; | ||
682 | |||
609 | /* | 683 | /* |
610 | * dump lkb's on the ls_waiters list | 684 | * dump lkb's on the ls_waiters list |
611 | */ | 685 | */ |
@@ -652,6 +726,8 @@ void dlm_delete_debug_file(struct dlm_ls *ls) | |||
652 | debugfs_remove(ls->ls_debug_locks_dentry); | 726 | debugfs_remove(ls->ls_debug_locks_dentry); |
653 | if (ls->ls_debug_all_dentry) | 727 | if (ls->ls_debug_all_dentry) |
654 | debugfs_remove(ls->ls_debug_all_dentry); | 728 | debugfs_remove(ls->ls_debug_all_dentry); |
729 | if (ls->ls_debug_toss_dentry) | ||
730 | debugfs_remove(ls->ls_debug_toss_dentry); | ||
655 | } | 731 | } |
656 | 732 | ||
657 | int dlm_create_debug_file(struct dlm_ls *ls) | 733 | int dlm_create_debug_file(struct dlm_ls *ls) |
@@ -694,6 +770,19 @@ int dlm_create_debug_file(struct dlm_ls *ls) | |||
694 | if (!ls->ls_debug_all_dentry) | 770 | if (!ls->ls_debug_all_dentry) |
695 | goto fail; | 771 | goto fail; |
696 | 772 | ||
773 | /* format 4 */ | ||
774 | |||
775 | memset(name, 0, sizeof(name)); | ||
776 | snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_toss", ls->ls_name); | ||
777 | |||
778 | ls->ls_debug_toss_dentry = debugfs_create_file(name, | ||
779 | S_IFREG | S_IRUGO, | ||
780 | dlm_root, | ||
781 | ls, | ||
782 | &format4_fops); | ||
783 | if (!ls->ls_debug_toss_dentry) | ||
784 | goto fail; | ||
785 | |||
697 | memset(name, 0, sizeof(name)); | 786 | memset(name, 0, sizeof(name)); |
698 | snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name); | 787 | snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name); |
699 | 788 | ||