1 // SPDX-License-Identifier: GPL-2.0
2 #define pr_fmt(fmt) "drbd debugfs: " fmt
3 #include <linux/kernel.h>
4 #include <linux/module.h>
5 #include <linux/debugfs.h>
6 #include <linux/seq_file.h>
7 #include <linux/stat.h>
8 #include <linux/jiffies.h>
9 #include <linux/list.h>
13 #include "drbd_debugfs.h"
16 /**********************************************************************
17 * Whenever you change the file format, remember to bump the version. *
18 **********************************************************************/
20 static struct dentry
*drbd_debugfs_root
;
21 static struct dentry
*drbd_debugfs_version
;
22 static struct dentry
*drbd_debugfs_resources
;
23 static struct dentry
*drbd_debugfs_minors
;
25 static void seq_print_age_or_dash(struct seq_file
*m
, bool valid
, unsigned long dt
)
28 seq_printf(m
, "\t%d", jiffies_to_msecs(dt
));
33 static void __seq_print_rq_state_bit(struct seq_file
*m
,
34 bool is_set
, char *sep
, const char *set_name
, const char *unset_name
)
36 if (is_set
&& set_name
) {
38 seq_puts(m
, set_name
);
40 } else if (!is_set
&& unset_name
) {
42 seq_puts(m
, unset_name
);
47 static void seq_print_rq_state_bit(struct seq_file
*m
,
48 bool is_set
, char *sep
, const char *set_name
)
50 __seq_print_rq_state_bit(m
, is_set
, sep
, set_name
, NULL
);
53 /* pretty print enum drbd_req_state_bits req->rq_state */
54 static void seq_print_request_state(struct seq_file
*m
, struct drbd_request
*req
)
56 unsigned int s
= req
->rq_state
;
58 seq_printf(m
, "\t0x%08x", s
);
59 seq_printf(m
, "\tmaster: %s", req
->master_bio
? "pending" : "completed");
61 /* RQ_WRITE ignored, already reported */
62 seq_puts(m
, "\tlocal:");
63 seq_print_rq_state_bit(m
, s
& RQ_IN_ACT_LOG
, &sep
, "in-AL");
64 seq_print_rq_state_bit(m
, s
& RQ_POSTPONED
, &sep
, "postponed");
65 seq_print_rq_state_bit(m
, s
& RQ_COMPLETION_SUSP
, &sep
, "suspended");
67 seq_print_rq_state_bit(m
, s
& RQ_LOCAL_PENDING
, &sep
, "pending");
68 seq_print_rq_state_bit(m
, s
& RQ_LOCAL_COMPLETED
, &sep
, "completed");
69 seq_print_rq_state_bit(m
, s
& RQ_LOCAL_ABORTED
, &sep
, "aborted");
70 seq_print_rq_state_bit(m
, s
& RQ_LOCAL_OK
, &sep
, "ok");
74 /* for_each_connection ... */
75 seq_printf(m
, "\tnet:");
77 seq_print_rq_state_bit(m
, s
& RQ_NET_PENDING
, &sep
, "pending");
78 seq_print_rq_state_bit(m
, s
& RQ_NET_QUEUED
, &sep
, "queued");
79 seq_print_rq_state_bit(m
, s
& RQ_NET_SENT
, &sep
, "sent");
80 seq_print_rq_state_bit(m
, s
& RQ_NET_DONE
, &sep
, "done");
81 seq_print_rq_state_bit(m
, s
& RQ_NET_SIS
, &sep
, "sis");
82 seq_print_rq_state_bit(m
, s
& RQ_NET_OK
, &sep
, "ok");
88 seq_print_rq_state_bit(m
, s
& RQ_EXP_RECEIVE_ACK
, &sep
, "B");
89 seq_print_rq_state_bit(m
, s
& RQ_EXP_WRITE_ACK
, &sep
, "C");
90 seq_print_rq_state_bit(m
, s
& RQ_EXP_BARR_ACK
, &sep
, "barr");
96 static void seq_print_one_request(struct seq_file
*m
, struct drbd_request
*req
, unsigned long now
)
98 /* change anything here, fixup header below! */
99 unsigned int s
= req
->rq_state
;
101 #define RQ_HDR_1 "epoch\tsector\tsize\trw"
102 seq_printf(m
, "0x%x\t%llu\t%u\t%s",
104 (unsigned long long)req
->i
.sector
, req
->i
.size
>> 9,
105 (s
& RQ_WRITE
) ? "W" : "R");
107 #define RQ_HDR_2 "\tstart\tin AL\tsubmit"
108 seq_printf(m
, "\t%d", jiffies_to_msecs(now
- req
->start_jif
));
109 seq_print_age_or_dash(m
, s
& RQ_IN_ACT_LOG
, now
- req
->in_actlog_jif
);
110 seq_print_age_or_dash(m
, s
& RQ_LOCAL_PENDING
, now
- req
->pre_submit_jif
);
112 #define RQ_HDR_3 "\tsent\tacked\tdone"
113 seq_print_age_or_dash(m
, s
& RQ_NET_SENT
, now
- req
->pre_send_jif
);
114 seq_print_age_or_dash(m
, (s
& RQ_NET_SENT
) && !(s
& RQ_NET_PENDING
), now
- req
->acked_jif
);
115 seq_print_age_or_dash(m
, s
& RQ_NET_DONE
, now
- req
->net_done_jif
);
117 #define RQ_HDR_4 "\tstate\n"
118 seq_print_request_state(m
, req
);
120 #define RQ_HDR RQ_HDR_1 RQ_HDR_2 RQ_HDR_3 RQ_HDR_4
122 static void seq_print_minor_vnr_req(struct seq_file
*m
, struct drbd_request
*req
, unsigned long now
)
124 seq_printf(m
, "%u\t%u\t", req
->device
->minor
, req
->device
->vnr
);
125 seq_print_one_request(m
, req
, now
);
128 static void seq_print_resource_pending_meta_io(struct seq_file
*m
, struct drbd_resource
*resource
, unsigned long now
)
130 struct drbd_device
*device
;
133 seq_puts(m
, "minor\tvnr\tstart\tsubmit\tintent\n");
135 idr_for_each_entry(&resource
->devices
, device
, i
) {
136 struct drbd_md_io tmp
;
137 /* In theory this is racy,
138 * in the sense that there could have been a
139 * drbd_md_put_buffer(); drbd_md_get_buffer();
140 * between accessing these members here. */
142 if (atomic_read(&tmp
.in_use
)) {
143 seq_printf(m
, "%u\t%u\t%d\t",
144 device
->minor
, device
->vnr
,
145 jiffies_to_msecs(now
- tmp
.start_jif
));
146 if (time_before(tmp
.submit_jif
, tmp
.start_jif
))
149 seq_printf(m
, "%d\t", jiffies_to_msecs(now
- tmp
.submit_jif
));
150 seq_printf(m
, "%s\n", tmp
.current_use
);
156 static void seq_print_waiting_for_AL(struct seq_file
*m
, struct drbd_resource
*resource
, unsigned long now
)
158 struct drbd_device
*device
;
161 seq_puts(m
, "minor\tvnr\tage\t#waiting\n");
163 idr_for_each_entry(&resource
->devices
, device
, i
) {
165 struct drbd_request
*req
;
166 int n
= atomic_read(&device
->ap_actlog_cnt
);
168 spin_lock_irq(&device
->resource
->req_lock
);
169 req
= list_first_entry_or_null(&device
->pending_master_completion
[1],
170 struct drbd_request
, req_pending_master_completion
);
171 /* if the oldest request does not wait for the activity log
172 * it is not interesting for us here */
173 if (req
&& !(req
->rq_state
& RQ_IN_ACT_LOG
))
174 jif
= req
->start_jif
;
177 spin_unlock_irq(&device
->resource
->req_lock
);
180 seq_printf(m
, "%u\t%u\t", device
->minor
, device
->vnr
);
182 seq_printf(m
, "%u\t", jiffies_to_msecs(now
- jif
));
185 seq_printf(m
, "%u\n", n
);
191 static void seq_print_device_bitmap_io(struct seq_file
*m
, struct drbd_device
*device
, unsigned long now
)
193 struct drbd_bm_aio_ctx
*ctx
;
194 unsigned long start_jif
;
195 unsigned int in_flight
;
197 spin_lock_irq(&device
->resource
->req_lock
);
198 ctx
= list_first_entry_or_null(&device
->pending_bitmap_io
, struct drbd_bm_aio_ctx
, list
);
199 if (ctx
&& ctx
->done
)
202 start_jif
= ctx
->start_jif
;
203 in_flight
= atomic_read(&ctx
->in_flight
);
206 spin_unlock_irq(&device
->resource
->req_lock
);
208 seq_printf(m
, "%u\t%u\t%c\t%u\t%u\n",
209 device
->minor
, device
->vnr
,
210 (flags
& BM_AIO_READ
) ? 'R' : 'W',
211 jiffies_to_msecs(now
- start_jif
),
216 static void seq_print_resource_pending_bitmap_io(struct seq_file
*m
, struct drbd_resource
*resource
, unsigned long now
)
218 struct drbd_device
*device
;
221 seq_puts(m
, "minor\tvnr\trw\tage\t#in-flight\n");
223 idr_for_each_entry(&resource
->devices
, device
, i
) {
224 seq_print_device_bitmap_io(m
, device
, now
);
229 /* pretty print enum peer_req->flags */
230 static void seq_print_peer_request_flags(struct seq_file
*m
, struct drbd_peer_request
*peer_req
)
232 unsigned long f
= peer_req
->flags
;
235 __seq_print_rq_state_bit(m
, f
& EE_SUBMITTED
, &sep
, "submitted", "preparing");
236 __seq_print_rq_state_bit(m
, f
& EE_APPLICATION
, &sep
, "application", "internal");
237 seq_print_rq_state_bit(m
, f
& EE_CALL_AL_COMPLETE_IO
, &sep
, "in-AL");
238 seq_print_rq_state_bit(m
, f
& EE_SEND_WRITE_ACK
, &sep
, "C");
239 seq_print_rq_state_bit(m
, f
& EE_MAY_SET_IN_SYNC
, &sep
, "set-in-sync");
240 seq_print_rq_state_bit(m
, f
& EE_TRIM
, &sep
, "trim");
241 seq_print_rq_state_bit(m
, f
& EE_ZEROOUT
, &sep
, "zero-out");
242 seq_print_rq_state_bit(m
, f
& EE_WRITE_SAME
, &sep
, "write-same");
246 static void seq_print_peer_request(struct seq_file
*m
,
247 struct drbd_device
*device
, struct list_head
*lh
,
250 bool reported_preparing
= false;
251 struct drbd_peer_request
*peer_req
;
252 list_for_each_entry(peer_req
, lh
, w
.list
) {
253 if (reported_preparing
&& !(peer_req
->flags
& EE_SUBMITTED
))
257 seq_printf(m
, "%u\t%u\t", device
->minor
, device
->vnr
);
259 seq_printf(m
, "%llu\t%u\t%c\t%u\t",
260 (unsigned long long)peer_req
->i
.sector
, peer_req
->i
.size
>> 9,
261 (peer_req
->flags
& EE_WRITE
) ? 'W' : 'R',
262 jiffies_to_msecs(now
- peer_req
->submit_jif
));
263 seq_print_peer_request_flags(m
, peer_req
);
264 if (peer_req
->flags
& EE_SUBMITTED
)
267 reported_preparing
= true;
271 static void seq_print_device_peer_requests(struct seq_file
*m
,
272 struct drbd_device
*device
, unsigned long now
)
274 seq_puts(m
, "minor\tvnr\tsector\tsize\trw\tage\tflags\n");
275 spin_lock_irq(&device
->resource
->req_lock
);
276 seq_print_peer_request(m
, device
, &device
->active_ee
, now
);
277 seq_print_peer_request(m
, device
, &device
->read_ee
, now
);
278 seq_print_peer_request(m
, device
, &device
->sync_ee
, now
);
279 spin_unlock_irq(&device
->resource
->req_lock
);
280 if (test_bit(FLUSH_PENDING
, &device
->flags
)) {
281 seq_printf(m
, "%u\t%u\t-\t-\tF\t%u\tflush\n",
282 device
->minor
, device
->vnr
,
283 jiffies_to_msecs(now
- device
->flush_jif
));
287 static void seq_print_resource_pending_peer_requests(struct seq_file
*m
,
288 struct drbd_resource
*resource
, unsigned long now
)
290 struct drbd_device
*device
;
294 idr_for_each_entry(&resource
->devices
, device
, i
) {
295 seq_print_device_peer_requests(m
, device
, now
);
300 static void seq_print_resource_transfer_log_summary(struct seq_file
*m
,
301 struct drbd_resource
*resource
,
302 struct drbd_connection
*connection
,
305 struct drbd_request
*req
;
306 unsigned int count
= 0;
307 unsigned int show_state
= 0;
309 seq_puts(m
, "n\tdevice\tvnr\t" RQ_HDR
);
310 spin_lock_irq(&resource
->req_lock
);
311 list_for_each_entry(req
, &connection
->transfer_log
, tl_requests
) {
312 unsigned int tmp
= 0;
316 /* don't disable irq "forever" */
317 if (!(count
& 0x1ff)) {
318 struct drbd_request
*req_next
;
319 kref_get(&req
->kref
);
320 spin_unlock_irq(&resource
->req_lock
);
322 spin_lock_irq(&resource
->req_lock
);
323 req_next
= list_next_entry(req
, tl_requests
);
324 if (kref_put(&req
->kref
, drbd_req_destroy
))
326 if (&req
->tl_requests
== &connection
->transfer_log
)
332 /* This is meant to summarize timing issues, to be able to tell
333 * local disk problems from network problems.
334 * Skip requests, if we have shown an even older request with
335 * similar aspects already. */
336 if (req
->master_bio
== NULL
)
338 if ((s
& RQ_LOCAL_MASK
) && (s
& RQ_LOCAL_PENDING
))
340 if (s
& RQ_NET_MASK
) {
341 if (!(s
& RQ_NET_SENT
))
343 if (s
& RQ_NET_PENDING
)
345 if (!(s
& RQ_NET_DONE
))
348 if ((tmp
& show_state
) == tmp
)
351 seq_printf(m
, "%u\t", count
);
352 seq_print_minor_vnr_req(m
, req
, now
);
353 if (show_state
== 0x1f)
356 spin_unlock_irq(&resource
->req_lock
);
359 /* TODO: transfer_log and friends should be moved to resource */
360 static int in_flight_summary_show(struct seq_file
*m
, void *pos
)
362 struct drbd_resource
*resource
= m
->private;
363 struct drbd_connection
*connection
;
364 unsigned long jif
= jiffies
;
366 connection
= first_connection(resource
);
367 /* This does not happen, actually.
368 * But be robust and prepare for future code changes. */
369 if (!connection
|| !kref_get_unless_zero(&connection
->kref
))
372 /* BUMP me if you change the file format/content/presentation */
373 seq_printf(m
, "v: %u\n\n", 0);
375 seq_puts(m
, "oldest bitmap IO\n");
376 seq_print_resource_pending_bitmap_io(m
, resource
, jif
);
379 seq_puts(m
, "meta data IO\n");
380 seq_print_resource_pending_meta_io(m
, resource
, jif
);
383 seq_puts(m
, "socket buffer stats\n");
384 /* for each connection ... once we have more than one */
386 if (connection
->data
.socket
) {
387 /* open coded SIOCINQ, the "relevant" part */
388 struct tcp_sock
*tp
= tcp_sk(connection
->data
.socket
->sk
);
389 int answ
= tp
->rcv_nxt
- tp
->copied_seq
;
390 seq_printf(m
, "unread receive buffer: %u Byte\n", answ
);
391 /* open coded SIOCOUTQ, the "relevant" part */
392 answ
= tp
->write_seq
- tp
->snd_una
;
393 seq_printf(m
, "unacked send buffer: %u Byte\n", answ
);
398 seq_puts(m
, "oldest peer requests\n");
399 seq_print_resource_pending_peer_requests(m
, resource
, jif
);
402 seq_puts(m
, "application requests waiting for activity log\n");
403 seq_print_waiting_for_AL(m
, resource
, jif
);
406 seq_puts(m
, "oldest application requests\n");
407 seq_print_resource_transfer_log_summary(m
, resource
, connection
, jif
);
412 seq_printf(m
, "generated in %d ms\n", jiffies_to_msecs(jif
));
413 kref_put(&connection
->kref
, drbd_destroy_connection
);
417 /* make sure at *open* time that the respective object won't go away. */
418 static int drbd_single_open(struct file
*file
, int (*show
)(struct seq_file
*, void *),
419 void *data
, struct kref
*kref
,
420 void (*release
)(struct kref
*))
422 struct dentry
*parent
;
425 /* Are we still linked,
426 * or has debugfs_remove() already been called? */
427 parent
= file
->f_path
.dentry
->d_parent
;
428 /* serialize with d_delete() */
429 inode_lock(d_inode(parent
));
430 /* Make sure the object is still alive */
431 if (simple_positive(file
->f_path
.dentry
)
432 && kref_get_unless_zero(kref
))
434 inode_unlock(d_inode(parent
));
436 ret
= single_open(file
, show
, data
);
438 kref_put(kref
, release
);
443 static int in_flight_summary_open(struct inode
*inode
, struct file
*file
)
445 struct drbd_resource
*resource
= inode
->i_private
;
446 return drbd_single_open(file
, in_flight_summary_show
, resource
,
447 &resource
->kref
, drbd_destroy_resource
);
450 static int in_flight_summary_release(struct inode
*inode
, struct file
*file
)
452 struct drbd_resource
*resource
= inode
->i_private
;
453 kref_put(&resource
->kref
, drbd_destroy_resource
);
454 return single_release(inode
, file
);
457 static const struct file_operations in_flight_summary_fops
= {
458 .owner
= THIS_MODULE
,
459 .open
= in_flight_summary_open
,
462 .release
= in_flight_summary_release
,
465 void drbd_debugfs_resource_add(struct drbd_resource
*resource
)
467 struct dentry
*dentry
;
469 dentry
= debugfs_create_dir(resource
->name
, drbd_debugfs_resources
);
470 resource
->debugfs_res
= dentry
;
472 dentry
= debugfs_create_dir("volumes", resource
->debugfs_res
);
473 resource
->debugfs_res_volumes
= dentry
;
475 dentry
= debugfs_create_dir("connections", resource
->debugfs_res
);
476 resource
->debugfs_res_connections
= dentry
;
478 dentry
= debugfs_create_file("in_flight_summary", 0440,
479 resource
->debugfs_res
, resource
,
480 &in_flight_summary_fops
);
481 resource
->debugfs_res_in_flight_summary
= dentry
;
484 static void drbd_debugfs_remove(struct dentry
**dp
)
490 void drbd_debugfs_resource_cleanup(struct drbd_resource
*resource
)
492 /* it is ok to call debugfs_remove(NULL) */
493 drbd_debugfs_remove(&resource
->debugfs_res_in_flight_summary
);
494 drbd_debugfs_remove(&resource
->debugfs_res_connections
);
495 drbd_debugfs_remove(&resource
->debugfs_res_volumes
);
496 drbd_debugfs_remove(&resource
->debugfs_res
);
499 static void seq_print_one_timing_detail(struct seq_file
*m
,
500 const struct drbd_thread_timing_details
*tdp
,
503 struct drbd_thread_timing_details td
;
505 * use temporary assignment to get at consistent data. */
508 } while (td
.cb_nr
!= tdp
->cb_nr
);
511 seq_printf(m
, "%u\t%d\t%s:%u\t%ps\n",
513 jiffies_to_msecs(now
- td
.start_jif
),
514 td
.caller_fn
, td
.line
,
518 static void seq_print_timing_details(struct seq_file
*m
,
520 unsigned int cb_nr
, struct drbd_thread_timing_details
*tdp
, unsigned long now
)
522 unsigned int start_idx
;
525 seq_printf(m
, "%s\n", title
);
526 /* If not much is going on, this will result in natural ordering.
527 * If it is very busy, we will possibly skip events, or even see wrap
528 * arounds, which could only be avoided with locking.
530 start_idx
= cb_nr
% DRBD_THREAD_DETAILS_HIST
;
531 for (i
= start_idx
; i
< DRBD_THREAD_DETAILS_HIST
; i
++)
532 seq_print_one_timing_detail(m
, tdp
+i
, now
);
533 for (i
= 0; i
< start_idx
; i
++)
534 seq_print_one_timing_detail(m
, tdp
+i
, now
);
537 static int callback_history_show(struct seq_file
*m
, void *ignored
)
539 struct drbd_connection
*connection
= m
->private;
540 unsigned long jif
= jiffies
;
542 /* BUMP me if you change the file format/content/presentation */
543 seq_printf(m
, "v: %u\n\n", 0);
545 seq_puts(m
, "n\tage\tcallsite\tfn\n");
546 seq_print_timing_details(m
, "worker", connection
->w_cb_nr
, connection
->w_timing_details
, jif
);
547 seq_print_timing_details(m
, "receiver", connection
->r_cb_nr
, connection
->r_timing_details
, jif
);
551 static int callback_history_open(struct inode
*inode
, struct file
*file
)
553 struct drbd_connection
*connection
= inode
->i_private
;
554 return drbd_single_open(file
, callback_history_show
, connection
,
555 &connection
->kref
, drbd_destroy_connection
);
558 static int callback_history_release(struct inode
*inode
, struct file
*file
)
560 struct drbd_connection
*connection
= inode
->i_private
;
561 kref_put(&connection
->kref
, drbd_destroy_connection
);
562 return single_release(inode
, file
);
565 static const struct file_operations connection_callback_history_fops
= {
566 .owner
= THIS_MODULE
,
567 .open
= callback_history_open
,
570 .release
= callback_history_release
,
573 static int connection_oldest_requests_show(struct seq_file
*m
, void *ignored
)
575 struct drbd_connection
*connection
= m
->private;
576 unsigned long now
= jiffies
;
577 struct drbd_request
*r1
, *r2
;
579 /* BUMP me if you change the file format/content/presentation */
580 seq_printf(m
, "v: %u\n\n", 0);
582 spin_lock_irq(&connection
->resource
->req_lock
);
583 r1
= connection
->req_next
;
585 seq_print_minor_vnr_req(m
, r1
, now
);
586 r2
= connection
->req_ack_pending
;
587 if (r2
&& r2
!= r1
) {
589 seq_print_minor_vnr_req(m
, r1
, now
);
591 r2
= connection
->req_not_net_done
;
593 seq_print_minor_vnr_req(m
, r2
, now
);
594 spin_unlock_irq(&connection
->resource
->req_lock
);
598 static int connection_oldest_requests_open(struct inode
*inode
, struct file
*file
)
600 struct drbd_connection
*connection
= inode
->i_private
;
601 return drbd_single_open(file
, connection_oldest_requests_show
, connection
,
602 &connection
->kref
, drbd_destroy_connection
);
605 static int connection_oldest_requests_release(struct inode
*inode
, struct file
*file
)
607 struct drbd_connection
*connection
= inode
->i_private
;
608 kref_put(&connection
->kref
, drbd_destroy_connection
);
609 return single_release(inode
, file
);
612 static const struct file_operations connection_oldest_requests_fops
= {
613 .owner
= THIS_MODULE
,
614 .open
= connection_oldest_requests_open
,
617 .release
= connection_oldest_requests_release
,
620 void drbd_debugfs_connection_add(struct drbd_connection
*connection
)
622 struct dentry
*conns_dir
= connection
->resource
->debugfs_res_connections
;
623 struct dentry
*dentry
;
625 /* Once we enable mutliple peers,
626 * these connections will have descriptive names.
627 * For now, it is just the one connection to the (only) "peer". */
628 dentry
= debugfs_create_dir("peer", conns_dir
);
629 connection
->debugfs_conn
= dentry
;
631 dentry
= debugfs_create_file("callback_history", 0440,
632 connection
->debugfs_conn
, connection
,
633 &connection_callback_history_fops
);
634 connection
->debugfs_conn_callback_history
= dentry
;
636 dentry
= debugfs_create_file("oldest_requests", 0440,
637 connection
->debugfs_conn
, connection
,
638 &connection_oldest_requests_fops
);
639 connection
->debugfs_conn_oldest_requests
= dentry
;
642 void drbd_debugfs_connection_cleanup(struct drbd_connection
*connection
)
644 drbd_debugfs_remove(&connection
->debugfs_conn_callback_history
);
645 drbd_debugfs_remove(&connection
->debugfs_conn_oldest_requests
);
646 drbd_debugfs_remove(&connection
->debugfs_conn
);
649 static void resync_dump_detail(struct seq_file
*m
, struct lc_element
*e
)
651 struct bm_extent
*bme
= lc_entry(e
, struct bm_extent
, lce
);
653 seq_printf(m
, "%5d %s %s %s", bme
->rs_left
,
654 test_bit(BME_NO_WRITES
, &bme
->flags
) ? "NO_WRITES" : "---------",
655 test_bit(BME_LOCKED
, &bme
->flags
) ? "LOCKED" : "------",
656 test_bit(BME_PRIORITY
, &bme
->flags
) ? "PRIORITY" : "--------"
660 static int device_resync_extents_show(struct seq_file
*m
, void *ignored
)
662 struct drbd_device
*device
= m
->private;
664 /* BUMP me if you change the file format/content/presentation */
665 seq_printf(m
, "v: %u\n\n", 0);
667 if (get_ldev_if_state(device
, D_FAILED
)) {
668 lc_seq_printf_stats(m
, device
->resync
);
669 lc_seq_dump_details(m
, device
->resync
, "rs_left flags", resync_dump_detail
);
675 static int device_act_log_extents_show(struct seq_file
*m
, void *ignored
)
677 struct drbd_device
*device
= m
->private;
679 /* BUMP me if you change the file format/content/presentation */
680 seq_printf(m
, "v: %u\n\n", 0);
682 if (get_ldev_if_state(device
, D_FAILED
)) {
683 lc_seq_printf_stats(m
, device
->act_log
);
684 lc_seq_dump_details(m
, device
->act_log
, "", NULL
);
690 static int device_oldest_requests_show(struct seq_file
*m
, void *ignored
)
692 struct drbd_device
*device
= m
->private;
693 struct drbd_resource
*resource
= device
->resource
;
694 unsigned long now
= jiffies
;
695 struct drbd_request
*r1
, *r2
;
698 /* BUMP me if you change the file format/content/presentation */
699 seq_printf(m
, "v: %u\n\n", 0);
702 spin_lock_irq(&resource
->req_lock
);
703 /* WRITE, then READ */
704 for (i
= 1; i
>= 0; --i
) {
705 r1
= list_first_entry_or_null(&device
->pending_master_completion
[i
],
706 struct drbd_request
, req_pending_master_completion
);
707 r2
= list_first_entry_or_null(&device
->pending_completion
[i
],
708 struct drbd_request
, req_pending_local
);
710 seq_print_one_request(m
, r1
, now
);
712 seq_print_one_request(m
, r2
, now
);
714 spin_unlock_irq(&resource
->req_lock
);
718 static int device_data_gen_id_show(struct seq_file
*m
, void *ignored
)
720 struct drbd_device
*device
= m
->private;
722 enum drbd_uuid_index idx
;
724 if (!get_ldev_if_state(device
, D_FAILED
))
727 md
= &device
->ldev
->md
;
728 spin_lock_irq(&md
->uuid_lock
);
729 for (idx
= UI_CURRENT
; idx
<= UI_HISTORY_END
; idx
++) {
730 seq_printf(m
, "0x%016llX\n", md
->uuid
[idx
]);
732 spin_unlock_irq(&md
->uuid_lock
);
737 static int device_ed_gen_id_show(struct seq_file
*m
, void *ignored
)
739 struct drbd_device
*device
= m
->private;
740 seq_printf(m
, "0x%016llX\n", (unsigned long long)device
->ed_uuid
);
744 #define drbd_debugfs_device_attr(name) \
745 static int device_ ## name ## _open(struct inode *inode, struct file *file) \
747 struct drbd_device *device = inode->i_private; \
748 return drbd_single_open(file, device_ ## name ## _show, device, \
749 &device->kref, drbd_destroy_device); \
751 static int device_ ## name ## _release(struct inode *inode, struct file *file) \
753 struct drbd_device *device = inode->i_private; \
754 kref_put(&device->kref, drbd_destroy_device); \
755 return single_release(inode, file); \
757 static const struct file_operations device_ ## name ## _fops = { \
758 .owner = THIS_MODULE, \
759 .open = device_ ## name ## _open, \
761 .llseek = seq_lseek, \
762 .release = device_ ## name ## _release, \
765 drbd_debugfs_device_attr(oldest_requests
)
766 drbd_debugfs_device_attr(act_log_extents
)
767 drbd_debugfs_device_attr(resync_extents
)
768 drbd_debugfs_device_attr(data_gen_id
)
769 drbd_debugfs_device_attr(ed_gen_id
)
771 void drbd_debugfs_device_add(struct drbd_device
*device
)
773 struct dentry
*vols_dir
= device
->resource
->debugfs_res_volumes
;
774 char minor_buf
[8]; /* MINORMASK, MINORBITS == 20; */
775 char vnr_buf
[8]; /* volume number vnr is even 16 bit only; */
776 char *slink_name
= NULL
;
778 struct dentry
*dentry
;
779 if (!vols_dir
|| !drbd_debugfs_minors
)
782 snprintf(vnr_buf
, sizeof(vnr_buf
), "%u", device
->vnr
);
783 dentry
= debugfs_create_dir(vnr_buf
, vols_dir
);
784 device
->debugfs_vol
= dentry
;
786 snprintf(minor_buf
, sizeof(minor_buf
), "%u", device
->minor
);
787 slink_name
= kasprintf(GFP_KERNEL
, "../resources/%s/volumes/%u",
788 device
->resource
->name
, device
->vnr
);
791 dentry
= debugfs_create_symlink(minor_buf
, drbd_debugfs_minors
, slink_name
);
792 device
->debugfs_minor
= dentry
;
796 #define DCF(name) do { \
797 dentry = debugfs_create_file(#name, 0440, \
798 device->debugfs_vol, device, \
799 &device_ ## name ## _fops); \
800 device->debugfs_vol_ ## name = dentry; \
803 DCF(oldest_requests
);
804 DCF(act_log_extents
);
812 drbd_debugfs_device_cleanup(device
);
813 drbd_err(device
, "failed to create debugfs entries\n");
816 void drbd_debugfs_device_cleanup(struct drbd_device
*device
)
818 drbd_debugfs_remove(&device
->debugfs_minor
);
819 drbd_debugfs_remove(&device
->debugfs_vol_oldest_requests
);
820 drbd_debugfs_remove(&device
->debugfs_vol_act_log_extents
);
821 drbd_debugfs_remove(&device
->debugfs_vol_resync_extents
);
822 drbd_debugfs_remove(&device
->debugfs_vol_data_gen_id
);
823 drbd_debugfs_remove(&device
->debugfs_vol_ed_gen_id
);
824 drbd_debugfs_remove(&device
->debugfs_vol
);
827 void drbd_debugfs_peer_device_add(struct drbd_peer_device
*peer_device
)
829 struct dentry
*conn_dir
= peer_device
->connection
->debugfs_conn
;
830 struct dentry
*dentry
;
833 snprintf(vnr_buf
, sizeof(vnr_buf
), "%u", peer_device
->device
->vnr
);
834 dentry
= debugfs_create_dir(vnr_buf
, conn_dir
);
835 peer_device
->debugfs_peer_dev
= dentry
;
838 void drbd_debugfs_peer_device_cleanup(struct drbd_peer_device
*peer_device
)
840 drbd_debugfs_remove(&peer_device
->debugfs_peer_dev
);
843 static int drbd_version_show(struct seq_file
*m
, void *ignored
)
845 seq_printf(m
, "# %s\n", drbd_buildtag());
846 seq_printf(m
, "VERSION=%s\n", REL_VERSION
);
847 seq_printf(m
, "API_VERSION=%u\n", API_VERSION
);
848 seq_printf(m
, "PRO_VERSION_MIN=%u\n", PRO_VERSION_MIN
);
849 seq_printf(m
, "PRO_VERSION_MAX=%u\n", PRO_VERSION_MAX
);
853 static int drbd_version_open(struct inode
*inode
, struct file
*file
)
855 return single_open(file
, drbd_version_show
, NULL
);
858 static const struct file_operations drbd_version_fops
= {
859 .owner
= THIS_MODULE
,
860 .open
= drbd_version_open
,
863 .release
= single_release
,
866 /* not __exit, may be indirectly called
867 * from the module-load-failure path as well. */
868 void drbd_debugfs_cleanup(void)
870 drbd_debugfs_remove(&drbd_debugfs_resources
);
871 drbd_debugfs_remove(&drbd_debugfs_minors
);
872 drbd_debugfs_remove(&drbd_debugfs_version
);
873 drbd_debugfs_remove(&drbd_debugfs_root
);
876 void __init
drbd_debugfs_init(void)
878 struct dentry
*dentry
;
880 dentry
= debugfs_create_dir("drbd", NULL
);
881 drbd_debugfs_root
= dentry
;
883 dentry
= debugfs_create_file("version", 0444, drbd_debugfs_root
, NULL
, &drbd_version_fops
);
884 drbd_debugfs_version
= dentry
;
886 dentry
= debugfs_create_dir("resources", drbd_debugfs_root
);
887 drbd_debugfs_resources
= dentry
;
889 dentry
= debugfs_create_dir("minors", drbd_debugfs_root
);
890 drbd_debugfs_minors
= dentry
;