1 #define pr_fmt(fmt) "drbd debugfs: " fmt
2 #include <linux/kernel.h>
3 #include <linux/module.h>
4 #include <linux/debugfs.h>
5 #include <linux/seq_file.h>
6 #include <linux/stat.h>
7 #include <linux/jiffies.h>
8 #include <linux/list.h>
12 #include "drbd_debugfs.h"
15 /**********************************************************************
16 * Whenever you change the file format, remember to bump the version. *
17 **********************************************************************/
19 static struct dentry
*drbd_debugfs_root
;
20 static struct dentry
*drbd_debugfs_version
;
21 static struct dentry
*drbd_debugfs_resources
;
22 static struct dentry
*drbd_debugfs_minors
;
24 static void seq_print_age_or_dash(struct seq_file
*m
, bool valid
, unsigned long dt
)
27 seq_printf(m
, "\t%d", jiffies_to_msecs(dt
));
32 static void __seq_print_rq_state_bit(struct seq_file
*m
,
33 bool is_set
, char *sep
, const char *set_name
, const char *unset_name
)
35 if (is_set
&& set_name
) {
37 seq_puts(m
, set_name
);
39 } else if (!is_set
&& unset_name
) {
41 seq_puts(m
, unset_name
);
46 static void seq_print_rq_state_bit(struct seq_file
*m
,
47 bool is_set
, char *sep
, const char *set_name
)
49 __seq_print_rq_state_bit(m
, is_set
, sep
, set_name
, NULL
);
52 /* pretty print enum drbd_req_state_bits req->rq_state */
53 static void seq_print_request_state(struct seq_file
*m
, struct drbd_request
*req
)
55 unsigned int s
= req
->rq_state
;
57 seq_printf(m
, "\t0x%08x", s
);
58 seq_printf(m
, "\tmaster: %s", req
->master_bio
? "pending" : "completed");
60 /* RQ_WRITE ignored, already reported */
61 seq_puts(m
, "\tlocal:");
62 seq_print_rq_state_bit(m
, s
& RQ_IN_ACT_LOG
, &sep
, "in-AL");
63 seq_print_rq_state_bit(m
, s
& RQ_POSTPONED
, &sep
, "postponed");
64 seq_print_rq_state_bit(m
, s
& RQ_COMPLETION_SUSP
, &sep
, "suspended");
66 seq_print_rq_state_bit(m
, s
& RQ_LOCAL_PENDING
, &sep
, "pending");
67 seq_print_rq_state_bit(m
, s
& RQ_LOCAL_COMPLETED
, &sep
, "completed");
68 seq_print_rq_state_bit(m
, s
& RQ_LOCAL_ABORTED
, &sep
, "aborted");
69 seq_print_rq_state_bit(m
, s
& RQ_LOCAL_OK
, &sep
, "ok");
73 /* for_each_connection ... */
74 seq_printf(m
, "\tnet:");
76 seq_print_rq_state_bit(m
, s
& RQ_NET_PENDING
, &sep
, "pending");
77 seq_print_rq_state_bit(m
, s
& RQ_NET_QUEUED
, &sep
, "queued");
78 seq_print_rq_state_bit(m
, s
& RQ_NET_SENT
, &sep
, "sent");
79 seq_print_rq_state_bit(m
, s
& RQ_NET_DONE
, &sep
, "done");
80 seq_print_rq_state_bit(m
, s
& RQ_NET_SIS
, &sep
, "sis");
81 seq_print_rq_state_bit(m
, s
& RQ_NET_OK
, &sep
, "ok");
87 seq_print_rq_state_bit(m
, s
& RQ_EXP_RECEIVE_ACK
, &sep
, "B");
88 seq_print_rq_state_bit(m
, s
& RQ_EXP_WRITE_ACK
, &sep
, "C");
89 seq_print_rq_state_bit(m
, s
& RQ_EXP_BARR_ACK
, &sep
, "barr");
95 static void seq_print_one_request(struct seq_file
*m
, struct drbd_request
*req
, unsigned long now
)
97 /* change anything here, fixup header below! */
98 unsigned int s
= req
->rq_state
;
100 #define RQ_HDR_1 "epoch\tsector\tsize\trw"
101 seq_printf(m
, "0x%x\t%llu\t%u\t%s",
103 (unsigned long long)req
->i
.sector
, req
->i
.size
>> 9,
104 (s
& RQ_WRITE
) ? "W" : "R");
106 #define RQ_HDR_2 "\tstart\tin AL\tsubmit"
107 seq_printf(m
, "\t%d", jiffies_to_msecs(now
- req
->start_jif
));
108 seq_print_age_or_dash(m
, s
& RQ_IN_ACT_LOG
, now
- req
->in_actlog_jif
);
109 seq_print_age_or_dash(m
, s
& RQ_LOCAL_PENDING
, now
- req
->pre_submit_jif
);
111 #define RQ_HDR_3 "\tsent\tacked\tdone"
112 seq_print_age_or_dash(m
, s
& RQ_NET_SENT
, now
- req
->pre_send_jif
);
113 seq_print_age_or_dash(m
, (s
& RQ_NET_SENT
) && !(s
& RQ_NET_PENDING
), now
- req
->acked_jif
);
114 seq_print_age_or_dash(m
, s
& RQ_NET_DONE
, now
- req
->net_done_jif
);
116 #define RQ_HDR_4 "\tstate\n"
117 seq_print_request_state(m
, req
);
119 #define RQ_HDR RQ_HDR_1 RQ_HDR_2 RQ_HDR_3 RQ_HDR_4
121 static void seq_print_minor_vnr_req(struct seq_file
*m
, struct drbd_request
*req
, unsigned long now
)
123 seq_printf(m
, "%u\t%u\t", req
->device
->minor
, req
->device
->vnr
);
124 seq_print_one_request(m
, req
, now
);
127 static void seq_print_resource_pending_meta_io(struct seq_file
*m
, struct drbd_resource
*resource
, unsigned long now
)
129 struct drbd_device
*device
;
132 seq_puts(m
, "minor\tvnr\tstart\tsubmit\tintent\n");
134 idr_for_each_entry(&resource
->devices
, device
, i
) {
135 struct drbd_md_io tmp
;
136 /* In theory this is racy,
137 * in the sense that there could have been a
138 * drbd_md_put_buffer(); drbd_md_get_buffer();
139 * between accessing these members here. */
141 if (atomic_read(&tmp
.in_use
)) {
142 seq_printf(m
, "%u\t%u\t%d\t",
143 device
->minor
, device
->vnr
,
144 jiffies_to_msecs(now
- tmp
.start_jif
));
145 if (time_before(tmp
.submit_jif
, tmp
.start_jif
))
148 seq_printf(m
, "%d\t", jiffies_to_msecs(now
- tmp
.submit_jif
));
149 seq_printf(m
, "%s\n", tmp
.current_use
);
155 static void seq_print_waiting_for_AL(struct seq_file
*m
, struct drbd_resource
*resource
, unsigned long now
)
157 struct drbd_device
*device
;
160 seq_puts(m
, "minor\tvnr\tage\t#waiting\n");
162 idr_for_each_entry(&resource
->devices
, device
, i
) {
164 struct drbd_request
*req
;
165 int n
= atomic_read(&device
->ap_actlog_cnt
);
167 spin_lock_irq(&device
->resource
->req_lock
);
168 req
= list_first_entry_or_null(&device
->pending_master_completion
[1],
169 struct drbd_request
, req_pending_master_completion
);
170 /* if the oldest request does not wait for the activity log
171 * it is not interesting for us here */
172 if (req
&& !(req
->rq_state
& RQ_IN_ACT_LOG
))
173 jif
= req
->start_jif
;
176 spin_unlock_irq(&device
->resource
->req_lock
);
179 seq_printf(m
, "%u\t%u\t", device
->minor
, device
->vnr
);
181 seq_printf(m
, "%u\t", jiffies_to_msecs(now
- jif
));
184 seq_printf(m
, "%u\n", n
);
190 static void seq_print_device_bitmap_io(struct seq_file
*m
, struct drbd_device
*device
, unsigned long now
)
192 struct drbd_bm_aio_ctx
*ctx
;
193 unsigned long start_jif
;
194 unsigned int in_flight
;
196 spin_lock_irq(&device
->resource
->req_lock
);
197 ctx
= list_first_entry_or_null(&device
->pending_bitmap_io
, struct drbd_bm_aio_ctx
, list
);
198 if (ctx
&& ctx
->done
)
201 start_jif
= ctx
->start_jif
;
202 in_flight
= atomic_read(&ctx
->in_flight
);
205 spin_unlock_irq(&device
->resource
->req_lock
);
207 seq_printf(m
, "%u\t%u\t%c\t%u\t%u\n",
208 device
->minor
, device
->vnr
,
209 (flags
& BM_AIO_READ
) ? 'R' : 'W',
210 jiffies_to_msecs(now
- start_jif
),
215 static void seq_print_resource_pending_bitmap_io(struct seq_file
*m
, struct drbd_resource
*resource
, unsigned long now
)
217 struct drbd_device
*device
;
220 seq_puts(m
, "minor\tvnr\trw\tage\t#in-flight\n");
222 idr_for_each_entry(&resource
->devices
, device
, i
) {
223 seq_print_device_bitmap_io(m
, device
, now
);
228 /* pretty print enum peer_req->flags */
229 static void seq_print_peer_request_flags(struct seq_file
*m
, struct drbd_peer_request
*peer_req
)
231 unsigned long f
= peer_req
->flags
;
234 __seq_print_rq_state_bit(m
, f
& EE_SUBMITTED
, &sep
, "submitted", "preparing");
235 __seq_print_rq_state_bit(m
, f
& EE_APPLICATION
, &sep
, "application", "internal");
236 seq_print_rq_state_bit(m
, f
& EE_CALL_AL_COMPLETE_IO
, &sep
, "in-AL");
237 seq_print_rq_state_bit(m
, f
& EE_SEND_WRITE_ACK
, &sep
, "C");
238 seq_print_rq_state_bit(m
, f
& EE_MAY_SET_IN_SYNC
, &sep
, "set-in-sync");
239 seq_print_rq_state_bit(m
, f
& EE_WRITE_SAME
, &sep
, "write-same");
243 static void seq_print_peer_request(struct seq_file
*m
,
244 struct drbd_device
*device
, struct list_head
*lh
,
247 bool reported_preparing
= false;
248 struct drbd_peer_request
*peer_req
;
249 list_for_each_entry(peer_req
, lh
, w
.list
) {
250 if (reported_preparing
&& !(peer_req
->flags
& EE_SUBMITTED
))
254 seq_printf(m
, "%u\t%u\t", device
->minor
, device
->vnr
);
256 seq_printf(m
, "%llu\t%u\t%c\t%u\t",
257 (unsigned long long)peer_req
->i
.sector
, peer_req
->i
.size
>> 9,
258 (peer_req
->flags
& EE_WRITE
) ? 'W' : 'R',
259 jiffies_to_msecs(now
- peer_req
->submit_jif
));
260 seq_print_peer_request_flags(m
, peer_req
);
261 if (peer_req
->flags
& EE_SUBMITTED
)
264 reported_preparing
= true;
268 static void seq_print_device_peer_requests(struct seq_file
*m
,
269 struct drbd_device
*device
, unsigned long now
)
271 seq_puts(m
, "minor\tvnr\tsector\tsize\trw\tage\tflags\n");
272 spin_lock_irq(&device
->resource
->req_lock
);
273 seq_print_peer_request(m
, device
, &device
->active_ee
, now
);
274 seq_print_peer_request(m
, device
, &device
->read_ee
, now
);
275 seq_print_peer_request(m
, device
, &device
->sync_ee
, now
);
276 spin_unlock_irq(&device
->resource
->req_lock
);
277 if (test_bit(FLUSH_PENDING
, &device
->flags
)) {
278 seq_printf(m
, "%u\t%u\t-\t-\tF\t%u\tflush\n",
279 device
->minor
, device
->vnr
,
280 jiffies_to_msecs(now
- device
->flush_jif
));
284 static void seq_print_resource_pending_peer_requests(struct seq_file
*m
,
285 struct drbd_resource
*resource
, unsigned long now
)
287 struct drbd_device
*device
;
291 idr_for_each_entry(&resource
->devices
, device
, i
) {
292 seq_print_device_peer_requests(m
, device
, now
);
297 static void seq_print_resource_transfer_log_summary(struct seq_file
*m
,
298 struct drbd_resource
*resource
,
299 struct drbd_connection
*connection
,
302 struct drbd_request
*req
;
303 unsigned int count
= 0;
304 unsigned int show_state
= 0;
306 seq_puts(m
, "n\tdevice\tvnr\t" RQ_HDR
);
307 spin_lock_irq(&resource
->req_lock
);
308 list_for_each_entry(req
, &connection
->transfer_log
, tl_requests
) {
309 unsigned int tmp
= 0;
313 /* don't disable irq "forever" */
314 if (!(count
& 0x1ff)) {
315 struct drbd_request
*req_next
;
316 kref_get(&req
->kref
);
317 spin_unlock_irq(&resource
->req_lock
);
319 spin_lock_irq(&resource
->req_lock
);
320 req_next
= list_next_entry(req
, tl_requests
);
321 if (kref_put(&req
->kref
, drbd_req_destroy
))
323 if (&req
->tl_requests
== &connection
->transfer_log
)
329 /* This is meant to summarize timing issues, to be able to tell
330 * local disk problems from network problems.
331 * Skip requests, if we have shown an even older request with
332 * similar aspects already. */
333 if (req
->master_bio
== NULL
)
335 if ((s
& RQ_LOCAL_MASK
) && (s
& RQ_LOCAL_PENDING
))
337 if (s
& RQ_NET_MASK
) {
338 if (!(s
& RQ_NET_SENT
))
340 if (s
& RQ_NET_PENDING
)
342 if (!(s
& RQ_NET_DONE
))
345 if ((tmp
& show_state
) == tmp
)
348 seq_printf(m
, "%u\t", count
);
349 seq_print_minor_vnr_req(m
, req
, now
);
350 if (show_state
== 0x1f)
353 spin_unlock_irq(&resource
->req_lock
);
356 /* TODO: transfer_log and friends should be moved to resource */
357 static int in_flight_summary_show(struct seq_file
*m
, void *pos
)
359 struct drbd_resource
*resource
= m
->private;
360 struct drbd_connection
*connection
;
361 unsigned long jif
= jiffies
;
363 connection
= first_connection(resource
);
364 /* This does not happen, actually.
365 * But be robust and prepare for future code changes. */
366 if (!connection
|| !kref_get_unless_zero(&connection
->kref
))
369 /* BUMP me if you change the file format/content/presentation */
370 seq_printf(m
, "v: %u\n\n", 0);
372 seq_puts(m
, "oldest bitmap IO\n");
373 seq_print_resource_pending_bitmap_io(m
, resource
, jif
);
376 seq_puts(m
, "meta data IO\n");
377 seq_print_resource_pending_meta_io(m
, resource
, jif
);
380 seq_puts(m
, "socket buffer stats\n");
381 /* for each connection ... once we have more than one */
383 if (connection
->data
.socket
) {
384 /* open coded SIOCINQ, the "relevant" part */
385 struct tcp_sock
*tp
= tcp_sk(connection
->data
.socket
->sk
);
386 int answ
= tp
->rcv_nxt
- tp
->copied_seq
;
387 seq_printf(m
, "unread receive buffer: %u Byte\n", answ
);
388 /* open coded SIOCOUTQ, the "relevant" part */
389 answ
= tp
->write_seq
- tp
->snd_una
;
390 seq_printf(m
, "unacked send buffer: %u Byte\n", answ
);
395 seq_puts(m
, "oldest peer requests\n");
396 seq_print_resource_pending_peer_requests(m
, resource
, jif
);
399 seq_puts(m
, "application requests waiting for activity log\n");
400 seq_print_waiting_for_AL(m
, resource
, jif
);
403 seq_puts(m
, "oldest application requests\n");
404 seq_print_resource_transfer_log_summary(m
, resource
, connection
, jif
);
409 seq_printf(m
, "generated in %d ms\n", jiffies_to_msecs(jif
));
410 kref_put(&connection
->kref
, drbd_destroy_connection
);
414 /* make sure at *open* time that the respective object won't go away. */
415 static int drbd_single_open(struct file
*file
, int (*show
)(struct seq_file
*, void *),
416 void *data
, struct kref
*kref
,
417 void (*release
)(struct kref
*))
419 struct dentry
*parent
;
422 /* Are we still linked,
423 * or has debugfs_remove() already been called? */
424 parent
= file
->f_path
.dentry
->d_parent
;
425 /* serialize with d_delete() */
426 inode_lock(d_inode(parent
));
427 /* Make sure the object is still alive */
428 if (simple_positive(file
->f_path
.dentry
)
429 && kref_get_unless_zero(kref
))
431 inode_unlock(d_inode(parent
));
433 ret
= single_open(file
, show
, data
);
435 kref_put(kref
, release
);
440 static int in_flight_summary_open(struct inode
*inode
, struct file
*file
)
442 struct drbd_resource
*resource
= inode
->i_private
;
443 return drbd_single_open(file
, in_flight_summary_show
, resource
,
444 &resource
->kref
, drbd_destroy_resource
);
447 static int in_flight_summary_release(struct inode
*inode
, struct file
*file
)
449 struct drbd_resource
*resource
= inode
->i_private
;
450 kref_put(&resource
->kref
, drbd_destroy_resource
);
451 return single_release(inode
, file
);
454 static const struct file_operations in_flight_summary_fops
= {
455 .owner
= THIS_MODULE
,
456 .open
= in_flight_summary_open
,
459 .release
= in_flight_summary_release
,
462 void drbd_debugfs_resource_add(struct drbd_resource
*resource
)
464 struct dentry
*dentry
;
465 if (!drbd_debugfs_resources
)
468 dentry
= debugfs_create_dir(resource
->name
, drbd_debugfs_resources
);
469 if (IS_ERR_OR_NULL(dentry
))
471 resource
->debugfs_res
= dentry
;
473 dentry
= debugfs_create_dir("volumes", resource
->debugfs_res
);
474 if (IS_ERR_OR_NULL(dentry
))
476 resource
->debugfs_res_volumes
= dentry
;
478 dentry
= debugfs_create_dir("connections", resource
->debugfs_res
);
479 if (IS_ERR_OR_NULL(dentry
))
481 resource
->debugfs_res_connections
= dentry
;
483 dentry
= debugfs_create_file("in_flight_summary", S_IRUSR
|S_IRGRP
,
484 resource
->debugfs_res
, resource
,
485 &in_flight_summary_fops
);
486 if (IS_ERR_OR_NULL(dentry
))
488 resource
->debugfs_res_in_flight_summary
= dentry
;
492 drbd_debugfs_resource_cleanup(resource
);
493 drbd_err(resource
, "failed to create debugfs dentry\n");
496 static void drbd_debugfs_remove(struct dentry
**dp
)
502 void drbd_debugfs_resource_cleanup(struct drbd_resource
*resource
)
504 /* it is ok to call debugfs_remove(NULL) */
505 drbd_debugfs_remove(&resource
->debugfs_res_in_flight_summary
);
506 drbd_debugfs_remove(&resource
->debugfs_res_connections
);
507 drbd_debugfs_remove(&resource
->debugfs_res_volumes
);
508 drbd_debugfs_remove(&resource
->debugfs_res
);
511 static void seq_print_one_timing_detail(struct seq_file
*m
,
512 const struct drbd_thread_timing_details
*tdp
,
515 struct drbd_thread_timing_details td
;
517 * use temporary assignment to get at consistent data. */
520 } while (td
.cb_nr
!= tdp
->cb_nr
);
523 seq_printf(m
, "%u\t%d\t%s:%u\t%ps\n",
525 jiffies_to_msecs(now
- td
.start_jif
),
526 td
.caller_fn
, td
.line
,
530 static void seq_print_timing_details(struct seq_file
*m
,
532 unsigned int cb_nr
, struct drbd_thread_timing_details
*tdp
, unsigned long now
)
534 unsigned int start_idx
;
537 seq_printf(m
, "%s\n", title
);
538 /* If not much is going on, this will result in natural ordering.
539 * If it is very busy, we will possibly skip events, or even see wrap
540 * arounds, which could only be avoided with locking.
542 start_idx
= cb_nr
% DRBD_THREAD_DETAILS_HIST
;
543 for (i
= start_idx
; i
< DRBD_THREAD_DETAILS_HIST
; i
++)
544 seq_print_one_timing_detail(m
, tdp
+i
, now
);
545 for (i
= 0; i
< start_idx
; i
++)
546 seq_print_one_timing_detail(m
, tdp
+i
, now
);
549 static int callback_history_show(struct seq_file
*m
, void *ignored
)
551 struct drbd_connection
*connection
= m
->private;
552 unsigned long jif
= jiffies
;
554 /* BUMP me if you change the file format/content/presentation */
555 seq_printf(m
, "v: %u\n\n", 0);
557 seq_puts(m
, "n\tage\tcallsite\tfn\n");
558 seq_print_timing_details(m
, "worker", connection
->w_cb_nr
, connection
->w_timing_details
, jif
);
559 seq_print_timing_details(m
, "receiver", connection
->r_cb_nr
, connection
->r_timing_details
, jif
);
563 static int callback_history_open(struct inode
*inode
, struct file
*file
)
565 struct drbd_connection
*connection
= inode
->i_private
;
566 return drbd_single_open(file
, callback_history_show
, connection
,
567 &connection
->kref
, drbd_destroy_connection
);
570 static int callback_history_release(struct inode
*inode
, struct file
*file
)
572 struct drbd_connection
*connection
= inode
->i_private
;
573 kref_put(&connection
->kref
, drbd_destroy_connection
);
574 return single_release(inode
, file
);
577 static const struct file_operations connection_callback_history_fops
= {
578 .owner
= THIS_MODULE
,
579 .open
= callback_history_open
,
582 .release
= callback_history_release
,
585 static int connection_oldest_requests_show(struct seq_file
*m
, void *ignored
)
587 struct drbd_connection
*connection
= m
->private;
588 unsigned long now
= jiffies
;
589 struct drbd_request
*r1
, *r2
;
591 /* BUMP me if you change the file format/content/presentation */
592 seq_printf(m
, "v: %u\n\n", 0);
594 spin_lock_irq(&connection
->resource
->req_lock
);
595 r1
= connection
->req_next
;
597 seq_print_minor_vnr_req(m
, r1
, now
);
598 r2
= connection
->req_ack_pending
;
599 if (r2
&& r2
!= r1
) {
601 seq_print_minor_vnr_req(m
, r1
, now
);
603 r2
= connection
->req_not_net_done
;
605 seq_print_minor_vnr_req(m
, r2
, now
);
606 spin_unlock_irq(&connection
->resource
->req_lock
);
610 static int connection_oldest_requests_open(struct inode
*inode
, struct file
*file
)
612 struct drbd_connection
*connection
= inode
->i_private
;
613 return drbd_single_open(file
, connection_oldest_requests_show
, connection
,
614 &connection
->kref
, drbd_destroy_connection
);
617 static int connection_oldest_requests_release(struct inode
*inode
, struct file
*file
)
619 struct drbd_connection
*connection
= inode
->i_private
;
620 kref_put(&connection
->kref
, drbd_destroy_connection
);
621 return single_release(inode
, file
);
624 static const struct file_operations connection_oldest_requests_fops
= {
625 .owner
= THIS_MODULE
,
626 .open
= connection_oldest_requests_open
,
629 .release
= connection_oldest_requests_release
,
632 void drbd_debugfs_connection_add(struct drbd_connection
*connection
)
634 struct dentry
*conns_dir
= connection
->resource
->debugfs_res_connections
;
635 struct dentry
*dentry
;
639 /* Once we enable mutliple peers,
640 * these connections will have descriptive names.
641 * For now, it is just the one connection to the (only) "peer". */
642 dentry
= debugfs_create_dir("peer", conns_dir
);
643 if (IS_ERR_OR_NULL(dentry
))
645 connection
->debugfs_conn
= dentry
;
647 dentry
= debugfs_create_file("callback_history", S_IRUSR
|S_IRGRP
,
648 connection
->debugfs_conn
, connection
,
649 &connection_callback_history_fops
);
650 if (IS_ERR_OR_NULL(dentry
))
652 connection
->debugfs_conn_callback_history
= dentry
;
654 dentry
= debugfs_create_file("oldest_requests", S_IRUSR
|S_IRGRP
,
655 connection
->debugfs_conn
, connection
,
656 &connection_oldest_requests_fops
);
657 if (IS_ERR_OR_NULL(dentry
))
659 connection
->debugfs_conn_oldest_requests
= dentry
;
663 drbd_debugfs_connection_cleanup(connection
);
664 drbd_err(connection
, "failed to create debugfs dentry\n");
667 void drbd_debugfs_connection_cleanup(struct drbd_connection
*connection
)
669 drbd_debugfs_remove(&connection
->debugfs_conn_callback_history
);
670 drbd_debugfs_remove(&connection
->debugfs_conn_oldest_requests
);
671 drbd_debugfs_remove(&connection
->debugfs_conn
);
674 static void resync_dump_detail(struct seq_file
*m
, struct lc_element
*e
)
676 struct bm_extent
*bme
= lc_entry(e
, struct bm_extent
, lce
);
678 seq_printf(m
, "%5d %s %s %s", bme
->rs_left
,
679 test_bit(BME_NO_WRITES
, &bme
->flags
) ? "NO_WRITES" : "---------",
680 test_bit(BME_LOCKED
, &bme
->flags
) ? "LOCKED" : "------",
681 test_bit(BME_PRIORITY
, &bme
->flags
) ? "PRIORITY" : "--------"
685 static int device_resync_extents_show(struct seq_file
*m
, void *ignored
)
687 struct drbd_device
*device
= m
->private;
689 /* BUMP me if you change the file format/content/presentation */
690 seq_printf(m
, "v: %u\n\n", 0);
692 if (get_ldev_if_state(device
, D_FAILED
)) {
693 lc_seq_printf_stats(m
, device
->resync
);
694 lc_seq_dump_details(m
, device
->resync
, "rs_left flags", resync_dump_detail
);
700 static int device_act_log_extents_show(struct seq_file
*m
, void *ignored
)
702 struct drbd_device
*device
= m
->private;
704 /* BUMP me if you change the file format/content/presentation */
705 seq_printf(m
, "v: %u\n\n", 0);
707 if (get_ldev_if_state(device
, D_FAILED
)) {
708 lc_seq_printf_stats(m
, device
->act_log
);
709 lc_seq_dump_details(m
, device
->act_log
, "", NULL
);
715 static int device_oldest_requests_show(struct seq_file
*m
, void *ignored
)
717 struct drbd_device
*device
= m
->private;
718 struct drbd_resource
*resource
= device
->resource
;
719 unsigned long now
= jiffies
;
720 struct drbd_request
*r1
, *r2
;
723 /* BUMP me if you change the file format/content/presentation */
724 seq_printf(m
, "v: %u\n\n", 0);
727 spin_lock_irq(&resource
->req_lock
);
728 /* WRITE, then READ */
729 for (i
= 1; i
>= 0; --i
) {
730 r1
= list_first_entry_or_null(&device
->pending_master_completion
[i
],
731 struct drbd_request
, req_pending_master_completion
);
732 r2
= list_first_entry_or_null(&device
->pending_completion
[i
],
733 struct drbd_request
, req_pending_local
);
735 seq_print_one_request(m
, r1
, now
);
737 seq_print_one_request(m
, r2
, now
);
739 spin_unlock_irq(&resource
->req_lock
);
743 static int device_data_gen_id_show(struct seq_file
*m
, void *ignored
)
745 struct drbd_device
*device
= m
->private;
747 enum drbd_uuid_index idx
;
749 if (!get_ldev_if_state(device
, D_FAILED
))
752 md
= &device
->ldev
->md
;
753 spin_lock_irq(&md
->uuid_lock
);
754 for (idx
= UI_CURRENT
; idx
<= UI_HISTORY_END
; idx
++) {
755 seq_printf(m
, "0x%016llX\n", md
->uuid
[idx
]);
757 spin_unlock_irq(&md
->uuid_lock
);
762 static int device_ed_gen_id_show(struct seq_file
*m
, void *ignored
)
764 struct drbd_device
*device
= m
->private;
765 seq_printf(m
, "0x%016llX\n", (unsigned long long)device
->ed_uuid
);
769 #define drbd_debugfs_device_attr(name) \
770 static int device_ ## name ## _open(struct inode *inode, struct file *file) \
772 struct drbd_device *device = inode->i_private; \
773 return drbd_single_open(file, device_ ## name ## _show, device, \
774 &device->kref, drbd_destroy_device); \
776 static int device_ ## name ## _release(struct inode *inode, struct file *file) \
778 struct drbd_device *device = inode->i_private; \
779 kref_put(&device->kref, drbd_destroy_device); \
780 return single_release(inode, file); \
782 static const struct file_operations device_ ## name ## _fops = { \
783 .owner = THIS_MODULE, \
784 .open = device_ ## name ## _open, \
786 .llseek = seq_lseek, \
787 .release = device_ ## name ## _release, \
790 drbd_debugfs_device_attr(oldest_requests
)
791 drbd_debugfs_device_attr(act_log_extents
)
792 drbd_debugfs_device_attr(resync_extents
)
793 drbd_debugfs_device_attr(data_gen_id
)
794 drbd_debugfs_device_attr(ed_gen_id
)
796 void drbd_debugfs_device_add(struct drbd_device
*device
)
798 struct dentry
*vols_dir
= device
->resource
->debugfs_res_volumes
;
799 char minor_buf
[8]; /* MINORMASK, MINORBITS == 20; */
800 char vnr_buf
[8]; /* volume number vnr is even 16 bit only; */
801 char *slink_name
= NULL
;
803 struct dentry
*dentry
;
804 if (!vols_dir
|| !drbd_debugfs_minors
)
807 snprintf(vnr_buf
, sizeof(vnr_buf
), "%u", device
->vnr
);
808 dentry
= debugfs_create_dir(vnr_buf
, vols_dir
);
809 if (IS_ERR_OR_NULL(dentry
))
811 device
->debugfs_vol
= dentry
;
813 snprintf(minor_buf
, sizeof(minor_buf
), "%u", device
->minor
);
814 slink_name
= kasprintf(GFP_KERNEL
, "../resources/%s/volumes/%u",
815 device
->resource
->name
, device
->vnr
);
818 dentry
= debugfs_create_symlink(minor_buf
, drbd_debugfs_minors
, slink_name
);
821 if (IS_ERR_OR_NULL(dentry
))
823 device
->debugfs_minor
= dentry
;
825 #define DCF(name) do { \
826 dentry = debugfs_create_file(#name, S_IRUSR|S_IRGRP, \
827 device->debugfs_vol, device, \
828 &device_ ## name ## _fops); \
829 if (IS_ERR_OR_NULL(dentry)) \
831 device->debugfs_vol_ ## name = dentry; \
834 DCF(oldest_requests
);
835 DCF(act_log_extents
);
843 drbd_debugfs_device_cleanup(device
);
844 drbd_err(device
, "failed to create debugfs entries\n");
847 void drbd_debugfs_device_cleanup(struct drbd_device
*device
)
849 drbd_debugfs_remove(&device
->debugfs_minor
);
850 drbd_debugfs_remove(&device
->debugfs_vol_oldest_requests
);
851 drbd_debugfs_remove(&device
->debugfs_vol_act_log_extents
);
852 drbd_debugfs_remove(&device
->debugfs_vol_resync_extents
);
853 drbd_debugfs_remove(&device
->debugfs_vol_data_gen_id
);
854 drbd_debugfs_remove(&device
->debugfs_vol_ed_gen_id
);
855 drbd_debugfs_remove(&device
->debugfs_vol
);
858 void drbd_debugfs_peer_device_add(struct drbd_peer_device
*peer_device
)
860 struct dentry
*conn_dir
= peer_device
->connection
->debugfs_conn
;
861 struct dentry
*dentry
;
867 snprintf(vnr_buf
, sizeof(vnr_buf
), "%u", peer_device
->device
->vnr
);
868 dentry
= debugfs_create_dir(vnr_buf
, conn_dir
);
869 if (IS_ERR_OR_NULL(dentry
))
871 peer_device
->debugfs_peer_dev
= dentry
;
875 drbd_debugfs_peer_device_cleanup(peer_device
);
876 drbd_err(peer_device
, "failed to create debugfs entries\n");
879 void drbd_debugfs_peer_device_cleanup(struct drbd_peer_device
*peer_device
)
881 drbd_debugfs_remove(&peer_device
->debugfs_peer_dev
);
884 static int drbd_version_show(struct seq_file
*m
, void *ignored
)
886 seq_printf(m
, "# %s\n", drbd_buildtag());
887 seq_printf(m
, "VERSION=%s\n", REL_VERSION
);
888 seq_printf(m
, "API_VERSION=%u\n", API_VERSION
);
889 seq_printf(m
, "PRO_VERSION_MIN=%u\n", PRO_VERSION_MIN
);
890 seq_printf(m
, "PRO_VERSION_MAX=%u\n", PRO_VERSION_MAX
);
894 static int drbd_version_open(struct inode
*inode
, struct file
*file
)
896 return single_open(file
, drbd_version_show
, NULL
);
899 static const struct file_operations drbd_version_fops
= {
900 .owner
= THIS_MODULE
,
901 .open
= drbd_version_open
,
904 .release
= single_release
,
907 /* not __exit, may be indirectly called
908 * from the module-load-failure path as well. */
909 void drbd_debugfs_cleanup(void)
911 drbd_debugfs_remove(&drbd_debugfs_resources
);
912 drbd_debugfs_remove(&drbd_debugfs_minors
);
913 drbd_debugfs_remove(&drbd_debugfs_version
);
914 drbd_debugfs_remove(&drbd_debugfs_root
);
917 int __init
drbd_debugfs_init(void)
919 struct dentry
*dentry
;
921 dentry
= debugfs_create_dir("drbd", NULL
);
922 if (IS_ERR_OR_NULL(dentry
))
924 drbd_debugfs_root
= dentry
;
926 dentry
= debugfs_create_file("version", 0444, drbd_debugfs_root
, NULL
, &drbd_version_fops
);
927 if (IS_ERR_OR_NULL(dentry
))
929 drbd_debugfs_version
= dentry
;
931 dentry
= debugfs_create_dir("resources", drbd_debugfs_root
);
932 if (IS_ERR_OR_NULL(dentry
))
934 drbd_debugfs_resources
= dentry
;
936 dentry
= debugfs_create_dir("minors", drbd_debugfs_root
);
937 if (IS_ERR_OR_NULL(dentry
))
939 drbd_debugfs_minors
= dentry
;
943 drbd_debugfs_cleanup();
945 return PTR_ERR(dentry
);