root/fs/dlm/debug_fs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. print_lockmode
  2. print_format1_lock
  3. print_format1
  4. print_format2_lock
  5. print_format2
  6. print_format3_lock
  7. print_format3
  8. print_format4
  9. table_seq_show
  10. table_seq_start
  11. table_seq_next
  12. table_seq_stop
  13. table_open1
  14. table_open2
  15. table_open3
  16. table_open4
  17. waiters_read
  18. dlm_delete_debug_file
  19. dlm_create_debug_file
  20. dlm_register_debugfs
  21. dlm_unregister_debugfs

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /******************************************************************************
   3 *******************************************************************************
   4 **
   5 **  Copyright (C) 2005-2009 Red Hat, Inc.  All rights reserved.
   6 **
   7 **
   8 *******************************************************************************
   9 ******************************************************************************/
  10 
  11 #include <linux/pagemap.h>
  12 #include <linux/seq_file.h>
  13 #include <linux/init.h>
  14 #include <linux/ctype.h>
  15 #include <linux/debugfs.h>
  16 #include <linux/slab.h>
  17 
  18 #include "dlm_internal.h"
  19 #include "lock.h"
  20 
  21 #define DLM_DEBUG_BUF_LEN 4096
  22 static char debug_buf[DLM_DEBUG_BUF_LEN];
  23 static struct mutex debug_buf_lock;
  24 
  25 static struct dentry *dlm_root;
  26 
  27 static char *print_lockmode(int mode)
  28 {
  29         switch (mode) {
  30         case DLM_LOCK_IV:
  31                 return "--";
  32         case DLM_LOCK_NL:
  33                 return "NL";
  34         case DLM_LOCK_CR:
  35                 return "CR";
  36         case DLM_LOCK_CW:
  37                 return "CW";
  38         case DLM_LOCK_PR:
  39                 return "PR";
  40         case DLM_LOCK_PW:
  41                 return "PW";
  42         case DLM_LOCK_EX:
  43                 return "EX";
  44         default:
  45                 return "??";
  46         }
  47 }
  48 
  49 static void print_format1_lock(struct seq_file *s, struct dlm_lkb *lkb,
  50                                struct dlm_rsb *res)
  51 {
  52         seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode));
  53 
  54         if (lkb->lkb_status == DLM_LKSTS_CONVERT ||
  55             lkb->lkb_status == DLM_LKSTS_WAITING)
  56                 seq_printf(s, " (%s)", print_lockmode(lkb->lkb_rqmode));
  57 
  58         if (lkb->lkb_nodeid) {
  59                 if (lkb->lkb_nodeid != res->res_nodeid)
  60                         seq_printf(s, " Remote: %3d %08x", lkb->lkb_nodeid,
  61                                    lkb->lkb_remid);
  62                 else
  63                         seq_printf(s, " Master:     %08x", lkb->lkb_remid);
  64         }
  65 
  66         if (lkb->lkb_wait_type)
  67                 seq_printf(s, " wait_type: %d", lkb->lkb_wait_type);
  68 
  69         seq_putc(s, '\n');
  70 }
  71 
  72 static void print_format1(struct dlm_rsb *res, struct seq_file *s)
  73 {
  74         struct dlm_lkb *lkb;
  75         int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list;
  76 
  77         lock_rsb(res);
  78 
  79         seq_printf(s, "\nResource %p Name (len=%d) \"", res, res->res_length);
  80 
  81         for (i = 0; i < res->res_length; i++) {
  82                 if (isprint(res->res_name[i]))
  83                         seq_printf(s, "%c", res->res_name[i]);
  84                 else
  85                         seq_printf(s, "%c", '.');
  86         }
  87 
  88         if (res->res_nodeid > 0)
  89                 seq_printf(s, "\"\nLocal Copy, Master is node %d\n",
  90                            res->res_nodeid);
  91         else if (res->res_nodeid == 0)
  92                 seq_puts(s, "\"\nMaster Copy\n");
  93         else if (res->res_nodeid == -1)
  94                 seq_printf(s, "\"\nLooking up master (lkid %x)\n",
  95                            res->res_first_lkid);
  96         else
  97                 seq_printf(s, "\"\nInvalid master %d\n", res->res_nodeid);
  98         if (seq_has_overflowed(s))
  99                 goto out;
 100 
 101         /* Print the LVB: */
 102         if (res->res_lvbptr) {
 103                 seq_puts(s, "LVB: ");
 104                 for (i = 0; i < lvblen; i++) {
 105                         if (i == lvblen / 2)
 106                                 seq_puts(s, "\n     ");
 107                         seq_printf(s, "%02x ",
 108                                    (unsigned char) res->res_lvbptr[i]);
 109                 }
 110                 if (rsb_flag(res, RSB_VALNOTVALID))
 111                         seq_puts(s, " (INVALID)");
 112                 seq_putc(s, '\n');
 113                 if (seq_has_overflowed(s))
 114                         goto out;
 115         }
 116 
 117         root_list = !list_empty(&res->res_root_list);
 118         recover_list = !list_empty(&res->res_recover_list);
 119 
 120         if (root_list || recover_list) {
 121                 seq_printf(s, "Recovery: root %d recover %d flags %lx count %d\n",
 122                            root_list, recover_list,
 123                            res->res_flags, res->res_recover_locks_count);
 124         }
 125 
 126         /* Print the locks attached to this resource */
 127         seq_puts(s, "Granted Queue\n");
 128         list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue) {
 129                 print_format1_lock(s, lkb, res);
 130                 if (seq_has_overflowed(s))
 131                         goto out;
 132         }
 133 
 134         seq_puts(s, "Conversion Queue\n");
 135         list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue) {
 136                 print_format1_lock(s, lkb, res);
 137                 if (seq_has_overflowed(s))
 138                         goto out;
 139         }
 140 
 141         seq_puts(s, "Waiting Queue\n");
 142         list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue) {
 143                 print_format1_lock(s, lkb, res);
 144                 if (seq_has_overflowed(s))
 145                         goto out;
 146         }
 147 
 148         if (list_empty(&res->res_lookup))
 149                 goto out;
 150 
 151         seq_puts(s, "Lookup Queue\n");
 152         list_for_each_entry(lkb, &res->res_lookup, lkb_rsb_lookup) {
 153                 seq_printf(s, "%08x %s",
 154                            lkb->lkb_id, print_lockmode(lkb->lkb_rqmode));
 155                 if (lkb->lkb_wait_type)
 156                         seq_printf(s, " wait_type: %d", lkb->lkb_wait_type);
 157                 seq_putc(s, '\n');
 158                 if (seq_has_overflowed(s))
 159                         goto out;
 160         }
 161  out:
 162         unlock_rsb(res);
 163 }
 164 
 165 static void print_format2_lock(struct seq_file *s, struct dlm_lkb *lkb,
 166                                struct dlm_rsb *r)
 167 {
 168         u64 xid = 0;
 169         u64 us;
 170 
 171         if (lkb->lkb_flags & DLM_IFL_USER) {
 172                 if (lkb->lkb_ua)
 173                         xid = lkb->lkb_ua->xid;
 174         }
 175 
 176         /* microseconds since lkb was added to current queue */
 177         us = ktime_to_us(ktime_sub(ktime_get(), lkb->lkb_timestamp));
 178 
 179         /* id nodeid remid pid xid exflags flags sts grmode rqmode time_us
 180            r_nodeid r_len r_name */
 181 
 182         seq_printf(s, "%x %d %x %u %llu %x %x %d %d %d %llu %u %d \"%s\"\n",
 183                    lkb->lkb_id,
 184                    lkb->lkb_nodeid,
 185                    lkb->lkb_remid,
 186                    lkb->lkb_ownpid,
 187                    (unsigned long long)xid,
 188                    lkb->lkb_exflags,
 189                    lkb->lkb_flags,
 190                    lkb->lkb_status,
 191                    lkb->lkb_grmode,
 192                    lkb->lkb_rqmode,
 193                    (unsigned long long)us,
 194                    r->res_nodeid,
 195                    r->res_length,
 196                    r->res_name);
 197 }
 198 
 199 static void print_format2(struct dlm_rsb *r, struct seq_file *s)
 200 {
 201         struct dlm_lkb *lkb;
 202 
 203         lock_rsb(r);
 204 
 205         list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) {
 206                 print_format2_lock(s, lkb, r);
 207                 if (seq_has_overflowed(s))
 208                         goto out;
 209         }
 210 
 211         list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) {
 212                 print_format2_lock(s, lkb, r);
 213                 if (seq_has_overflowed(s))
 214                         goto out;
 215         }
 216 
 217         list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) {
 218                 print_format2_lock(s, lkb, r);
 219                 if (seq_has_overflowed(s))
 220                         goto out;
 221         }
 222  out:
 223         unlock_rsb(r);
 224 }
 225 
 226 static void print_format3_lock(struct seq_file *s, struct dlm_lkb *lkb,
 227                               int rsb_lookup)
 228 {
 229         u64 xid = 0;
 230 
 231         if (lkb->lkb_flags & DLM_IFL_USER) {
 232                 if (lkb->lkb_ua)
 233                         xid = lkb->lkb_ua->xid;
 234         }
 235 
 236         seq_printf(s, "lkb %x %d %x %u %llu %x %x %d %d %d %d %d %d %u %llu %llu\n",
 237                    lkb->lkb_id,
 238                    lkb->lkb_nodeid,
 239                    lkb->lkb_remid,
 240                    lkb->lkb_ownpid,
 241                    (unsigned long long)xid,
 242                    lkb->lkb_exflags,
 243                    lkb->lkb_flags,
 244                    lkb->lkb_status,
 245                    lkb->lkb_grmode,
 246                    lkb->lkb_rqmode,
 247                    lkb->lkb_last_bast.mode,
 248                    rsb_lookup,
 249                    lkb->lkb_wait_type,
 250                    lkb->lkb_lvbseq,
 251                    (unsigned long long)ktime_to_ns(lkb->lkb_timestamp),
 252                    (unsigned long long)ktime_to_ns(lkb->lkb_last_bast_time));
 253 }
 254 
 255 static void print_format3(struct dlm_rsb *r, struct seq_file *s)
 256 {
 257         struct dlm_lkb *lkb;
 258         int i, lvblen = r->res_ls->ls_lvblen;
 259         int print_name = 1;
 260 
 261         lock_rsb(r);
 262 
 263         seq_printf(s, "rsb %p %d %x %lx %d %d %u %d ",
 264                    r,
 265                    r->res_nodeid,
 266                    r->res_first_lkid,
 267                    r->res_flags,
 268                    !list_empty(&r->res_root_list),
 269                    !list_empty(&r->res_recover_list),
 270                    r->res_recover_locks_count,
 271                    r->res_length);
 272         if (seq_has_overflowed(s))
 273                 goto out;
 274 
 275         for (i = 0; i < r->res_length; i++) {
 276                 if (!isascii(r->res_name[i]) || !isprint(r->res_name[i]))
 277                         print_name = 0;
 278         }
 279 
 280         seq_puts(s, print_name ? "str " : "hex");
 281 
 282         for (i = 0; i < r->res_length; i++) {
 283                 if (print_name)
 284                         seq_printf(s, "%c", r->res_name[i]);
 285                 else
 286                         seq_printf(s, " %02x", (unsigned char)r->res_name[i]);
 287         }
 288         seq_putc(s, '\n');
 289         if (seq_has_overflowed(s))
 290                 goto out;
 291 
 292         if (!r->res_lvbptr)
 293                 goto do_locks;
 294 
 295         seq_printf(s, "lvb %u %d", r->res_lvbseq, lvblen);
 296 
 297         for (i = 0; i < lvblen; i++)
 298                 seq_printf(s, " %02x", (unsigned char)r->res_lvbptr[i]);
 299         seq_putc(s, '\n');
 300         if (seq_has_overflowed(s))
 301                 goto out;
 302 
 303  do_locks:
 304         list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) {
 305                 print_format3_lock(s, lkb, 0);
 306                 if (seq_has_overflowed(s))
 307                         goto out;
 308         }
 309 
 310         list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) {
 311                 print_format3_lock(s, lkb, 0);
 312                 if (seq_has_overflowed(s))
 313                         goto out;
 314         }
 315 
 316         list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) {
 317                 print_format3_lock(s, lkb, 0);
 318                 if (seq_has_overflowed(s))
 319                         goto out;
 320         }
 321 
 322         list_for_each_entry(lkb, &r->res_lookup, lkb_rsb_lookup) {
 323                 print_format3_lock(s, lkb, 1);
 324                 if (seq_has_overflowed(s))
 325                         goto out;
 326         }
 327  out:
 328         unlock_rsb(r);
 329 }
 330 
 331 static void print_format4(struct dlm_rsb *r, struct seq_file *s)
 332 {
 333         int our_nodeid = dlm_our_nodeid();
 334         int print_name = 1;
 335         int i;
 336 
 337         lock_rsb(r);
 338 
 339         seq_printf(s, "rsb %p %d %d %d %d %lu %lx %d ",
 340                    r,
 341                    r->res_nodeid,
 342                    r->res_master_nodeid,
 343                    r->res_dir_nodeid,
 344                    our_nodeid,
 345                    r->res_toss_time,
 346                    r->res_flags,
 347                    r->res_length);
 348 
 349         for (i = 0; i < r->res_length; i++) {
 350                 if (!isascii(r->res_name[i]) || !isprint(r->res_name[i]))
 351                         print_name = 0;
 352         }
 353 
 354         seq_puts(s, print_name ? "str " : "hex");
 355 
 356         for (i = 0; i < r->res_length; i++) {
 357                 if (print_name)
 358                         seq_printf(s, "%c", r->res_name[i]);
 359                 else
 360                         seq_printf(s, " %02x", (unsigned char)r->res_name[i]);
 361         }
 362         seq_putc(s, '\n');
 363         unlock_rsb(r);
 364 }
 365 
 366 struct rsbtbl_iter {
 367         struct dlm_rsb *rsb;
 368         unsigned bucket;
 369         int format;
 370         int header;
 371 };
 372 
 373 /*
 374  * If the buffer is full, seq_printf can be called again, but it
 375  * does nothing.  So, the these printing routines periodically check
 376  * seq_has_overflowed to avoid wasting too much time trying to print to
 377  * a full buffer.
 378  */
 379 
 380 static int table_seq_show(struct seq_file *seq, void *iter_ptr)
 381 {
 382         struct rsbtbl_iter *ri = iter_ptr;
 383 
 384         switch (ri->format) {
 385         case 1:
 386                 print_format1(ri->rsb, seq);
 387                 break;
 388         case 2:
 389                 if (ri->header) {
 390                         seq_puts(seq, "id nodeid remid pid xid exflags flags sts grmode rqmode time_ms r_nodeid r_len r_name\n");
 391                         ri->header = 0;
 392                 }
 393                 print_format2(ri->rsb, seq);
 394                 break;
 395         case 3:
 396                 if (ri->header) {
 397                         seq_puts(seq, "version rsb 1.1 lvb 1.1 lkb 1.1\n");
 398                         ri->header = 0;
 399                 }
 400                 print_format3(ri->rsb, seq);
 401                 break;
 402         case 4:
 403                 if (ri->header) {
 404                         seq_puts(seq, "version 4 rsb 2\n");
 405                         ri->header = 0;
 406                 }
 407                 print_format4(ri->rsb, seq);
 408                 break;
 409         }
 410 
 411         return 0;
 412 }
 413 
 414 static const struct seq_operations format1_seq_ops;
 415 static const struct seq_operations format2_seq_ops;
 416 static const struct seq_operations format3_seq_ops;
 417 static const struct seq_operations format4_seq_ops;
 418 
 419 static void *table_seq_start(struct seq_file *seq, loff_t *pos)
 420 {
 421         struct rb_root *tree;
 422         struct rb_node *node;
 423         struct dlm_ls *ls = seq->private;
 424         struct rsbtbl_iter *ri;
 425         struct dlm_rsb *r;
 426         loff_t n = *pos;
 427         unsigned bucket, entry;
 428         int toss = (seq->op == &format4_seq_ops);
 429 
 430         bucket = n >> 32;
 431         entry = n & ((1LL << 32) - 1);
 432 
 433         if (bucket >= ls->ls_rsbtbl_size)
 434                 return NULL;
 435 
 436         ri = kzalloc(sizeof(*ri), GFP_NOFS);
 437         if (!ri)
 438                 return NULL;
 439         if (n == 0)
 440                 ri->header = 1;
 441         if (seq->op == &format1_seq_ops)
 442                 ri->format = 1;
 443         if (seq->op == &format2_seq_ops)
 444                 ri->format = 2;
 445         if (seq->op == &format3_seq_ops)
 446                 ri->format = 3;
 447         if (seq->op == &format4_seq_ops)
 448                 ri->format = 4;
 449 
 450         tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;
 451 
 452         spin_lock(&ls->ls_rsbtbl[bucket].lock);
 453         if (!RB_EMPTY_ROOT(tree)) {
 454                 for (node = rb_first(tree); node; node = rb_next(node)) {
 455                         r = rb_entry(node, struct dlm_rsb, res_hashnode);
 456                         if (!entry--) {
 457                                 dlm_hold_rsb(r);
 458                                 ri->rsb = r;
 459                                 ri->bucket = bucket;
 460                                 spin_unlock(&ls->ls_rsbtbl[bucket].lock);
 461                                 return ri;
 462                         }
 463                 }
 464         }
 465         spin_unlock(&ls->ls_rsbtbl[bucket].lock);
 466 
 467         /*
 468          * move to the first rsb in the next non-empty bucket
 469          */
 470 
 471         /* zero the entry */
 472         n &= ~((1LL << 32) - 1);
 473 
 474         while (1) {
 475                 bucket++;
 476                 n += 1LL << 32;
 477 
 478                 if (bucket >= ls->ls_rsbtbl_size) {
 479                         kfree(ri);
 480                         return NULL;
 481                 }
 482                 tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;
 483 
 484                 spin_lock(&ls->ls_rsbtbl[bucket].lock);
 485                 if (!RB_EMPTY_ROOT(tree)) {
 486                         node = rb_first(tree);
 487                         r = rb_entry(node, struct dlm_rsb, res_hashnode);
 488                         dlm_hold_rsb(r);
 489                         ri->rsb = r;
 490                         ri->bucket = bucket;
 491                         spin_unlock(&ls->ls_rsbtbl[bucket].lock);
 492                         *pos = n;
 493                         return ri;
 494                 }
 495                 spin_unlock(&ls->ls_rsbtbl[bucket].lock);
 496         }
 497 }
 498 
 499 static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos)
 500 {
 501         struct dlm_ls *ls = seq->private;
 502         struct rsbtbl_iter *ri = iter_ptr;
 503         struct rb_root *tree;
 504         struct rb_node *next;
 505         struct dlm_rsb *r, *rp;
 506         loff_t n = *pos;
 507         unsigned bucket;
 508         int toss = (seq->op == &format4_seq_ops);
 509 
 510         bucket = n >> 32;
 511 
 512         /*
 513          * move to the next rsb in the same bucket
 514          */
 515 
 516         spin_lock(&ls->ls_rsbtbl[bucket].lock);
 517         rp = ri->rsb;
 518         next = rb_next(&rp->res_hashnode);
 519 
 520         if (next) {
 521                 r = rb_entry(next, struct dlm_rsb, res_hashnode);
 522                 dlm_hold_rsb(r);
 523                 ri->rsb = r;
 524                 spin_unlock(&ls->ls_rsbtbl[bucket].lock);
 525                 dlm_put_rsb(rp);
 526                 ++*pos;
 527                 return ri;
 528         }
 529         spin_unlock(&ls->ls_rsbtbl[bucket].lock);
 530         dlm_put_rsb(rp);
 531 
 532         /*
 533          * move to the first rsb in the next non-empty bucket
 534          */
 535 
 536         /* zero the entry */
 537         n &= ~((1LL << 32) - 1);
 538 
 539         while (1) {
 540                 bucket++;
 541                 n += 1LL << 32;
 542 
 543                 if (bucket >= ls->ls_rsbtbl_size) {
 544                         kfree(ri);
 545                         return NULL;
 546                 }
 547                 tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;
 548 
 549                 spin_lock(&ls->ls_rsbtbl[bucket].lock);
 550                 if (!RB_EMPTY_ROOT(tree)) {
 551                         next = rb_first(tree);
 552                         r = rb_entry(next, struct dlm_rsb, res_hashnode);
 553                         dlm_hold_rsb(r);
 554                         ri->rsb = r;
 555                         ri->bucket = bucket;
 556                         spin_unlock(&ls->ls_rsbtbl[bucket].lock);
 557                         *pos = n;
 558                         return ri;
 559                 }
 560                 spin_unlock(&ls->ls_rsbtbl[bucket].lock);
 561         }
 562 }
 563 
 564 static void table_seq_stop(struct seq_file *seq, void *iter_ptr)
 565 {
 566         struct rsbtbl_iter *ri = iter_ptr;
 567 
 568         if (ri) {
 569                 dlm_put_rsb(ri->rsb);
 570                 kfree(ri);
 571         }
 572 }
 573 
 574 static const struct seq_operations format1_seq_ops = {
 575         .start = table_seq_start,
 576         .next  = table_seq_next,
 577         .stop  = table_seq_stop,
 578         .show  = table_seq_show,
 579 };
 580 
 581 static const struct seq_operations format2_seq_ops = {
 582         .start = table_seq_start,
 583         .next  = table_seq_next,
 584         .stop  = table_seq_stop,
 585         .show  = table_seq_show,
 586 };
 587 
 588 static const struct seq_operations format3_seq_ops = {
 589         .start = table_seq_start,
 590         .next  = table_seq_next,
 591         .stop  = table_seq_stop,
 592         .show  = table_seq_show,
 593 };
 594 
 595 static const struct seq_operations format4_seq_ops = {
 596         .start = table_seq_start,
 597         .next  = table_seq_next,
 598         .stop  = table_seq_stop,
 599         .show  = table_seq_show,
 600 };
 601 
 602 static const struct file_operations format1_fops;
 603 static const struct file_operations format2_fops;
 604 static const struct file_operations format3_fops;
 605 static const struct file_operations format4_fops;
 606 
 607 static int table_open1(struct inode *inode, struct file *file)
 608 {
 609         struct seq_file *seq;
 610         int ret;
 611 
 612         ret = seq_open(file, &format1_seq_ops);
 613         if (ret)
 614                 return ret;
 615 
 616         seq = file->private_data;
 617         seq->private = inode->i_private; /* the dlm_ls */
 618         return 0;
 619 }
 620 
 621 static int table_open2(struct inode *inode, struct file *file)
 622 {
 623         struct seq_file *seq;
 624         int ret;
 625 
 626         ret = seq_open(file, &format2_seq_ops);
 627         if (ret)
 628                 return ret;
 629 
 630         seq = file->private_data;
 631         seq->private = inode->i_private; /* the dlm_ls */
 632         return 0;
 633 }
 634 
 635 static int table_open3(struct inode *inode, struct file *file)
 636 {
 637         struct seq_file *seq;
 638         int ret;
 639 
 640         ret = seq_open(file, &format3_seq_ops);
 641         if (ret)
 642                 return ret;
 643 
 644         seq = file->private_data;
 645         seq->private = inode->i_private; /* the dlm_ls */
 646         return 0;
 647 }
 648 
 649 static int table_open4(struct inode *inode, struct file *file)
 650 {
 651         struct seq_file *seq;
 652         int ret;
 653 
 654         ret = seq_open(file, &format4_seq_ops);
 655         if (ret)
 656                 return ret;
 657 
 658         seq = file->private_data;
 659         seq->private = inode->i_private; /* the dlm_ls */
 660         return 0;
 661 }
 662 
 663 static const struct file_operations format1_fops = {
 664         .owner   = THIS_MODULE,
 665         .open    = table_open1,
 666         .read    = seq_read,
 667         .llseek  = seq_lseek,
 668         .release = seq_release
 669 };
 670 
 671 static const struct file_operations format2_fops = {
 672         .owner   = THIS_MODULE,
 673         .open    = table_open2,
 674         .read    = seq_read,
 675         .llseek  = seq_lseek,
 676         .release = seq_release
 677 };
 678 
 679 static const struct file_operations format3_fops = {
 680         .owner   = THIS_MODULE,
 681         .open    = table_open3,
 682         .read    = seq_read,
 683         .llseek  = seq_lseek,
 684         .release = seq_release
 685 };
 686 
 687 static const struct file_operations format4_fops = {
 688         .owner   = THIS_MODULE,
 689         .open    = table_open4,
 690         .read    = seq_read,
 691         .llseek  = seq_lseek,
 692         .release = seq_release
 693 };
 694 
 695 /*
 696  * dump lkb's on the ls_waiters list
 697  */
 698 static ssize_t waiters_read(struct file *file, char __user *userbuf,
 699                             size_t count, loff_t *ppos)
 700 {
 701         struct dlm_ls *ls = file->private_data;
 702         struct dlm_lkb *lkb;
 703         size_t len = DLM_DEBUG_BUF_LEN, pos = 0, ret, rv;
 704 
 705         mutex_lock(&debug_buf_lock);
 706         mutex_lock(&ls->ls_waiters_mutex);
 707         memset(debug_buf, 0, sizeof(debug_buf));
 708 
 709         list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
 710                 ret = snprintf(debug_buf + pos, len - pos, "%x %d %d %s\n",
 711                                lkb->lkb_id, lkb->lkb_wait_type,
 712                                lkb->lkb_nodeid, lkb->lkb_resource->res_name);
 713                 if (ret >= len - pos)
 714                         break;
 715                 pos += ret;
 716         }
 717         mutex_unlock(&ls->ls_waiters_mutex);
 718 
 719         rv = simple_read_from_buffer(userbuf, count, ppos, debug_buf, pos);
 720         mutex_unlock(&debug_buf_lock);
 721         return rv;
 722 }
 723 
 724 static const struct file_operations waiters_fops = {
 725         .owner   = THIS_MODULE,
 726         .open    = simple_open,
 727         .read    = waiters_read,
 728         .llseek  = default_llseek,
 729 };
 730 
 731 void dlm_delete_debug_file(struct dlm_ls *ls)
 732 {
 733         debugfs_remove(ls->ls_debug_rsb_dentry);
 734         debugfs_remove(ls->ls_debug_waiters_dentry);
 735         debugfs_remove(ls->ls_debug_locks_dentry);
 736         debugfs_remove(ls->ls_debug_all_dentry);
 737         debugfs_remove(ls->ls_debug_toss_dentry);
 738 }
 739 
 740 void dlm_create_debug_file(struct dlm_ls *ls)
 741 {
 742         char name[DLM_LOCKSPACE_LEN + 8];
 743 
 744         /* format 1 */
 745 
 746         ls->ls_debug_rsb_dentry = debugfs_create_file(ls->ls_name,
 747                                                       S_IFREG | S_IRUGO,
 748                                                       dlm_root,
 749                                                       ls,
 750                                                       &format1_fops);
 751 
 752         /* format 2 */
 753 
 754         memset(name, 0, sizeof(name));
 755         snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_locks", ls->ls_name);
 756 
 757         ls->ls_debug_locks_dentry = debugfs_create_file(name,
 758                                                         S_IFREG | S_IRUGO,
 759                                                         dlm_root,
 760                                                         ls,
 761                                                         &format2_fops);
 762 
 763         /* format 3 */
 764 
 765         memset(name, 0, sizeof(name));
 766         snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_all", ls->ls_name);
 767 
 768         ls->ls_debug_all_dentry = debugfs_create_file(name,
 769                                                       S_IFREG | S_IRUGO,
 770                                                       dlm_root,
 771                                                       ls,
 772                                                       &format3_fops);
 773 
 774         /* format 4 */
 775 
 776         memset(name, 0, sizeof(name));
 777         snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_toss", ls->ls_name);
 778 
 779         ls->ls_debug_toss_dentry = debugfs_create_file(name,
 780                                                        S_IFREG | S_IRUGO,
 781                                                        dlm_root,
 782                                                        ls,
 783                                                        &format4_fops);
 784 
 785         memset(name, 0, sizeof(name));
 786         snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_waiters", ls->ls_name);
 787 
 788         ls->ls_debug_waiters_dentry = debugfs_create_file(name,
 789                                                           S_IFREG | S_IRUGO,
 790                                                           dlm_root,
 791                                                           ls,
 792                                                           &waiters_fops);
 793 }
 794 
 795 void __init dlm_register_debugfs(void)
 796 {
 797         mutex_init(&debug_buf_lock);
 798         dlm_root = debugfs_create_dir("dlm", NULL);
 799 }
 800 
 801 void dlm_unregister_debugfs(void)
 802 {
 803         debugfs_remove(dlm_root);
 804 }
 805 

/* [<][>][^][v][top][bottom][index][help] */