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_WRITE_SAME
, &sep
, "write-same");
244 static void seq_print_peer_request(struct seq_file
*m
,
245 struct drbd_device
*device
, struct list_head
*lh
,
248 bool reported_preparing
= false;
249 struct drbd_peer_request
*peer_req
;
250 list_for_each_entry(peer_req
, lh
, w
.list
) {
251 if (reported_preparing
&& !(peer_req
->flags
& EE_SUBMITTED
))
255 seq_printf(m
, "%u\t%u\t", device
->minor
, device
->vnr
);
257 seq_printf(m
, "%llu\t%u\t%c\t%u\t",
258 (unsigned long long)peer_req
->i
.sector
, peer_req
->i
.size
>> 9,
259 (peer_req
->flags
& EE_WRITE
) ? 'W' : 'R',
260 jiffies_to_msecs(now
- peer_req
->submit_jif
));
261 seq_print_peer_request_flags(m
, peer_req
);
262 if (peer_req
->flags
& EE_SUBMITTED
)
265 reported_preparing
= true;
269 static void seq_print_device_peer_requests(struct seq_file
*m
,
270 struct drbd_device
*device
, unsigned long now
)
272 seq_puts(m
, "minor\tvnr\tsector\tsize\trw\tage\tflags\n");
273 spin_lock_irq(&device
->resource
->req_lock
);
274 seq_print_peer_request(m
, device
, &device
->active_ee
, now
);
275 seq_print_peer_request(m
, device
, &device
->read_ee
, now
);
276 seq_print_peer_request(m
, device
, &device
->sync_ee
, now
);
277 spin_unlock_irq(&device
->resource
->req_lock
);
278 if (test_bit(FLUSH_PENDING
, &device
->flags
)) {
279 seq_printf(m
, "%u\t%u\t-\t-\tF\t%u\tflush\n",
280 device
->minor
, device
->vnr
,
281 jiffies_to_msecs(now
- device
->flush_jif
));
285 static void seq_print_resource_pending_peer_requests(struct seq_file
*m
,
286 struct drbd_resource
*resource
, unsigned long now
)
288 struct drbd_device
*device
;
292 idr_for_each_entry(&resource
->devices
, device
, i
) {
293 seq_print_device_peer_requests(m
, device
, now
);
298 static void seq_print_resource_transfer_log_summary(struct seq_file
*m
,
299 struct drbd_resource
*resource
,
300 struct drbd_connection
*connection
,
303 struct drbd_request
*req
;
304 unsigned int count
= 0;
305 unsigned int show_state
= 0;
307 seq_puts(m
, "n\tdevice\tvnr\t" RQ_HDR
);
308 spin_lock_irq(&resource
->req_lock
);
309 list_for_each_entry(req
, &connection
->transfer_log
, tl_requests
) {
310 unsigned int tmp
= 0;
314 /* don't disable irq "forever" */
315 if (!(count
& 0x1ff)) {
316 struct drbd_request
*req_next
;
317 kref_get(&req
->kref
);
318 spin_unlock_irq(&resource
->req_lock
);
320 spin_lock_irq(&resource
->req_lock
);
321 req_next
= list_next_entry(req
, tl_requests
);
322 if (kref_put(&req
->kref
, drbd_req_destroy
))
324 if (&req
->tl_requests
== &connection
->transfer_log
)
330 /* This is meant to summarize timing issues, to be able to tell
331 * local disk problems from network problems.
332 * Skip requests, if we have shown an even older request with
333 * similar aspects already. */
334 if (req
->master_bio
== NULL
)
336 if ((s
& RQ_LOCAL_MASK
) && (s
& RQ_LOCAL_PENDING
))
338 if (s
& RQ_NET_MASK
) {
339 if (!(s
& RQ_NET_SENT
))
341 if (s
& RQ_NET_PENDING
)
343 if (!(s
& RQ_NET_DONE
))
346 if ((tmp
& show_state
) == tmp
)
349 seq_printf(m
, "%u\t", count
);
350 seq_print_minor_vnr_req(m
, req
, now
);
351 if (show_state
== 0x1f)
354 spin_unlock_irq(&resource
->req_lock
);
357 /* TODO: transfer_log and friends should be moved to resource */
358 static int in_flight_summary_show(struct seq_file
*m
, void *pos
)
360 struct drbd_resource
*resource
= m
->private;
361 struct drbd_connection
*connection
;
362 unsigned long jif
= jiffies
;
364 connection
= first_connection(resource
);
365 /* This does not happen, actually.
366 * But be robust and prepare for future code changes. */
367 if (!connection
|| !kref_get_unless_zero(&connection
->kref
))
370 /* BUMP me if you change the file format/content/presentation */
371 seq_printf(m
, "v: %u\n\n", 0);
373 seq_puts(m
, "oldest bitmap IO\n");
374 seq_print_resource_pending_bitmap_io(m
, resource
, jif
);
377 seq_puts(m
, "meta data IO\n");
378 seq_print_resource_pending_meta_io(m
, resource
, jif
);
381 seq_puts(m
, "socket buffer stats\n");
382 /* for each connection ... once we have more than one */
384 if (connection
->data
.socket
) {
385 /* open coded SIOCINQ, the "relevant" part */
386 struct tcp_sock
*tp
= tcp_sk(connection
->data
.socket
->sk
);
387 int answ
= tp
->rcv_nxt
- tp
->copied_seq
;
388 seq_printf(m
, "unread receive buffer: %u Byte\n", answ
);
389 /* open coded SIOCOUTQ, the "relevant" part */
390 answ
= tp
->write_seq
- tp
->snd_una
;
391 seq_printf(m
, "unacked send buffer: %u Byte\n", answ
);
396 seq_puts(m
, "oldest peer requests\n");
397 seq_print_resource_pending_peer_requests(m
, resource
, jif
);
400 seq_puts(m
, "application requests waiting for activity log\n");
401 seq_print_waiting_for_AL(m
, resource
, jif
);
404 seq_puts(m
, "oldest application requests\n");
405 seq_print_resource_transfer_log_summary(m
, resource
, connection
, jif
);
410 seq_printf(m
, "generated in %d ms\n", jiffies_to_msecs(jif
));
411 kref_put(&connection
->kref
, drbd_destroy_connection
);
415 /* make sure at *open* time that the respective object won't go away. */
416 static int drbd_single_open(struct file
*file
, int (*show
)(struct seq_file
*, void *),
417 void *data
, struct kref
*kref
,
418 void (*release
)(struct kref
*))
420 struct dentry
*parent
;
423 /* Are we still linked,
424 * or has debugfs_remove() already been called? */
425 parent
= file
->f_path
.dentry
->d_parent
;
426 /* serialize with d_delete() */
427 inode_lock(d_inode(parent
));
428 /* Make sure the object is still alive */
429 if (simple_positive(file
->f_path
.dentry
)
430 && kref_get_unless_zero(kref
))
432 inode_unlock(d_inode(parent
));
434 ret
= single_open(file
, show
, data
);
436 kref_put(kref
, release
);
441 static int in_flight_summary_open(struct inode
*inode
, struct file
*file
)
443 struct drbd_resource
*resource
= inode
->i_private
;
444 return drbd_single_open(file
, in_flight_summary_show
, resource
,
445 &resource
->kref
, drbd_destroy_resource
);
448 static int in_flight_summary_release(struct inode
*inode
, struct file
*file
)
450 struct drbd_resource
*resource
= inode
->i_private
;
451 kref_put(&resource
->kref
, drbd_destroy_resource
);
452 return single_release(inode
, file
);
455 static const struct file_operations in_flight_summary_fops
= {
456 .owner
= THIS_MODULE
,
457 .open
= in_flight_summary_open
,
460 .release
= in_flight_summary_release
,
463 void drbd_debugfs_resource_add(struct drbd_resource
*resource
)
465 struct dentry
*dentry
;
466 if (!drbd_debugfs_resources
)
469 dentry
= debugfs_create_dir(resource
->name
, drbd_debugfs_resources
);
470 if (IS_ERR_OR_NULL(dentry
))
472 resource
->debugfs_res
= dentry
;
474 dentry
= debugfs_create_dir("volumes", resource
->debugfs_res
);
475 if (IS_ERR_OR_NULL(dentry
))
477 resource
->debugfs_res_volumes
= dentry
;
479 dentry
= debugfs_create_dir("connections", resource
->debugfs_res
);
480 if (IS_ERR_OR_NULL(dentry
))
482 resource
->debugfs_res_connections
= dentry
;
484 dentry
= debugfs_create_file("in_flight_summary", S_IRUSR
|S_IRGRP
,
485 resource
->debugfs_res
, resource
,
486 &in_flight_summary_fops
);
487 if (IS_ERR_OR_NULL(dentry
))
489 resource
->debugfs_res_in_flight_summary
= dentry
;
493 drbd_debugfs_resource_cleanup(resource
);
494 drbd_err(resource
, "failed to create debugfs dentry\n");
497 static void drbd_debugfs_remove(struct dentry
**dp
)
503 void drbd_debugfs_resource_cleanup(struct drbd_resource
*resource
)
505 /* it is ok to call debugfs_remove(NULL) */
506 drbd_debugfs_remove(&resource
->debugfs_res_in_flight_summary
);
507 drbd_debugfs_remove(&resource
->debugfs_res_connections
);
508 drbd_debugfs_remove(&resource
->debugfs_res_volumes
);
509 drbd_debugfs_remove(&resource
->debugfs_res
);
512 static void seq_print_one_timing_detail(struct seq_file
*m
,
513 const struct drbd_thread_timing_details
*tdp
,
516 struct drbd_thread_timing_details td
;
518 * use temporary assignment to get at consistent data. */
521 } while (td
.cb_nr
!= tdp
->cb_nr
);
524 seq_printf(m
, "%u\t%d\t%s:%u\t%ps\n",
526 jiffies_to_msecs(now
- td
.start_jif
),
527 td
.caller_fn
, td
.line
,
531 static void seq_print_timing_details(struct seq_file
*m
,
533 unsigned int cb_nr
, struct drbd_thread_timing_details
*tdp
, unsigned long now
)
535 unsigned int start_idx
;
538 seq_printf(m
, "%s\n", title
);
539 /* If not much is going on, this will result in natural ordering.
540 * If it is very busy, we will possibly skip events, or even see wrap
541 * arounds, which could only be avoided with locking.
543 start_idx
= cb_nr
% DRBD_THREAD_DETAILS_HIST
;
544 for (i
= start_idx
; i
< DRBD_THREAD_DETAILS_HIST
; i
++)
545 seq_print_one_timing_detail(m
, tdp
+i
, now
);
546 for (i
= 0; i
< start_idx
; i
++)
547 seq_print_one_timing_detail(m
, tdp
+i
, now
);
550 static int callback_history_show(struct seq_file
*m
, void *ignored
)
552 struct drbd_connection
*connection
= m
->private;
553 unsigned long jif
= jiffies
;
555 /* BUMP me if you change the file format/content/presentation */
556 seq_printf(m
, "v: %u\n\n", 0);
558 seq_puts(m
, "n\tage\tcallsite\tfn\n");
559 seq_print_timing_details(m
, "worker", connection
->w_cb_nr
, connection
->w_timing_details
, jif
);
560 seq_print_timing_details(m
, "receiver", connection
->r_cb_nr
, connection
->r_timing_details
, jif
);
564 static int callback_history_open(struct inode
*inode
, struct file
*file
)
566 struct drbd_connection
*connection
= inode
->i_private
;
567 return drbd_single_open(file
, callback_history_show
, connection
,
568 &connection
->kref
, drbd_destroy_connection
);
571 static int callback_history_release(struct inode
*inode
, struct file
*file
)
573 struct drbd_connection
*connection
= inode
->i_private
;
574 kref_put(&connection
->kref
, drbd_destroy_connection
);
575 return single_release(inode
, file
);
578 static const struct file_operations connection_callback_history_fops
= {
579 .owner
= THIS_MODULE
,
580 .open
= callback_history_open
,
583 .release
= callback_history_release
,
586 static int connection_oldest_requests_show(struct seq_file
*m
, void *ignored
)
588 struct drbd_connection
*connection
= m
->private;
589 unsigned long now
= jiffies
;
590 struct drbd_request
*r1
, *r2
;
592 /* BUMP me if you change the file format/content/presentation */
593 seq_printf(m
, "v: %u\n\n", 0);
595 spin_lock_irq(&connection
->resource
->req_lock
);
596 r1
= connection
->req_next
;
598 seq_print_minor_vnr_req(m
, r1
, now
);
599 r2
= connection
->req_ack_pending
;
600 if (r2
&& r2
!= r1
) {
602 seq_print_minor_vnr_req(m
, r1
, now
);
604 r2
= connection
->req_not_net_done
;
606 seq_print_minor_vnr_req(m
, r2
, now
);
607 spin_unlock_irq(&connection
->resource
->req_lock
);
611 static int connection_oldest_requests_open(struct inode
*inode
, struct file
*file
)
613 struct drbd_connection
*connection
= inode
->i_private
;
614 return drbd_single_open(file
, connection_oldest_requests_show
, connection
,
615 &connection
->kref
, drbd_destroy_connection
);
618 static int connection_oldest_requests_release(struct inode
*inode
, struct file
*file
)
620 struct drbd_connection
*connection
= inode
->i_private
;
621 kref_put(&connection
->kref
, drbd_destroy_connection
);
622 return single_release(inode
, file
);
625 static const struct file_operations connection_oldest_requests_fops
= {
626 .owner
= THIS_MODULE
,
627 .open
= connection_oldest_requests_open
,
630 .release
= connection_oldest_requests_release
,
633 void drbd_debugfs_connection_add(struct drbd_connection
*connection
)
635 struct dentry
*conns_dir
= connection
->resource
->debugfs_res_connections
;
636 struct dentry
*dentry
;
640 /* Once we enable mutliple peers,
641 * these connections will have descriptive names.
642 * For now, it is just the one connection to the (only) "peer". */
643 dentry
= debugfs_create_dir("peer", conns_dir
);
644 if (IS_ERR_OR_NULL(dentry
))
646 connection
->debugfs_conn
= dentry
;
648 dentry
= debugfs_create_file("callback_history", S_IRUSR
|S_IRGRP
,
649 connection
->debugfs_conn
, connection
,
650 &connection_callback_history_fops
);
651 if (IS_ERR_OR_NULL(dentry
))
653 connection
->debugfs_conn_callback_history
= dentry
;
655 dentry
= debugfs_create_file("oldest_requests", S_IRUSR
|S_IRGRP
,
656 connection
->debugfs_conn
, connection
,
657 &connection_oldest_requests_fops
);
658 if (IS_ERR_OR_NULL(dentry
))
660 connection
->debugfs_conn_oldest_requests
= dentry
;
664 drbd_debugfs_connection_cleanup(connection
);
665 drbd_err(connection
, "failed to create debugfs dentry\n");
668 void drbd_debugfs_connection_cleanup(struct drbd_connection
*connection
)
670 drbd_debugfs_remove(&connection
->debugfs_conn_callback_history
);
671 drbd_debugfs_remove(&connection
->debugfs_conn_oldest_requests
);
672 drbd_debugfs_remove(&connection
->debugfs_conn
);
675 static void resync_dump_detail(struct seq_file
*m
, struct lc_element
*e
)
677 struct bm_extent
*bme
= lc_entry(e
, struct bm_extent
, lce
);
679 seq_printf(m
, "%5d %s %s %s", bme
->rs_left
,
680 test_bit(BME_NO_WRITES
, &bme
->flags
) ? "NO_WRITES" : "---------",
681 test_bit(BME_LOCKED
, &bme
->flags
) ? "LOCKED" : "------",
682 test_bit(BME_PRIORITY
, &bme
->flags
) ? "PRIORITY" : "--------"
686 static int device_resync_extents_show(struct seq_file
*m
, void *ignored
)
688 struct drbd_device
*device
= m
->private;
690 /* BUMP me if you change the file format/content/presentation */
691 seq_printf(m
, "v: %u\n\n", 0);
693 if (get_ldev_if_state(device
, D_FAILED
)) {
694 lc_seq_printf_stats(m
, device
->resync
);
695 lc_seq_dump_details(m
, device
->resync
, "rs_left flags", resync_dump_detail
);
701 static int device_act_log_extents_show(struct seq_file
*m
, void *ignored
)
703 struct drbd_device
*device
= m
->private;
705 /* BUMP me if you change the file format/content/presentation */
706 seq_printf(m
, "v: %u\n\n", 0);
708 if (get_ldev_if_state(device
, D_FAILED
)) {
709 lc_seq_printf_stats(m
, device
->act_log
);
710 lc_seq_dump_details(m
, device
->act_log
, "", NULL
);
716 static int device_oldest_requests_show(struct seq_file
*m
, void *ignored
)
718 struct drbd_device
*device
= m
->private;
719 struct drbd_resource
*resource
= device
->resource
;
720 unsigned long now
= jiffies
;
721 struct drbd_request
*r1
, *r2
;
724 /* BUMP me if you change the file format/content/presentation */
725 seq_printf(m
, "v: %u\n\n", 0);
728 spin_lock_irq(&resource
->req_lock
);
729 /* WRITE, then READ */
730 for (i
= 1; i
>= 0; --i
) {
731 r1
= list_first_entry_or_null(&device
->pending_master_completion
[i
],
732 struct drbd_request
, req_pending_master_completion
);
733 r2
= list_first_entry_or_null(&device
->pending_completion
[i
],
734 struct drbd_request
, req_pending_local
);
736 seq_print_one_request(m
, r1
, now
);
738 seq_print_one_request(m
, r2
, now
);
740 spin_unlock_irq(&resource
->req_lock
);
744 static int device_data_gen_id_show(struct seq_file
*m
, void *ignored
)
746 struct drbd_device
*device
= m
->private;
748 enum drbd_uuid_index idx
;
750 if (!get_ldev_if_state(device
, D_FAILED
))
753 md
= &device
->ldev
->md
;
754 spin_lock_irq(&md
->uuid_lock
);
755 for (idx
= UI_CURRENT
; idx
<= UI_HISTORY_END
; idx
++) {
756 seq_printf(m
, "0x%016llX\n", md
->uuid
[idx
]);
758 spin_unlock_irq(&md
->uuid_lock
);
763 static int device_ed_gen_id_show(struct seq_file
*m
, void *ignored
)
765 struct drbd_device
*device
= m
->private;
766 seq_printf(m
, "0x%016llX\n", (unsigned long long)device
->ed_uuid
);
770 #define drbd_debugfs_device_attr(name) \
771 static int device_ ## name ## _open(struct inode *inode, struct file *file) \
773 struct drbd_device *device = inode->i_private; \
774 return drbd_single_open(file, device_ ## name ## _show, device, \
775 &device->kref, drbd_destroy_device); \
777 static int device_ ## name ## _release(struct inode *inode, struct file *file) \
779 struct drbd_device *device = inode->i_private; \
780 kref_put(&device->kref, drbd_destroy_device); \
781 return single_release(inode, file); \
783 static const struct file_operations device_ ## name ## _fops = { \
784 .owner = THIS_MODULE, \
785 .open = device_ ## name ## _open, \
787 .llseek = seq_lseek, \
788 .release = device_ ## name ## _release, \
791 drbd_debugfs_device_attr(oldest_requests
)
792 drbd_debugfs_device_attr(act_log_extents
)
793 drbd_debugfs_device_attr(resync_extents
)
794 drbd_debugfs_device_attr(data_gen_id
)
795 drbd_debugfs_device_attr(ed_gen_id
)
797 void drbd_debugfs_device_add(struct drbd_device
*device
)
799 struct dentry
*vols_dir
= device
->resource
->debugfs_res_volumes
;
800 char minor_buf
[8]; /* MINORMASK, MINORBITS == 20; */
801 char vnr_buf
[8]; /* volume number vnr is even 16 bit only; */
802 char *slink_name
= NULL
;
804 struct dentry
*dentry
;
805 if (!vols_dir
|| !drbd_debugfs_minors
)
808 snprintf(vnr_buf
, sizeof(vnr_buf
), "%u", device
->vnr
);
809 dentry
= debugfs_create_dir(vnr_buf
, vols_dir
);
810 if (IS_ERR_OR_NULL(dentry
))
812 device
->debugfs_vol
= dentry
;
814 snprintf(minor_buf
, sizeof(minor_buf
), "%u", device
->minor
);
815 slink_name
= kasprintf(GFP_KERNEL
, "../resources/%s/volumes/%u",
816 device
->resource
->name
, device
->vnr
);
819 dentry
= debugfs_create_symlink(minor_buf
, drbd_debugfs_minors
, slink_name
);
822 if (IS_ERR_OR_NULL(dentry
))
824 device
->debugfs_minor
= dentry
;
826 #define DCF(name) do { \
827 dentry = debugfs_create_file(#name, S_IRUSR|S_IRGRP, \
828 device->debugfs_vol, device, \
829 &device_ ## name ## _fops); \
830 if (IS_ERR_OR_NULL(dentry)) \
832 device->debugfs_vol_ ## name = dentry; \
835 DCF(oldest_requests
);
836 DCF(act_log_extents
);
844 drbd_debugfs_device_cleanup(device
);
845 drbd_err(device
, "failed to create debugfs entries\n");
848 void drbd_debugfs_device_cleanup(struct drbd_device
*device
)
850 drbd_debugfs_remove(&device
->debugfs_minor
);
851 drbd_debugfs_remove(&device
->debugfs_vol_oldest_requests
);
852 drbd_debugfs_remove(&device
->debugfs_vol_act_log_extents
);
853 drbd_debugfs_remove(&device
->debugfs_vol_resync_extents
);
854 drbd_debugfs_remove(&device
->debugfs_vol_data_gen_id
);
855 drbd_debugfs_remove(&device
->debugfs_vol_ed_gen_id
);
856 drbd_debugfs_remove(&device
->debugfs_vol
);
859 void drbd_debugfs_peer_device_add(struct drbd_peer_device
*peer_device
)
861 struct dentry
*conn_dir
= peer_device
->connection
->debugfs_conn
;
862 struct dentry
*dentry
;
868 snprintf(vnr_buf
, sizeof(vnr_buf
), "%u", peer_device
->device
->vnr
);
869 dentry
= debugfs_create_dir(vnr_buf
, conn_dir
);
870 if (IS_ERR_OR_NULL(dentry
))
872 peer_device
->debugfs_peer_dev
= dentry
;
876 drbd_debugfs_peer_device_cleanup(peer_device
);
877 drbd_err(peer_device
, "failed to create debugfs entries\n");
880 void drbd_debugfs_peer_device_cleanup(struct drbd_peer_device
*peer_device
)
882 drbd_debugfs_remove(&peer_device
->debugfs_peer_dev
);
885 static int drbd_version_show(struct seq_file
*m
, void *ignored
)
887 seq_printf(m
, "# %s\n", drbd_buildtag());
888 seq_printf(m
, "VERSION=%s\n", REL_VERSION
);
889 seq_printf(m
, "API_VERSION=%u\n", API_VERSION
);
890 seq_printf(m
, "PRO_VERSION_MIN=%u\n", PRO_VERSION_MIN
);
891 seq_printf(m
, "PRO_VERSION_MAX=%u\n", PRO_VERSION_MAX
);
895 static int drbd_version_open(struct inode
*inode
, struct file
*file
)
897 return single_open(file
, drbd_version_show
, NULL
);
900 static const struct file_operations drbd_version_fops
= {
901 .owner
= THIS_MODULE
,
902 .open
= drbd_version_open
,
905 .release
= single_release
,
908 /* not __exit, may be indirectly called
909 * from the module-load-failure path as well. */
910 void drbd_debugfs_cleanup(void)
912 drbd_debugfs_remove(&drbd_debugfs_resources
);
913 drbd_debugfs_remove(&drbd_debugfs_minors
);
914 drbd_debugfs_remove(&drbd_debugfs_version
);
915 drbd_debugfs_remove(&drbd_debugfs_root
);
918 int __init
drbd_debugfs_init(void)
920 struct dentry
*dentry
;
922 dentry
= debugfs_create_dir("drbd", NULL
);
923 if (IS_ERR_OR_NULL(dentry
))
925 drbd_debugfs_root
= dentry
;
927 dentry
= debugfs_create_file("version", 0444, drbd_debugfs_root
, NULL
, &drbd_version_fops
);
928 if (IS_ERR_OR_NULL(dentry
))
930 drbd_debugfs_version
= dentry
;
932 dentry
= debugfs_create_dir("resources", drbd_debugfs_root
);
933 if (IS_ERR_OR_NULL(dentry
))
935 drbd_debugfs_resources
= dentry
;
937 dentry
= debugfs_create_dir("minors", drbd_debugfs_root
);
938 if (IS_ERR_OR_NULL(dentry
))
940 drbd_debugfs_minors
= dentry
;
944 drbd_debugfs_cleanup();
946 return PTR_ERR(dentry
);