diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2014-05-02 07:19:51 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2014-07-10 12:35:16 -0400 |
commit | 4d3d5aa83aa45f1c7c9644b30e3a67e42c26695f (patch) | |
tree | 1789c8cdcc14a08208234c5131713db6a1640a4a /drivers/block/drbd | |
parent | 4ce4926683b820c5c85b8033891dbfb53cc8754f (diff) |
drbd: debugfs: add basic hierarchy
Add new debugfs hierarchy /sys/kernel/debug/
drbd/
resources/
$resource_name/connections/peer/$volume_number/
$resource_name/volumes/$volume_number/
minors/$minor_number -> ../resources/$resource_name/volumes/$volume_number/
Followup commits will populate this hierarchy with files containing
statistics, diagnostic information and some attribute data.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/Makefile | 1 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_debugfs.c | 191 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_debugfs.h | 39 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 30 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 22 |
5 files changed, 278 insertions, 5 deletions
diff --git a/drivers/block/drbd/Makefile b/drivers/block/drbd/Makefile index 8b450338075e..4464e353c1e8 100644 --- a/drivers/block/drbd/Makefile +++ b/drivers/block/drbd/Makefile | |||
@@ -3,5 +3,6 @@ drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o | |||
3 | drbd-y += drbd_main.o drbd_strings.o drbd_nl.o | 3 | drbd-y += drbd_main.o drbd_strings.o drbd_nl.o |
4 | drbd-y += drbd_interval.o drbd_state.o | 4 | drbd-y += drbd_interval.o drbd_state.o |
5 | drbd-y += drbd_nla.o | 5 | drbd-y += drbd_nla.o |
6 | drbd-$(CONFIG_DEBUG_FS) += drbd_debugfs.o | ||
6 | 7 | ||
7 | obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o | 8 | obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o |
diff --git a/drivers/block/drbd/drbd_debugfs.c b/drivers/block/drbd/drbd_debugfs.c new file mode 100644 index 000000000000..9b120c3d9703 --- /dev/null +++ b/drivers/block/drbd/drbd_debugfs.c | |||
@@ -0,0 +1,191 @@ | |||
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/stat.h> | ||
6 | #include <linux/list.h> | ||
7 | |||
8 | #include "drbd_int.h" | ||
9 | #include "drbd_req.h" | ||
10 | #include "drbd_debugfs.h" | ||
11 | |||
12 | static struct dentry *drbd_debugfs_root; | ||
13 | static struct dentry *drbd_debugfs_resources; | ||
14 | static struct dentry *drbd_debugfs_minors; | ||
15 | |||
16 | void drbd_debugfs_resource_add(struct drbd_resource *resource) | ||
17 | { | ||
18 | struct dentry *dentry; | ||
19 | if (!drbd_debugfs_resources) | ||
20 | return; | ||
21 | |||
22 | dentry = debugfs_create_dir(resource->name, drbd_debugfs_resources); | ||
23 | if (IS_ERR_OR_NULL(dentry)) | ||
24 | goto fail; | ||
25 | resource->debugfs_res = dentry; | ||
26 | |||
27 | dentry = debugfs_create_dir("volumes", resource->debugfs_res); | ||
28 | if (IS_ERR_OR_NULL(dentry)) | ||
29 | goto fail; | ||
30 | resource->debugfs_res_volumes = dentry; | ||
31 | |||
32 | dentry = debugfs_create_dir("connections", resource->debugfs_res); | ||
33 | if (IS_ERR_OR_NULL(dentry)) | ||
34 | goto fail; | ||
35 | resource->debugfs_res_connections = dentry; | ||
36 | |||
37 | return; | ||
38 | |||
39 | fail: | ||
40 | drbd_debugfs_resource_cleanup(resource); | ||
41 | drbd_err(resource, "failed to create debugfs dentry\n"); | ||
42 | } | ||
43 | |||
44 | static void drbd_debugfs_remove(struct dentry **dp) | ||
45 | { | ||
46 | debugfs_remove(*dp); | ||
47 | *dp = NULL; | ||
48 | } | ||
49 | |||
50 | void drbd_debugfs_resource_cleanup(struct drbd_resource *resource) | ||
51 | { | ||
52 | /* it is ok to call debugfs_remove(NULL) */ | ||
53 | drbd_debugfs_remove(&resource->debugfs_res_in_flight_summary); | ||
54 | drbd_debugfs_remove(&resource->debugfs_res_connections); | ||
55 | drbd_debugfs_remove(&resource->debugfs_res_volumes); | ||
56 | drbd_debugfs_remove(&resource->debugfs_res); | ||
57 | } | ||
58 | |||
59 | void drbd_debugfs_connection_add(struct drbd_connection *connection) | ||
60 | { | ||
61 | struct dentry *conns_dir = connection->resource->debugfs_res_connections; | ||
62 | struct dentry *dentry; | ||
63 | if (!conns_dir) | ||
64 | return; | ||
65 | |||
66 | /* Once we enable mutliple peers, | ||
67 | * these connections will have descriptive names. | ||
68 | * For now, it is just the one connection to the (only) "peer". */ | ||
69 | dentry = debugfs_create_dir("peer", conns_dir); | ||
70 | if (IS_ERR_OR_NULL(dentry)) | ||
71 | goto fail; | ||
72 | connection->debugfs_conn = dentry; | ||
73 | return; | ||
74 | |||
75 | fail: | ||
76 | drbd_debugfs_connection_cleanup(connection); | ||
77 | drbd_err(connection, "failed to create debugfs dentry\n"); | ||
78 | } | ||
79 | |||
80 | void drbd_debugfs_connection_cleanup(struct drbd_connection *connection) | ||
81 | { | ||
82 | drbd_debugfs_remove(&connection->debugfs_conn_callback_history); | ||
83 | drbd_debugfs_remove(&connection->debugfs_conn_oldest_requests); | ||
84 | drbd_debugfs_remove(&connection->debugfs_conn); | ||
85 | } | ||
86 | |||
87 | void drbd_debugfs_device_add(struct drbd_device *device) | ||
88 | { | ||
89 | struct dentry *vols_dir = device->resource->debugfs_res_volumes; | ||
90 | char minor_buf[8]; /* MINORMASK, MINORBITS == 20; */ | ||
91 | char vnr_buf[8]; /* volume number vnr is even 16 bit only; */ | ||
92 | char *slink_name = NULL; | ||
93 | |||
94 | struct dentry *dentry; | ||
95 | if (!vols_dir || !drbd_debugfs_minors) | ||
96 | return; | ||
97 | |||
98 | snprintf(vnr_buf, sizeof(vnr_buf), "%u", device->vnr); | ||
99 | dentry = debugfs_create_dir(vnr_buf, vols_dir); | ||
100 | if (IS_ERR_OR_NULL(dentry)) | ||
101 | goto fail; | ||
102 | device->debugfs_vol = dentry; | ||
103 | |||
104 | snprintf(minor_buf, sizeof(minor_buf), "%u", device->minor); | ||
105 | slink_name = kasprintf(GFP_KERNEL, "../resources/%s/volumes/%u", | ||
106 | device->resource->name, device->vnr); | ||
107 | if (!slink_name) | ||
108 | goto fail; | ||
109 | dentry = debugfs_create_symlink(minor_buf, drbd_debugfs_minors, slink_name); | ||
110 | if (IS_ERR_OR_NULL(dentry)) | ||
111 | goto fail; | ||
112 | device->debugfs_minor = dentry; | ||
113 | kfree(slink_name); | ||
114 | |||
115 | fail: | ||
116 | drbd_debugfs_device_cleanup(device); | ||
117 | drbd_err(device, "failed to create debugfs entries\n"); | ||
118 | } | ||
119 | |||
120 | void drbd_debugfs_device_cleanup(struct drbd_device *device) | ||
121 | { | ||
122 | drbd_debugfs_remove(&device->debugfs_minor); | ||
123 | drbd_debugfs_remove(&device->debugfs_vol_oldest_requests); | ||
124 | drbd_debugfs_remove(&device->debugfs_vol_act_log_extents); | ||
125 | drbd_debugfs_remove(&device->debugfs_vol_resync_extents); | ||
126 | drbd_debugfs_remove(&device->debugfs_vol_data_gen_id); | ||
127 | drbd_debugfs_remove(&device->debugfs_vol); | ||
128 | } | ||
129 | |||
130 | void drbd_debugfs_peer_device_add(struct drbd_peer_device *peer_device) | ||
131 | { | ||
132 | struct dentry *conn_dir = peer_device->connection->debugfs_conn; | ||
133 | struct dentry *dentry; | ||
134 | char vnr_buf[8]; | ||
135 | |||
136 | if (!conn_dir) | ||
137 | return; | ||
138 | |||
139 | snprintf(vnr_buf, sizeof(vnr_buf), "%u", peer_device->device->vnr); | ||
140 | dentry = debugfs_create_dir(vnr_buf, conn_dir); | ||
141 | if (IS_ERR_OR_NULL(dentry)) | ||
142 | goto fail; | ||
143 | peer_device->debugfs_peer_dev = dentry; | ||
144 | return; | ||
145 | |||
146 | fail: | ||
147 | drbd_debugfs_peer_device_cleanup(peer_device); | ||
148 | drbd_err(peer_device, "failed to create debugfs entries\n"); | ||
149 | } | ||
150 | |||
151 | void drbd_debugfs_peer_device_cleanup(struct drbd_peer_device *peer_device) | ||
152 | { | ||
153 | drbd_debugfs_remove(&peer_device->debugfs_peer_dev); | ||
154 | } | ||
155 | |||
156 | /* not __exit, may be indirectly called | ||
157 | * from the module-load-failure path as well. */ | ||
158 | void drbd_debugfs_cleanup(void) | ||
159 | { | ||
160 | drbd_debugfs_remove(&drbd_debugfs_resources); | ||
161 | drbd_debugfs_remove(&drbd_debugfs_minors); | ||
162 | drbd_debugfs_remove(&drbd_debugfs_root); | ||
163 | } | ||
164 | |||
165 | int __init drbd_debugfs_init(void) | ||
166 | { | ||
167 | struct dentry *dentry; | ||
168 | |||
169 | dentry = debugfs_create_dir("drbd", NULL); | ||
170 | if (IS_ERR_OR_NULL(dentry)) | ||
171 | goto fail; | ||
172 | drbd_debugfs_root = dentry; | ||
173 | |||
174 | dentry = debugfs_create_dir("resources", drbd_debugfs_root); | ||
175 | if (IS_ERR_OR_NULL(dentry)) | ||
176 | goto fail; | ||
177 | drbd_debugfs_resources = dentry; | ||
178 | |||
179 | dentry = debugfs_create_dir("minors", drbd_debugfs_root); | ||
180 | if (IS_ERR_OR_NULL(dentry)) | ||
181 | goto fail; | ||
182 | drbd_debugfs_minors = dentry; | ||
183 | return 0; | ||
184 | |||
185 | fail: | ||
186 | drbd_debugfs_cleanup(); | ||
187 | if (dentry) | ||
188 | return PTR_ERR(dentry); | ||
189 | else | ||
190 | return -EINVAL; | ||
191 | } | ||
diff --git a/drivers/block/drbd/drbd_debugfs.h b/drivers/block/drbd/drbd_debugfs.h new file mode 100644 index 000000000000..8bee21340dce --- /dev/null +++ b/drivers/block/drbd/drbd_debugfs.h | |||
@@ -0,0 +1,39 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/debugfs.h> | ||
4 | |||
5 | #include "drbd_int.h" | ||
6 | |||
7 | #ifdef CONFIG_DEBUG_FS | ||
8 | int __init drbd_debugfs_init(void); | ||
9 | void drbd_debugfs_cleanup(void); | ||
10 | |||
11 | void drbd_debugfs_resource_add(struct drbd_resource *resource); | ||
12 | void drbd_debugfs_resource_cleanup(struct drbd_resource *resource); | ||
13 | |||
14 | void drbd_debugfs_connection_add(struct drbd_connection *connection); | ||
15 | void drbd_debugfs_connection_cleanup(struct drbd_connection *connection); | ||
16 | |||
17 | void drbd_debugfs_device_add(struct drbd_device *device); | ||
18 | void drbd_debugfs_device_cleanup(struct drbd_device *device); | ||
19 | |||
20 | void drbd_debugfs_peer_device_add(struct drbd_peer_device *peer_device); | ||
21 | void drbd_debugfs_peer_device_cleanup(struct drbd_peer_device *peer_device); | ||
22 | #else | ||
23 | |||
24 | static inline int __init drbd_debugfs_init(void) { return -ENODEV; } | ||
25 | static inline void drbd_debugfs_cleanup(void) { } | ||
26 | |||
27 | static inline void drbd_debugfs_resource_add(struct drbd_resource *resource) { } | ||
28 | static inline void drbd_debugfs_resource_cleanup(struct drbd_resource *resource) { } | ||
29 | |||
30 | static inline void drbd_debugfs_connection_add(struct drbd_connection *connection) { } | ||
31 | static inline void drbd_debugfs_connection_cleanup(struct drbd_connection *connection) { } | ||
32 | |||
33 | static inline void drbd_debugfs_device_add(struct drbd_device *device) { } | ||
34 | static inline void drbd_debugfs_device_cleanup(struct drbd_device *device) { } | ||
35 | |||
36 | static inline void drbd_debugfs_peer_device_add(struct drbd_peer_device *peer_device) { } | ||
37 | static inline void drbd_debugfs_peer_device_cleanup(struct drbd_peer_device *peer_device) { } | ||
38 | |||
39 | #endif | ||
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 40c816ce8d75..20f2b38e97b9 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -670,6 +670,12 @@ enum { | |||
670 | 670 | ||
671 | struct drbd_resource { | 671 | struct drbd_resource { |
672 | char *name; | 672 | char *name; |
673 | #ifdef CONFIG_DEBUG_FS | ||
674 | struct dentry *debugfs_res; | ||
675 | struct dentry *debugfs_res_volumes; | ||
676 | struct dentry *debugfs_res_connections; | ||
677 | struct dentry *debugfs_res_in_flight_summary; | ||
678 | #endif | ||
673 | struct kref kref; | 679 | struct kref kref; |
674 | struct idr devices; /* volume number to device mapping */ | 680 | struct idr devices; /* volume number to device mapping */ |
675 | struct list_head connections; | 681 | struct list_head connections; |
@@ -691,6 +697,11 @@ struct drbd_resource { | |||
691 | struct drbd_connection { | 697 | struct drbd_connection { |
692 | struct list_head connections; | 698 | struct list_head connections; |
693 | struct drbd_resource *resource; | 699 | struct drbd_resource *resource; |
700 | #ifdef CONFIG_DEBUG_FS | ||
701 | struct dentry *debugfs_conn; | ||
702 | struct dentry *debugfs_conn_callback_history; | ||
703 | struct dentry *debugfs_conn_oldest_requests; | ||
704 | #endif | ||
694 | struct kref kref; | 705 | struct kref kref; |
695 | struct idr peer_devices; /* volume number to peer device mapping */ | 706 | struct idr peer_devices; /* volume number to peer device mapping */ |
696 | enum drbd_conns cstate; /* Only C_STANDALONE to C_WF_REPORT_PARAMS */ | 707 | enum drbd_conns cstate; /* Only C_STANDALONE to C_WF_REPORT_PARAMS */ |
@@ -772,13 +783,29 @@ struct drbd_peer_device { | |||
772 | struct list_head peer_devices; | 783 | struct list_head peer_devices; |
773 | struct drbd_device *device; | 784 | struct drbd_device *device; |
774 | struct drbd_connection *connection; | 785 | struct drbd_connection *connection; |
786 | #ifdef CONFIG_DEBUG_FS | ||
787 | struct dentry *debugfs_peer_dev; | ||
788 | #endif | ||
775 | }; | 789 | }; |
776 | 790 | ||
777 | struct drbd_device { | 791 | struct drbd_device { |
778 | struct drbd_resource *resource; | 792 | struct drbd_resource *resource; |
779 | struct list_head peer_devices; | 793 | struct list_head peer_devices; |
780 | struct list_head pending_bitmap_io; | 794 | struct list_head pending_bitmap_io; |
781 | int vnr; /* volume number within the connection */ | 795 | |
796 | unsigned long flush_jif; | ||
797 | #ifdef CONFIG_DEBUG_FS | ||
798 | struct dentry *debugfs_minor; | ||
799 | struct dentry *debugfs_vol; | ||
800 | struct dentry *debugfs_vol_oldest_requests; | ||
801 | struct dentry *debugfs_vol_act_log_extents; | ||
802 | struct dentry *debugfs_vol_resync_extents; | ||
803 | struct dentry *debugfs_vol_data_gen_id; | ||
804 | #endif | ||
805 | |||
806 | unsigned int vnr; /* volume number within the connection */ | ||
807 | unsigned int minor; /* device minor number */ | ||
808 | |||
782 | struct kref kref; | 809 | struct kref kref; |
783 | 810 | ||
784 | /* things that are stored as / read from meta data on disk */ | 811 | /* things that are stored as / read from meta data on disk */ |
@@ -895,7 +922,6 @@ struct drbd_device { | |||
895 | atomic_t packet_seq; | 922 | atomic_t packet_seq; |
896 | unsigned int peer_seq; | 923 | unsigned int peer_seq; |
897 | spinlock_t peer_seq_lock; | 924 | spinlock_t peer_seq_lock; |
898 | unsigned int minor; | ||
899 | unsigned long comm_bm_set; /* communicated number of set bits. */ | 925 | unsigned long comm_bm_set; /* communicated number of set bits. */ |
900 | struct bm_io_work bm_io_work; | 926 | struct bm_io_work bm_io_work; |
901 | u64 ed_uuid; /* UUID of the exposed data */ | 927 | u64 ed_uuid; /* UUID of the exposed data */ |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 922d631c10b3..01de57ec0110 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -57,8 +57,8 @@ | |||
57 | #include "drbd_int.h" | 57 | #include "drbd_int.h" |
58 | #include "drbd_protocol.h" | 58 | #include "drbd_protocol.h" |
59 | #include "drbd_req.h" /* only for _req_mod in tl_release and tl_clear */ | 59 | #include "drbd_req.h" /* only for _req_mod in tl_release and tl_clear */ |
60 | |||
61 | #include "drbd_vli.h" | 60 | #include "drbd_vli.h" |
61 | #include "drbd_debugfs.h" | ||
62 | 62 | ||
63 | static DEFINE_MUTEX(drbd_main_mutex); | 63 | static DEFINE_MUTEX(drbd_main_mutex); |
64 | static int drbd_open(struct block_device *bdev, fmode_t mode); | 64 | static int drbd_open(struct block_device *bdev, fmode_t mode); |
@@ -2308,8 +2308,10 @@ void drbd_free_resource(struct drbd_resource *resource) | |||
2308 | 2308 | ||
2309 | for_each_connection_safe(connection, tmp, resource) { | 2309 | for_each_connection_safe(connection, tmp, resource) { |
2310 | list_del(&connection->connections); | 2310 | list_del(&connection->connections); |
2311 | drbd_debugfs_connection_cleanup(connection); | ||
2311 | kref_put(&connection->kref, drbd_destroy_connection); | 2312 | kref_put(&connection->kref, drbd_destroy_connection); |
2312 | } | 2313 | } |
2314 | drbd_debugfs_resource_cleanup(resource); | ||
2313 | kref_put(&resource->kref, drbd_destroy_resource); | 2315 | kref_put(&resource->kref, drbd_destroy_resource); |
2314 | } | 2316 | } |
2315 | 2317 | ||
@@ -2334,6 +2336,7 @@ static void drbd_cleanup(void) | |||
2334 | destroy_workqueue(retry.wq); | 2336 | destroy_workqueue(retry.wq); |
2335 | 2337 | ||
2336 | drbd_genl_unregister(); | 2338 | drbd_genl_unregister(); |
2339 | drbd_debugfs_cleanup(); | ||
2337 | 2340 | ||
2338 | idr_for_each_entry(&drbd_devices, device, i) | 2341 | idr_for_each_entry(&drbd_devices, device, i) |
2339 | drbd_delete_device(device); | 2342 | drbd_delete_device(device); |
@@ -2583,6 +2586,7 @@ struct drbd_resource *drbd_create_resource(const char *name) | |||
2583 | mutex_init(&resource->conf_update); | 2586 | mutex_init(&resource->conf_update); |
2584 | mutex_init(&resource->adm_mutex); | 2587 | mutex_init(&resource->adm_mutex); |
2585 | spin_lock_init(&resource->req_lock); | 2588 | spin_lock_init(&resource->req_lock); |
2589 | drbd_debugfs_resource_add(resource); | ||
2586 | return resource; | 2590 | return resource; |
2587 | 2591 | ||
2588 | fail_free_name: | 2592 | fail_free_name: |
@@ -2593,7 +2597,7 @@ fail: | |||
2593 | return NULL; | 2597 | return NULL; |
2594 | } | 2598 | } |
2595 | 2599 | ||
2596 | /* caller must be under genl_lock() */ | 2600 | /* caller must be under adm_mutex */ |
2597 | struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts) | 2601 | struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts) |
2598 | { | 2602 | { |
2599 | struct drbd_resource *resource; | 2603 | struct drbd_resource *resource; |
@@ -2651,6 +2655,7 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts) | |||
2651 | 2655 | ||
2652 | kref_get(&resource->kref); | 2656 | kref_get(&resource->kref); |
2653 | list_add_tail_rcu(&connection->connections, &resource->connections); | 2657 | list_add_tail_rcu(&connection->connections, &resource->connections); |
2658 | drbd_debugfs_connection_add(connection); | ||
2654 | return connection; | 2659 | return connection; |
2655 | 2660 | ||
2656 | fail_resource: | 2661 | fail_resource: |
@@ -2829,7 +2834,10 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig | |||
2829 | for_each_peer_device(peer_device, device) | 2834 | for_each_peer_device(peer_device, device) |
2830 | drbd_connected(peer_device); | 2835 | drbd_connected(peer_device); |
2831 | } | 2836 | } |
2832 | 2837 | /* move to create_peer_device() */ | |
2838 | for_each_peer_device(peer_device, device) | ||
2839 | drbd_debugfs_peer_device_add(peer_device); | ||
2840 | drbd_debugfs_device_add(device); | ||
2833 | return NO_ERROR; | 2841 | return NO_ERROR; |
2834 | 2842 | ||
2835 | out_idr_remove_vol: | 2843 | out_idr_remove_vol: |
@@ -2868,8 +2876,13 @@ void drbd_delete_device(struct drbd_device *device) | |||
2868 | { | 2876 | { |
2869 | struct drbd_resource *resource = device->resource; | 2877 | struct drbd_resource *resource = device->resource; |
2870 | struct drbd_connection *connection; | 2878 | struct drbd_connection *connection; |
2879 | struct drbd_peer_device *peer_device; | ||
2871 | int refs = 3; | 2880 | int refs = 3; |
2872 | 2881 | ||
2882 | /* move to free_peer_device() */ | ||
2883 | for_each_peer_device(peer_device, device) | ||
2884 | drbd_debugfs_peer_device_cleanup(peer_device); | ||
2885 | drbd_debugfs_device_cleanup(device); | ||
2873 | for_each_connection(connection, resource) { | 2886 | for_each_connection(connection, resource) { |
2874 | idr_remove(&connection->peer_devices, device->vnr); | 2887 | idr_remove(&connection->peer_devices, device->vnr); |
2875 | refs++; | 2888 | refs++; |
@@ -2938,6 +2951,9 @@ static int __init drbd_init(void) | |||
2938 | spin_lock_init(&retry.lock); | 2951 | spin_lock_init(&retry.lock); |
2939 | INIT_LIST_HEAD(&retry.writes); | 2952 | INIT_LIST_HEAD(&retry.writes); |
2940 | 2953 | ||
2954 | if (drbd_debugfs_init()) | ||
2955 | pr_notice("failed to initialize debugfs -- will not be available\n"); | ||
2956 | |||
2941 | pr_info("initialized. " | 2957 | pr_info("initialized. " |
2942 | "Version: " REL_VERSION " (api:%d/proto:%d-%d)\n", | 2958 | "Version: " REL_VERSION " (api:%d/proto:%d-%d)\n", |
2943 | API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX); | 2959 | API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX); |