Blame view

fs/dlm/debug_fs.c 16.4 KB
e7fd41792   David Teigland   [DLM] The core of...
1
2
3
  /******************************************************************************
  *******************************************************************************
  **
892c4467e   David Teigland   dlm: fix seq_file...
4
  **  Copyright (C) 2005-2009 Red Hat, Inc.  All rights reserved.
e7fd41792   David Teigland   [DLM] The core of...
5
6
7
8
9
10
11
12
13
14
15
16
17
  **
  **  This copyrighted material is made available to anyone wishing to use,
  **  modify, copy, or redistribute it subject to the terms and conditions
  **  of the GNU General Public License v.2.
  **
  *******************************************************************************
  ******************************************************************************/
  
  #include <linux/pagemap.h>
  #include <linux/seq_file.h>
  #include <linux/module.h>
  #include <linux/ctype.h>
  #include <linux/debugfs.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
18
  #include <linux/slab.h>
e7fd41792   David Teigland   [DLM] The core of...
19
20
  
  #include "dlm_internal.h"
916297aad   Josef Bacik   [DLM] keep dlm fr...
21
  #include "lock.h"
e7fd41792   David Teigland   [DLM] The core of...
22

5de6319b1   David Teigland   [DLM] more info t...
23
24
25
  #define DLM_DEBUG_BUF_LEN 4096
  static char debug_buf[DLM_DEBUG_BUF_LEN];
  static struct mutex debug_buf_lock;
e7fd41792   David Teigland   [DLM] The core of...
26
27
  
  static struct dentry *dlm_root;
e7fd41792   David Teigland   [DLM] The core of...
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  static char *print_lockmode(int mode)
  {
  	switch (mode) {
  	case DLM_LOCK_IV:
  		return "--";
  	case DLM_LOCK_NL:
  		return "NL";
  	case DLM_LOCK_CR:
  		return "CR";
  	case DLM_LOCK_CW:
  		return "CW";
  	case DLM_LOCK_PR:
  		return "PR";
  	case DLM_LOCK_PW:
  		return "PW";
  	case DLM_LOCK_EX:
  		return "EX";
  	default:
  		return "??";
  	}
  }
892c4467e   David Teigland   dlm: fix seq_file...
49
50
  static int print_format1_lock(struct seq_file *s, struct dlm_lkb *lkb,
  			      struct dlm_rsb *res)
e7fd41792   David Teigland   [DLM] The core of...
51
52
  {
  	seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode));
892c4467e   David Teigland   dlm: fix seq_file...
53
54
  	if (lkb->lkb_status == DLM_LKSTS_CONVERT ||
  	    lkb->lkb_status == DLM_LKSTS_WAITING)
e7fd41792   David Teigland   [DLM] The core of...
55
  		seq_printf(s, " (%s)", print_lockmode(lkb->lkb_rqmode));
e7fd41792   David Teigland   [DLM] The core of...
56
57
58
59
60
61
62
63
64
65
  	if (lkb->lkb_nodeid) {
  		if (lkb->lkb_nodeid != res->res_nodeid)
  			seq_printf(s, " Remote: %3d %08x", lkb->lkb_nodeid,
  				   lkb->lkb_remid);
  		else
  			seq_printf(s, " Master:     %08x", lkb->lkb_remid);
  	}
  
  	if (lkb->lkb_wait_type)
  		seq_printf(s, " wait_type: %d", lkb->lkb_wait_type);
892c4467e   David Teigland   dlm: fix seq_file...
66
67
  	return seq_printf(s, "
  ");
e7fd41792   David Teigland   [DLM] The core of...
68
  }
d022509d1   David Teigland   dlm: add new debu...
69
  static int print_format1(struct dlm_rsb *res, struct seq_file *s)
e7fd41792   David Teigland   [DLM] The core of...
70
71
  {
  	struct dlm_lkb *lkb;
5de6319b1   David Teigland   [DLM] more info t...
72
  	int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list;
892c4467e   David Teigland   dlm: fix seq_file...
73
  	int rv;
e7fd41792   David Teigland   [DLM] The core of...
74

9dd592d70   David Teigland   [DLM] dumping mas...
75
  	lock_rsb(res);
892c4467e   David Teigland   dlm: fix seq_file...
76
77
78
79
80
  	rv = seq_printf(s, "
  Resource %p Name (len=%d) \"",
  			res, res->res_length);
  	if (rv)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
81
82
83
84
85
86
  	for (i = 0; i < res->res_length; i++) {
  		if (isprint(res->res_name[i]))
  			seq_printf(s, "%c", res->res_name[i]);
  		else
  			seq_printf(s, "%c", '.');
  	}
892c4467e   David Teigland   dlm: fix seq_file...
87

e7fd41792   David Teigland   [DLM] The core of...
88
  	if (res->res_nodeid > 0)
892c4467e   David Teigland   dlm: fix seq_file...
89
90
91
92
  		rv = seq_printf(s, "\"  
  Local Copy, Master is node %d
  ",
  				res->res_nodeid);
e7fd41792   David Teigland   [DLM] The core of...
93
  	else if (res->res_nodeid == 0)
892c4467e   David Teigland   dlm: fix seq_file...
94
95
96
  		rv = seq_printf(s, "\"  
  Master Copy
  ");
e7fd41792   David Teigland   [DLM] The core of...
97
  	else if (res->res_nodeid == -1)
892c4467e   David Teigland   dlm: fix seq_file...
98
99
100
101
  		rv = seq_printf(s, "\"  
  Looking up master (lkid %x)
  ",
  			   	res->res_first_lkid);
e7fd41792   David Teigland   [DLM] The core of...
102
  	else
892c4467e   David Teigland   dlm: fix seq_file...
103
104
105
106
107
108
  		rv = seq_printf(s, "\"  
  Invalid master %d
  ",
  				res->res_nodeid);
  	if (rv)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
109
110
111
112
113
114
115
116
117
118
119
120
121
  
  	/* Print the LVB: */
  	if (res->res_lvbptr) {
  		seq_printf(s, "LVB: ");
  		for (i = 0; i < lvblen; i++) {
  			if (i == lvblen / 2)
  				seq_printf(s, "
       ");
  			seq_printf(s, "%02x ",
  				   (unsigned char) res->res_lvbptr[i]);
  		}
  		if (rsb_flag(res, RSB_VALNOTVALID))
  			seq_printf(s, " (INVALID)");
892c4467e   David Teigland   dlm: fix seq_file...
122
123
124
125
  		rv = seq_printf(s, "
  ");
  		if (rv)
  			goto out;
e7fd41792   David Teigland   [DLM] The core of...
126
  	}
5de6319b1   David Teigland   [DLM] more info t...
127
128
129
130
  	root_list = !list_empty(&res->res_root_list);
  	recover_list = !list_empty(&res->res_recover_list);
  
  	if (root_list || recover_list) {
892c4467e   David Teigland   dlm: fix seq_file...
131
132
133
134
135
136
  		rv = seq_printf(s, "Recovery: root %d recover %d flags %lx "
  				"count %d
  ", root_list, recover_list,
  			   	res->res_flags, res->res_recover_locks_count);
  		if (rv)
  			goto out;
5de6319b1   David Teigland   [DLM] more info t...
137
  	}
e7fd41792   David Teigland   [DLM] The core of...
138
139
140
  	/* Print the locks attached to this resource */
  	seq_printf(s, "Granted Queue
  ");
892c4467e   David Teigland   dlm: fix seq_file...
141
142
143
144
145
  	list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue) {
  		rv = print_format1_lock(s, lkb, res);
  		if (rv)
  			goto out;
  	}
e7fd41792   David Teigland   [DLM] The core of...
146
147
148
  
  	seq_printf(s, "Conversion Queue
  ");
892c4467e   David Teigland   dlm: fix seq_file...
149
150
151
152
153
  	list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue) {
  		rv = print_format1_lock(s, lkb, res);
  		if (rv)
  			goto out;
  	}
e7fd41792   David Teigland   [DLM] The core of...
154
155
156
  
  	seq_printf(s, "Waiting Queue
  ");
892c4467e   David Teigland   dlm: fix seq_file...
157
158
159
160
161
  	list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue) {
  		rv = print_format1_lock(s, lkb, res);
  		if (rv)
  			goto out;
  	}
e7fd41792   David Teigland   [DLM] The core of...
162

5de6319b1   David Teigland   [DLM] more info t...
163
164
165
166
167
168
  	if (list_empty(&res->res_lookup))
  		goto out;
  
  	seq_printf(s, "Lookup Queue
  ");
  	list_for_each_entry(lkb, &res->res_lookup, lkb_rsb_lookup) {
892c4467e   David Teigland   dlm: fix seq_file...
169
170
  		rv = seq_printf(s, "%08x %s", lkb->lkb_id,
  				print_lockmode(lkb->lkb_rqmode));
5de6319b1   David Teigland   [DLM] more info t...
171
172
  		if (lkb->lkb_wait_type)
  			seq_printf(s, " wait_type: %d", lkb->lkb_wait_type);
892c4467e   David Teigland   dlm: fix seq_file...
173
174
  		rv = seq_printf(s, "
  ");
5de6319b1   David Teigland   [DLM] more info t...
175
176
  	}
   out:
9dd592d70   David Teigland   [DLM] dumping mas...
177
  	unlock_rsb(res);
892c4467e   David Teigland   dlm: fix seq_file...
178
  	return rv;
9dd592d70   David Teigland   [DLM] dumping mas...
179
  }
892c4467e   David Teigland   dlm: fix seq_file...
180
181
  static int print_format2_lock(struct seq_file *s, struct dlm_lkb *lkb,
  			      struct dlm_rsb *r)
9dd592d70   David Teigland   [DLM] dumping mas...
182
  {
eeda418d8   David Teigland   dlm: change lock ...
183
184
  	u64 xid = 0;
  	u64 us;
892c4467e   David Teigland   dlm: fix seq_file...
185
  	int rv;
9dd592d70   David Teigland   [DLM] dumping mas...
186
187
  
  	if (lkb->lkb_flags & DLM_IFL_USER) {
d292c0cc4   David Teigland   dlm: eliminate as...
188
189
  		if (lkb->lkb_ua)
  			xid = lkb->lkb_ua->xid;
9dd592d70   David Teigland   [DLM] dumping mas...
190
  	}
eeda418d8   David Teigland   dlm: change lock ...
191
192
  	/* microseconds since lkb was added to current queue */
  	us = ktime_to_us(ktime_sub(ktime_get(), lkb->lkb_timestamp));
9dd592d70   David Teigland   [DLM] dumping mas...
193

eeda418d8   David Teigland   dlm: change lock ...
194
  	/* id nodeid remid pid xid exflags flags sts grmode rqmode time_us
ac90a2552   David Teigland   [DLM] dump more l...
195
  	   r_nodeid r_len r_name */
9dd592d70   David Teigland   [DLM] dumping mas...
196

892c4467e   David Teigland   dlm: fix seq_file...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  	rv = seq_printf(s, "%x %d %x %u %llu %x %x %d %d %d %llu %u %d \"%s\"
  ",
  			lkb->lkb_id,
  			lkb->lkb_nodeid,
  			lkb->lkb_remid,
  			lkb->lkb_ownpid,
  			(unsigned long long)xid,
  			lkb->lkb_exflags,
  			lkb->lkb_flags,
  			lkb->lkb_status,
  			lkb->lkb_grmode,
  			lkb->lkb_rqmode,
  			(unsigned long long)us,
  			r->res_nodeid,
  			r->res_length,
  			r->res_name);
  	return rv;
9dd592d70   David Teigland   [DLM] dumping mas...
214
  }
d022509d1   David Teigland   dlm: add new debu...
215
  static int print_format2(struct dlm_rsb *r, struct seq_file *s)
9dd592d70   David Teigland   [DLM] dumping mas...
216
217
  {
  	struct dlm_lkb *lkb;
892c4467e   David Teigland   dlm: fix seq_file...
218
  	int rv = 0;
9dd592d70   David Teigland   [DLM] dumping mas...
219
220
  
  	lock_rsb(r);
892c4467e   David Teigland   dlm: fix seq_file...
221
222
223
224
225
  	list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) {
  		rv = print_format2_lock(s, lkb, r);
  		if (rv)
  			goto out;
  	}
9dd592d70   David Teigland   [DLM] dumping mas...
226

892c4467e   David Teigland   dlm: fix seq_file...
227
228
229
230
231
  	list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) {
  		rv = print_format2_lock(s, lkb, r);
  		if (rv)
  			goto out;
  	}
d022509d1   David Teigland   dlm: add new debu...
232

892c4467e   David Teigland   dlm: fix seq_file...
233
234
235
236
237
238
  	list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) {
  		rv = print_format2_lock(s, lkb, r);
  		if (rv)
  			goto out;
  	}
   out:
d022509d1   David Teigland   dlm: add new debu...
239
  	unlock_rsb(r);
892c4467e   David Teigland   dlm: fix seq_file...
240
  	return rv;
d022509d1   David Teigland   dlm: add new debu...
241
  }
892c4467e   David Teigland   dlm: fix seq_file...
242
243
  static int print_format3_lock(struct seq_file *s, struct dlm_lkb *lkb,
  			      int rsb_lookup)
d022509d1   David Teigland   dlm: add new debu...
244
245
  {
  	u64 xid = 0;
892c4467e   David Teigland   dlm: fix seq_file...
246
  	int rv;
d022509d1   David Teigland   dlm: add new debu...
247
248
249
250
251
  
  	if (lkb->lkb_flags & DLM_IFL_USER) {
  		if (lkb->lkb_ua)
  			xid = lkb->lkb_ua->xid;
  	}
892c4467e   David Teigland   dlm: fix seq_file...
252
253
254
255
256
257
258
259
260
261
262
263
  	rv = seq_printf(s, "lkb %x %d %x %u %llu %x %x %d %d %d %d %d %d %u %llu %llu
  ",
  			lkb->lkb_id,
  			lkb->lkb_nodeid,
  			lkb->lkb_remid,
  			lkb->lkb_ownpid,
  			(unsigned long long)xid,
  			lkb->lkb_exflags,
  			lkb->lkb_flags,
  			lkb->lkb_status,
  			lkb->lkb_grmode,
  			lkb->lkb_rqmode,
8304d6f24   David Teigland   dlm: record full ...
264
  			lkb->lkb_last_bast.mode,
892c4467e   David Teigland   dlm: fix seq_file...
265
266
267
268
  			rsb_lookup,
  			lkb->lkb_wait_type,
  			lkb->lkb_lvbseq,
  			(unsigned long long)ktime_to_ns(lkb->lkb_timestamp),
8304d6f24   David Teigland   dlm: record full ...
269
  			(unsigned long long)ktime_to_ns(lkb->lkb_last_bast_time));
892c4467e   David Teigland   dlm: fix seq_file...
270
  	return rv;
d022509d1   David Teigland   dlm: add new debu...
271
272
273
274
275
276
277
  }
  
  static int print_format3(struct dlm_rsb *r, struct seq_file *s)
  {
  	struct dlm_lkb *lkb;
  	int i, lvblen = r->res_ls->ls_lvblen;
  	int print_name = 1;
892c4467e   David Teigland   dlm: fix seq_file...
278
  	int rv;
d022509d1   David Teigland   dlm: add new debu...
279
280
  
  	lock_rsb(r);
892c4467e   David Teigland   dlm: fix seq_file...
281
282
283
284
285
286
287
288
289
290
291
  	rv = seq_printf(s, "rsb %p %d %x %lx %d %d %u %d ",
  			r,
  			r->res_nodeid,
  			r->res_first_lkid,
  			r->res_flags,
  			!list_empty(&r->res_root_list),
  			!list_empty(&r->res_recover_list),
  			r->res_recover_locks_count,
  			r->res_length);
  	if (rv)
  		goto out;
d022509d1   David Teigland   dlm: add new debu...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
  
  	for (i = 0; i < r->res_length; i++) {
  		if (!isascii(r->res_name[i]) || !isprint(r->res_name[i]))
  			print_name = 0;
  	}
  
  	seq_printf(s, "%s", print_name ? "str " : "hex");
  
  	for (i = 0; i < r->res_length; i++) {
  		if (print_name)
  			seq_printf(s, "%c", r->res_name[i]);
  		else
  			seq_printf(s, " %02x", (unsigned char)r->res_name[i]);
  	}
892c4467e   David Teigland   dlm: fix seq_file...
306
307
308
309
  	rv = seq_printf(s, "
  ");
  	if (rv)
  		goto out;
d022509d1   David Teigland   dlm: add new debu...
310
311
312
313
314
315
316
317
  
  	if (!r->res_lvbptr)
  		goto do_locks;
  
  	seq_printf(s, "lvb %u %d", r->res_lvbseq, lvblen);
  
  	for (i = 0; i < lvblen; i++)
  		seq_printf(s, " %02x", (unsigned char)r->res_lvbptr[i]);
892c4467e   David Teigland   dlm: fix seq_file...
318
319
320
321
  	rv = seq_printf(s, "
  ");
  	if (rv)
  		goto out;
d022509d1   David Teigland   dlm: add new debu...
322
323
  
   do_locks:
892c4467e   David Teigland   dlm: fix seq_file...
324
325
326
327
  	list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) {
  		rv = print_format3_lock(s, lkb, 0);
  		if (rv)
  			goto out;
e7fd41792   David Teigland   [DLM] The core of...
328
  	}
e7fd41792   David Teigland   [DLM] The core of...
329

892c4467e   David Teigland   dlm: fix seq_file...
330
331
332
333
  	list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) {
  		rv = print_format3_lock(s, lkb, 0);
  		if (rv)
  			goto out;
e7fd41792   David Teigland   [DLM] The core of...
334
  	}
892c4467e   David Teigland   dlm: fix seq_file...
335
336
337
338
  	list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) {
  		rv = print_format3_lock(s, lkb, 0);
  		if (rv)
  			goto out;
e7fd41792   David Teigland   [DLM] The core of...
339
  	}
892c4467e   David Teigland   dlm: fix seq_file...
340
341
342
343
  	list_for_each_entry(lkb, &r->res_lookup, lkb_rsb_lookup) {
  		rv = print_format3_lock(s, lkb, 1);
  		if (rv)
  			goto out;
e7fd41792   David Teigland   [DLM] The core of...
344
  	}
892c4467e   David Teigland   dlm: fix seq_file...
345
346
347
   out:
  	unlock_rsb(r);
  	return rv;
e7fd41792   David Teigland   [DLM] The core of...
348
  }
892c4467e   David Teigland   dlm: fix seq_file...
349
350
351
352
353
354
  struct rsbtbl_iter {
  	struct dlm_rsb *rsb;
  	unsigned bucket;
  	int format;
  	int header;
  };
e7fd41792   David Teigland   [DLM] The core of...
355

892c4467e   David Teigland   dlm: fix seq_file...
356
357
358
359
360
361
362
  /* seq_printf returns -1 if the buffer is full, and 0 otherwise.
     If the buffer is full, seq_printf can be called again, but it
     does nothing and just returns -1.  So, the these printing routines
     periodically check the return value to avoid wasting too much time
     trying to print to a full buffer. */
  
  static int table_seq_show(struct seq_file *seq, void *iter_ptr)
e7fd41792   David Teigland   [DLM] The core of...
363
  {
892c4467e   David Teigland   dlm: fix seq_file...
364
365
  	struct rsbtbl_iter *ri = iter_ptr;
  	int rv = 0;
e7fd41792   David Teigland   [DLM] The core of...
366

d022509d1   David Teigland   dlm: add new debu...
367
368
  	switch (ri->format) {
  	case 1:
892c4467e   David Teigland   dlm: fix seq_file...
369
  		rv = print_format1(ri->rsb, seq);
d022509d1   David Teigland   dlm: add new debu...
370
371
  		break;
  	case 2:
9dd592d70   David Teigland   [DLM] dumping mas...
372
  		if (ri->header) {
892c4467e   David Teigland   dlm: fix seq_file...
373
374
375
376
  			seq_printf(seq, "id nodeid remid pid xid exflags "
  					"flags sts grmode rqmode time_ms "
  					"r_nodeid r_len r_name
  ");
9dd592d70   David Teigland   [DLM] dumping mas...
377
378
  			ri->header = 0;
  		}
892c4467e   David Teigland   dlm: fix seq_file...
379
  		rv = print_format2(ri->rsb, seq);
d022509d1   David Teigland   dlm: add new debu...
380
381
382
  		break;
  	case 3:
  		if (ri->header) {
892c4467e   David Teigland   dlm: fix seq_file...
383
384
  			seq_printf(seq, "version rsb 1.1 lvb 1.1 lkb 1.1
  ");
d022509d1   David Teigland   dlm: add new debu...
385
386
  			ri->header = 0;
  		}
892c4467e   David Teigland   dlm: fix seq_file...
387
  		rv = print_format3(ri->rsb, seq);
d022509d1   David Teigland   dlm: add new debu...
388
  		break;
9dd592d70   David Teigland   [DLM] dumping mas...
389
  	}
e7fd41792   David Teigland   [DLM] The core of...
390

892c4467e   David Teigland   dlm: fix seq_file...
391
  	return rv;
e7fd41792   David Teigland   [DLM] The core of...
392
  }
88e9d34c7   James Morris   seq_file: constif...
393
394
395
  static const struct seq_operations format1_seq_ops;
  static const struct seq_operations format2_seq_ops;
  static const struct seq_operations format3_seq_ops;
e7fd41792   David Teigland   [DLM] The core of...
396

892c4467e   David Teigland   dlm: fix seq_file...
397
  static void *table_seq_start(struct seq_file *seq, loff_t *pos)
e7fd41792   David Teigland   [DLM] The core of...
398
  {
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
399
  	struct rb_node *node;
892c4467e   David Teigland   dlm: fix seq_file...
400
401
402
403
404
  	struct dlm_ls *ls = seq->private;
  	struct rsbtbl_iter *ri;
  	struct dlm_rsb *r;
  	loff_t n = *pos;
  	unsigned bucket, entry;
e7fd41792   David Teigland   [DLM] The core of...
405

892c4467e   David Teigland   dlm: fix seq_file...
406
407
  	bucket = n >> 32;
  	entry = n & ((1LL << 32) - 1);
9dd592d70   David Teigland   [DLM] dumping mas...
408

892c4467e   David Teigland   dlm: fix seq_file...
409
410
  	if (bucket >= ls->ls_rsbtbl_size)
  		return NULL;
9dd592d70   David Teigland   [DLM] dumping mas...
411

573c24c4a   David Teigland   dlm: always use G...
412
  	ri = kzalloc(sizeof(struct rsbtbl_iter), GFP_NOFS);
9dd592d70   David Teigland   [DLM] dumping mas...
413
414
  	if (!ri)
  		return NULL;
892c4467e   David Teigland   dlm: fix seq_file...
415
  	if (n == 0)
9dd592d70   David Teigland   [DLM] dumping mas...
416
  		ri->header = 1;
892c4467e   David Teigland   dlm: fix seq_file...
417
418
419
420
421
422
  	if (seq->op == &format1_seq_ops)
  		ri->format = 1;
  	if (seq->op == &format2_seq_ops)
  		ri->format = 2;
  	if (seq->op == &format3_seq_ops)
  		ri->format = 3;
c7be761a8   David Teigland   dlm: change rsbtb...
423
  	spin_lock(&ls->ls_rsbtbl[bucket].lock);
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
424
425
426
427
  	if (!RB_EMPTY_ROOT(&ls->ls_rsbtbl[bucket].keep)) {
  		for (node = rb_first(&ls->ls_rsbtbl[bucket].keep); node;
  		     node = rb_next(node)) {
  			r = rb_entry(node, struct dlm_rsb, res_hashnode);
892c4467e   David Teigland   dlm: fix seq_file...
428
429
430
431
  			if (!entry--) {
  				dlm_hold_rsb(r);
  				ri->rsb = r;
  				ri->bucket = bucket;
c7be761a8   David Teigland   dlm: change rsbtb...
432
  				spin_unlock(&ls->ls_rsbtbl[bucket].lock);
892c4467e   David Teigland   dlm: fix seq_file...
433
434
435
  				return ri;
  			}
  		}
9dd592d70   David Teigland   [DLM] dumping mas...
436
  	}
c7be761a8   David Teigland   dlm: change rsbtb...
437
  	spin_unlock(&ls->ls_rsbtbl[bucket].lock);
9dd592d70   David Teigland   [DLM] dumping mas...
438

892c4467e   David Teigland   dlm: fix seq_file...
439
440
441
  	/*
  	 * move to the first rsb in the next non-empty bucket
  	 */
9dd592d70   David Teigland   [DLM] dumping mas...
442

892c4467e   David Teigland   dlm: fix seq_file...
443
444
  	/* zero the entry */
  	n &= ~((1LL << 32) - 1);
9dd592d70   David Teigland   [DLM] dumping mas...
445

892c4467e   David Teigland   dlm: fix seq_file...
446
447
448
  	while (1) {
  		bucket++;
  		n += 1LL << 32;
9dd592d70   David Teigland   [DLM] dumping mas...
449

892c4467e   David Teigland   dlm: fix seq_file...
450
451
  		if (bucket >= ls->ls_rsbtbl_size) {
  			kfree(ri);
9dd592d70   David Teigland   [DLM] dumping mas...
452
453
  			return NULL;
  		}
9dd592d70   David Teigland   [DLM] dumping mas...
454

c7be761a8   David Teigland   dlm: change rsbtb...
455
  		spin_lock(&ls->ls_rsbtbl[bucket].lock);
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
456
457
458
  		if (!RB_EMPTY_ROOT(&ls->ls_rsbtbl[bucket].keep)) {
  			node = rb_first(&ls->ls_rsbtbl[bucket].keep);
  			r = rb_entry(node, struct dlm_rsb, res_hashnode);
892c4467e   David Teigland   dlm: fix seq_file...
459
460
461
  			dlm_hold_rsb(r);
  			ri->rsb = r;
  			ri->bucket = bucket;
c7be761a8   David Teigland   dlm: change rsbtb...
462
  			spin_unlock(&ls->ls_rsbtbl[bucket].lock);
892c4467e   David Teigland   dlm: fix seq_file...
463
464
465
  			*pos = n;
  			return ri;
  		}
c7be761a8   David Teigland   dlm: change rsbtb...
466
  		spin_unlock(&ls->ls_rsbtbl[bucket].lock);
892c4467e   David Teigland   dlm: fix seq_file...
467
  	}
9dd592d70   David Teigland   [DLM] dumping mas...
468
  }
892c4467e   David Teigland   dlm: fix seq_file...
469
  static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos)
9dd592d70   David Teigland   [DLM] dumping mas...
470
  {
892c4467e   David Teigland   dlm: fix seq_file...
471
472
  	struct dlm_ls *ls = seq->private;
  	struct rsbtbl_iter *ri = iter_ptr;
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
473
  	struct rb_node *next;
892c4467e   David Teigland   dlm: fix seq_file...
474
475
476
477
478
479
480
481
482
  	struct dlm_rsb *r, *rp;
  	loff_t n = *pos;
  	unsigned bucket;
  
  	bucket = n >> 32;
  
  	/*
  	 * move to the next rsb in the same bucket
  	 */
c7be761a8   David Teigland   dlm: change rsbtb...
483
  	spin_lock(&ls->ls_rsbtbl[bucket].lock);
892c4467e   David Teigland   dlm: fix seq_file...
484
  	rp = ri->rsb;
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
485
  	next = rb_next(&rp->res_hashnode);
892c4467e   David Teigland   dlm: fix seq_file...
486

9beb3bf5a   Bob Peterson   dlm: convert rsb ...
487
488
  	if (next) {
  		r = rb_entry(next, struct dlm_rsb, res_hashnode);
892c4467e   David Teigland   dlm: fix seq_file...
489
490
  		dlm_hold_rsb(r);
  		ri->rsb = r;
c7be761a8   David Teigland   dlm: change rsbtb...
491
  		spin_unlock(&ls->ls_rsbtbl[bucket].lock);
892c4467e   David Teigland   dlm: fix seq_file...
492
493
494
495
  		dlm_put_rsb(rp);
  		++*pos;
  		return ri;
  	}
c7be761a8   David Teigland   dlm: change rsbtb...
496
  	spin_unlock(&ls->ls_rsbtbl[bucket].lock);
892c4467e   David Teigland   dlm: fix seq_file...
497
  	dlm_put_rsb(rp);
d022509d1   David Teigland   dlm: add new debu...
498

892c4467e   David Teigland   dlm: fix seq_file...
499
500
501
  	/*
  	 * move to the first rsb in the next non-empty bucket
  	 */
d022509d1   David Teigland   dlm: add new debu...
502

892c4467e   David Teigland   dlm: fix seq_file...
503
504
  	/* zero the entry */
  	n &= ~((1LL << 32) - 1);
d022509d1   David Teigland   dlm: add new debu...
505

892c4467e   David Teigland   dlm: fix seq_file...
506
507
508
  	while (1) {
  		bucket++;
  		n += 1LL << 32;
d022509d1   David Teigland   dlm: add new debu...
509

892c4467e   David Teigland   dlm: fix seq_file...
510
511
512
513
  		if (bucket >= ls->ls_rsbtbl_size) {
  			kfree(ri);
  			return NULL;
  		}
d022509d1   David Teigland   dlm: add new debu...
514

c7be761a8   David Teigland   dlm: change rsbtb...
515
  		spin_lock(&ls->ls_rsbtbl[bucket].lock);
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
516
517
518
  		if (!RB_EMPTY_ROOT(&ls->ls_rsbtbl[bucket].keep)) {
  			next = rb_first(&ls->ls_rsbtbl[bucket].keep);
  			r = rb_entry(next, struct dlm_rsb, res_hashnode);
892c4467e   David Teigland   dlm: fix seq_file...
519
520
521
  			dlm_hold_rsb(r);
  			ri->rsb = r;
  			ri->bucket = bucket;
c7be761a8   David Teigland   dlm: change rsbtb...
522
  			spin_unlock(&ls->ls_rsbtbl[bucket].lock);
892c4467e   David Teigland   dlm: fix seq_file...
523
524
525
  			*pos = n;
  			return ri;
  		}
c7be761a8   David Teigland   dlm: change rsbtb...
526
  		spin_unlock(&ls->ls_rsbtbl[bucket].lock);
d022509d1   David Teigland   dlm: add new debu...
527
  	}
d022509d1   David Teigland   dlm: add new debu...
528
  }
892c4467e   David Teigland   dlm: fix seq_file...
529
  static void table_seq_stop(struct seq_file *seq, void *iter_ptr)
d022509d1   David Teigland   dlm: add new debu...
530
  {
892c4467e   David Teigland   dlm: fix seq_file...
531
  	struct rsbtbl_iter *ri = iter_ptr;
d022509d1   David Teigland   dlm: add new debu...
532

892c4467e   David Teigland   dlm: fix seq_file...
533
534
535
  	if (ri) {
  		dlm_put_rsb(ri->rsb);
  		kfree(ri);
d022509d1   David Teigland   dlm: add new debu...
536
  	}
d022509d1   David Teigland   dlm: add new debu...
537
  }
88e9d34c7   James Morris   seq_file: constif...
538
  static const struct seq_operations format1_seq_ops = {
892c4467e   David Teigland   dlm: fix seq_file...
539
540
541
542
  	.start = table_seq_start,
  	.next  = table_seq_next,
  	.stop  = table_seq_stop,
  	.show  = table_seq_show,
d022509d1   David Teigland   dlm: add new debu...
543
  };
88e9d34c7   James Morris   seq_file: constif...
544
  static const struct seq_operations format2_seq_ops = {
892c4467e   David Teigland   dlm: fix seq_file...
545
546
547
548
549
  	.start = table_seq_start,
  	.next  = table_seq_next,
  	.stop  = table_seq_stop,
  	.show  = table_seq_show,
  };
88e9d34c7   James Morris   seq_file: constif...
550
  static const struct seq_operations format3_seq_ops = {
892c4467e   David Teigland   dlm: fix seq_file...
551
552
553
554
555
556
557
558
559
560
561
  	.start = table_seq_start,
  	.next  = table_seq_next,
  	.stop  = table_seq_stop,
  	.show  = table_seq_show,
  };
  
  static const struct file_operations format1_fops;
  static const struct file_operations format2_fops;
  static const struct file_operations format3_fops;
  
  static int table_open(struct inode *inode, struct file *file)
d022509d1   David Teigland   dlm: add new debu...
562
563
  {
  	struct seq_file *seq;
892c4467e   David Teigland   dlm: fix seq_file...
564
565
566
567
568
569
570
571
  	int ret = -1;
  
  	if (file->f_op == &format1_fops)
  		ret = seq_open(file, &format1_seq_ops);
  	else if (file->f_op == &format2_fops)
  		ret = seq_open(file, &format2_seq_ops);
  	else if (file->f_op == &format3_fops)
  		ret = seq_open(file, &format3_seq_ops);
d022509d1   David Teigland   dlm: add new debu...
572

d022509d1   David Teigland   dlm: add new debu...
573
574
575
576
  	if (ret)
  		return ret;
  
  	seq = file->private_data;
892c4467e   David Teigland   dlm: fix seq_file...
577
  	seq->private = inode->i_private; /* the dlm_ls */
d022509d1   David Teigland   dlm: add new debu...
578
579
  	return 0;
  }
892c4467e   David Teigland   dlm: fix seq_file...
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
  static const struct file_operations format1_fops = {
  	.owner   = THIS_MODULE,
  	.open    = table_open,
  	.read    = seq_read,
  	.llseek  = seq_lseek,
  	.release = seq_release
  };
  
  static const struct file_operations format2_fops = {
  	.owner   = THIS_MODULE,
  	.open    = table_open,
  	.read    = seq_read,
  	.llseek  = seq_lseek,
  	.release = seq_release
  };
  
  static const struct file_operations format3_fops = {
d022509d1   David Teigland   dlm: add new debu...
597
  	.owner   = THIS_MODULE,
892c4467e   David Teigland   dlm: fix seq_file...
598
  	.open    = table_open,
d022509d1   David Teigland   dlm: add new debu...
599
600
601
602
603
604
  	.read    = seq_read,
  	.llseek  = seq_lseek,
  	.release = seq_release
  };
  
  /*
5de6319b1   David Teigland   [DLM] more info t...
605
606
607
608
609
   * dump lkb's on the ls_waiters list
   */
  
  static int waiters_open(struct inode *inode, struct file *file)
  {
bba9dfd83   Theodore Ts'o   [GFS2] inode_diet...
610
  	file->private_data = inode->i_private;
5de6319b1   David Teigland   [DLM] more info t...
611
612
613
614
615
616
617
618
  	return 0;
  }
  
  static ssize_t waiters_read(struct file *file, char __user *userbuf,
  			    size_t count, loff_t *ppos)
  {
  	struct dlm_ls *ls = file->private_data;
  	struct dlm_lkb *lkb;
06442440b   David Teigland   [DLM] break from ...
619
  	size_t len = DLM_DEBUG_BUF_LEN, pos = 0, ret, rv;
5de6319b1   David Teigland   [DLM] more info t...
620
621
622
623
624
625
  
  	mutex_lock(&debug_buf_lock);
  	mutex_lock(&ls->ls_waiters_mutex);
  	memset(debug_buf, 0, sizeof(debug_buf));
  
  	list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
06442440b   David Teigland   [DLM] break from ...
626
627
628
629
630
631
632
  		ret = snprintf(debug_buf + pos, len - pos, "%x %d %d %s
  ",
  			       lkb->lkb_id, lkb->lkb_wait_type,
  			       lkb->lkb_nodeid, lkb->lkb_resource->res_name);
  		if (ret >= len - pos)
  			break;
  		pos += ret;
5de6319b1   David Teigland   [DLM] more info t...
633
634
635
636
637
638
639
  	}
  	mutex_unlock(&ls->ls_waiters_mutex);
  
  	rv = simple_read_from_buffer(userbuf, count, ppos, debug_buf, pos);
  	mutex_unlock(&debug_buf_lock);
  	return rv;
  }
00977a59b   Arjan van de Ven   [PATCH] mark stru...
640
  static const struct file_operations waiters_fops = {
5de6319b1   David Teigland   [DLM] more info t...
641
642
  	.owner   = THIS_MODULE,
  	.open    = waiters_open,
6038f373a   Arnd Bergmann   llseek: automatic...
643
644
  	.read    = waiters_read,
  	.llseek  = default_llseek,
5de6319b1   David Teigland   [DLM] more info t...
645
  };
d022509d1   David Teigland   dlm: add new debu...
646
647
648
649
650
651
652
653
654
655
656
  void dlm_delete_debug_file(struct dlm_ls *ls)
  {
  	if (ls->ls_debug_rsb_dentry)
  		debugfs_remove(ls->ls_debug_rsb_dentry);
  	if (ls->ls_debug_waiters_dentry)
  		debugfs_remove(ls->ls_debug_waiters_dentry);
  	if (ls->ls_debug_locks_dentry)
  		debugfs_remove(ls->ls_debug_locks_dentry);
  	if (ls->ls_debug_all_dentry)
  		debugfs_remove(ls->ls_debug_all_dentry);
  }
e7fd41792   David Teigland   [DLM] The core of...
657
658
  int dlm_create_debug_file(struct dlm_ls *ls)
  {
5de6319b1   David Teigland   [DLM] more info t...
659
  	char name[DLM_LOCKSPACE_LEN+8];
d022509d1   David Teigland   dlm: add new debu...
660
  	/* format 1 */
5de6319b1   David Teigland   [DLM] more info t...
661
662
663
664
  	ls->ls_debug_rsb_dentry = debugfs_create_file(ls->ls_name,
  						      S_IFREG | S_IRUGO,
  						      dlm_root,
  						      ls,
892c4467e   David Teigland   dlm: fix seq_file...
665
  						      &format1_fops);
20abf975f   David Teigland   [DLM] fix broken ...
666
  	if (!ls->ls_debug_rsb_dentry)
d022509d1   David Teigland   dlm: add new debu...
667
  		goto fail;
5de6319b1   David Teigland   [DLM] more info t...
668

d022509d1   David Teigland   dlm: add new debu...
669
  	/* format 2 */
5de6319b1   David Teigland   [DLM] more info t...
670

9dd592d70   David Teigland   [DLM] dumping mas...
671
  	memset(name, 0, sizeof(name));
ac90a2552   David Teigland   [DLM] dump more l...
672
673
674
675
676
677
  	snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_locks", ls->ls_name);
  
  	ls->ls_debug_locks_dentry = debugfs_create_file(name,
  							S_IFREG | S_IRUGO,
  							dlm_root,
  							ls,
892c4467e   David Teigland   dlm: fix seq_file...
678
  							&format2_fops);
d022509d1   David Teigland   dlm: add new debu...
679
680
681
682
683
684
685
686
687
688
689
690
  	if (!ls->ls_debug_locks_dentry)
  		goto fail;
  
  	/* format 3 */
  
  	memset(name, 0, sizeof(name));
  	snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_all", ls->ls_name);
  
  	ls->ls_debug_all_dentry = debugfs_create_file(name,
  						      S_IFREG | S_IRUGO,
  						      dlm_root,
  						      ls,
892c4467e   David Teigland   dlm: fix seq_file...
691
  						      &format3_fops);
d022509d1   David Teigland   dlm: add new debu...
692
693
694
695
696
697
698
699
700
701
702
703
704
  	if (!ls->ls_debug_all_dentry)
  		goto fail;
  
  	memset(name, 0, sizeof(name));
  	snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name);
  
  	ls->ls_debug_waiters_dentry = debugfs_create_file(name,
  							  S_IFREG | S_IRUGO,
  							  dlm_root,
  							  ls,
  							  &waiters_fops);
  	if (!ls->ls_debug_waiters_dentry)
  		goto fail;
9dd592d70   David Teigland   [DLM] dumping mas...
705

5de6319b1   David Teigland   [DLM] more info t...
706
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
707

d022509d1   David Teigland   dlm: add new debu...
708
709
710
   fail:
  	dlm_delete_debug_file(ls);
  	return -ENOMEM;
e7fd41792   David Teigland   [DLM] The core of...
711
  }
30727174b   Denis Cheng   dlm: add __init a...
712
  int __init dlm_register_debugfs(void)
e7fd41792   David Teigland   [DLM] The core of...
713
  {
5de6319b1   David Teigland   [DLM] more info t...
714
  	mutex_init(&debug_buf_lock);
e7fd41792   David Teigland   [DLM] The core of...
715
716
717
718
719
720
721
722
  	dlm_root = debugfs_create_dir("dlm", NULL);
  	return dlm_root ? 0 : -ENOMEM;
  }
  
  void dlm_unregister_debugfs(void)
  {
  	debugfs_remove(dlm_root);
  }