Blame view
net/batman-adv/debugfs.c
13.7 KB
e19f9759e
|
1 |
/* Copyright (C) 2010-2014 B.A.T.M.A.N. contributors: |
c6c8fea29
|
2 3 4 5 6 7 8 9 10 11 12 13 14 |
* * Marek Lindner * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License |
ebf38fb7a
|
15 |
* along with this program; if not, see <http://www.gnu.org/licenses/>. |
c6c8fea29
|
16 17 18 19 20 |
*/ #include "main.h" #include <linux/debugfs.h> |
b706b13b6
|
21 |
#include "debugfs.h" |
c6c8fea29
|
22 23 24 25 26 27 |
#include "translation-table.h" #include "originator.h" #include "hard-interface.h" #include "gateway_common.h" #include "gateway_client.h" #include "soft-interface.h" |
c6c8fea29
|
28 |
#include "icmp_socket.h" |
9bf8e4d42
|
29 |
#include "bridge_loop_avoidance.h" |
2f1dfbe18
|
30 |
#include "distributed-arp-table.h" |
d56b1705e
|
31 |
#include "network-coding.h" |
c6c8fea29
|
32 |
|
9e466250e
|
33 |
static struct dentry *batadv_debugfs; |
c6c8fea29
|
34 35 |
#ifdef CONFIG_BATMAN_ADV_DEBUG |
347c80f0f
|
36 |
#define BATADV_LOG_BUFF_MASK (batadv_log_buff_len - 1) |
c6c8fea29
|
37 |
|
a8a0a62d1
|
38 |
static const int batadv_log_buff_len = BATADV_LOG_BUF_LEN; |
0abf5d811
|
39 |
static char *batadv_log_char_addr(struct batadv_priv_debug_log *debug_log, |
a8a0a62d1
|
40 41 42 43 |
size_t idx) { return &debug_log->log_buff[idx & BATADV_LOG_BUFF_MASK]; } |
c6c8fea29
|
44 |
|
0abf5d811
|
45 46 |
static void batadv_emit_log_char(struct batadv_priv_debug_log *debug_log, char c) |
c6c8fea29
|
47 |
{ |
a8a0a62d1
|
48 49 50 51 |
char *char_addr; char_addr = batadv_log_char_addr(debug_log, debug_log->log_end); *char_addr = c; |
c6c8fea29
|
52 |
debug_log->log_end++; |
9e466250e
|
53 54 |
if (debug_log->log_end - debug_log->log_start > batadv_log_buff_len) debug_log->log_start = debug_log->log_end - batadv_log_buff_len; |
c6c8fea29
|
55 |
} |
d3a547be4
|
56 |
__printf(2, 3) |
0abf5d811
|
57 |
static int batadv_fdebug_log(struct batadv_priv_debug_log *debug_log, |
56303d34a
|
58 |
const char *fmt, ...) |
c6c8fea29
|
59 |
{ |
c6c8fea29
|
60 61 62 63 64 65 66 67 68 |
va_list args; static char debug_log_buf[256]; char *p; if (!debug_log) return 0; spin_lock_bh(&debug_log->lock); va_start(args, fmt); |
1299bdaa1
|
69 |
vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt, args); |
c6c8fea29
|
70 71 72 |
va_end(args); for (p = debug_log_buf; *p != 0; p++) |
9e466250e
|
73 |
batadv_emit_log_char(debug_log, *p); |
c6c8fea29
|
74 75 76 77 78 79 80 |
spin_unlock_bh(&debug_log->lock); wake_up(&debug_log->queue_wait); return 0; } |
56303d34a
|
81 |
int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) |
c6c8fea29
|
82 83 84 85 86 87 |
{ va_list args; char tmp_log_buf[256]; va_start(args, fmt); vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); |
9e466250e
|
88 89 |
batadv_fdebug_log(bat_priv->debug_log, "[%10u] %s", jiffies_to_msecs(jiffies), tmp_log_buf); |
c6c8fea29
|
90 91 92 93 |
va_end(args); return 0; } |
9e466250e
|
94 |
static int batadv_log_open(struct inode *inode, struct file *file) |
c6c8fea29
|
95 |
{ |
bd5b80d51
|
96 97 |
if (!try_module_get(THIS_MODULE)) return -EBUSY; |
c6c8fea29
|
98 99 |
nonseekable_open(inode, file); file->private_data = inode->i_private; |
c6c8fea29
|
100 101 |
return 0; } |
9e466250e
|
102 |
static int batadv_log_release(struct inode *inode, struct file *file) |
c6c8fea29
|
103 |
{ |
bd5b80d51
|
104 |
module_put(THIS_MODULE); |
c6c8fea29
|
105 106 |
return 0; } |
0abf5d811
|
107 |
static int batadv_log_empty(struct batadv_priv_debug_log *debug_log) |
0aca2369b
|
108 109 110 |
{ return !(debug_log->log_start - debug_log->log_end); } |
9e466250e
|
111 112 |
static ssize_t batadv_log_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) |
c6c8fea29
|
113 |
{ |
56303d34a
|
114 |
struct batadv_priv *bat_priv = file->private_data; |
0abf5d811
|
115 |
struct batadv_priv_debug_log *debug_log = bat_priv->debug_log; |
c6c8fea29
|
116 |
int error, i = 0; |
a8a0a62d1
|
117 |
char *char_addr; |
c6c8fea29
|
118 |
char c; |
0aca2369b
|
119 |
if ((file->f_flags & O_NONBLOCK) && batadv_log_empty(debug_log)) |
c6c8fea29
|
120 |
return -EAGAIN; |
16f14b45c
|
121 |
if (!buf) |
c6c8fea29
|
122 123 124 125 126 127 128 129 130 |
return -EINVAL; if (count == 0) return 0; if (!access_ok(VERIFY_WRITE, buf, count)) return -EFAULT; error = wait_event_interruptible(debug_log->queue_wait, |
0aca2369b
|
131 |
(!batadv_log_empty(debug_log))); |
c6c8fea29
|
132 133 134 135 136 137 138 139 |
if (error) return error; spin_lock_bh(&debug_log->lock); while ((!error) && (i < count) && (debug_log->log_start != debug_log->log_end)) { |
a8a0a62d1
|
140 141 142 |
char_addr = batadv_log_char_addr(debug_log, debug_log->log_start); c = *char_addr; |
c6c8fea29
|
143 144 145 146 147 148 149 150 151 152 153 |
debug_log->log_start++; spin_unlock_bh(&debug_log->lock); error = __put_user(c, buf); spin_lock_bh(&debug_log->lock); buf++; i++; |
c6c8fea29
|
154 155 156 157 158 159 160 161 162 |
} spin_unlock_bh(&debug_log->lock); if (!error) return i; return error; } |
9e466250e
|
163 |
static unsigned int batadv_log_poll(struct file *file, poll_table *wait) |
c6c8fea29
|
164 |
{ |
56303d34a
|
165 |
struct batadv_priv *bat_priv = file->private_data; |
0abf5d811
|
166 |
struct batadv_priv_debug_log *debug_log = bat_priv->debug_log; |
c6c8fea29
|
167 168 |
poll_wait(file, &debug_log->queue_wait, wait); |
0aca2369b
|
169 |
if (!batadv_log_empty(debug_log)) |
c6c8fea29
|
170 171 172 173 |
return POLLIN | POLLRDNORM; return 0; } |
9e466250e
|
174 175 176 177 178 |
static const struct file_operations batadv_log_fops = { .open = batadv_log_open, .release = batadv_log_release, .read = batadv_log_read, .poll = batadv_log_poll, |
c6c8fea29
|
179 180 |
.llseek = no_llseek, }; |
56303d34a
|
181 |
static int batadv_debug_log_setup(struct batadv_priv *bat_priv) |
c6c8fea29
|
182 183 184 185 186 |
{ struct dentry *d; if (!bat_priv->debug_dir) goto err; |
704509b8d
|
187 |
bat_priv->debug_log = kzalloc(sizeof(*bat_priv->debug_log), GFP_ATOMIC); |
c6c8fea29
|
188 189 190 191 192 193 194 |
if (!bat_priv->debug_log) goto err; spin_lock_init(&bat_priv->debug_log->lock); init_waitqueue_head(&bat_priv->debug_log->queue_wait); d = debugfs_create_file("log", S_IFREG | S_IRUSR, |
9e466250e
|
195 196 |
bat_priv->debug_dir, bat_priv, &batadv_log_fops); |
5346c35eb
|
197 |
if (!d) |
c6c8fea29
|
198 199 200 201 202 |
goto err; return 0; err: |
5346c35eb
|
203 |
return -ENOMEM; |
c6c8fea29
|
204 |
} |
56303d34a
|
205 |
static void batadv_debug_log_cleanup(struct batadv_priv *bat_priv) |
c6c8fea29
|
206 207 208 209 210 |
{ kfree(bat_priv->debug_log); bat_priv->debug_log = NULL; } #else /* CONFIG_BATMAN_ADV_DEBUG */ |
56303d34a
|
211 |
static int batadv_debug_log_setup(struct batadv_priv *bat_priv) |
c6c8fea29
|
212 |
{ |
c6c8fea29
|
213 214 |
return 0; } |
56303d34a
|
215 |
static void batadv_debug_log_cleanup(struct batadv_priv *bat_priv) |
c6c8fea29
|
216 217 218 219 |
{ return; } #endif |
9e466250e
|
220 |
static int batadv_algorithms_open(struct inode *inode, struct file *file) |
1c280471b
|
221 |
{ |
3193e8fdf
|
222 |
return single_open(file, batadv_algo_seq_print_text, NULL); |
1c280471b
|
223 |
} |
9e466250e
|
224 |
static int batadv_originators_open(struct inode *inode, struct file *file) |
c6c8fea29
|
225 226 |
{ struct net_device *net_dev = (struct net_device *)inode->i_private; |
f138694b1
|
227 |
|
7d211efc5
|
228 |
return single_open(file, batadv_orig_seq_print_text, net_dev); |
c6c8fea29
|
229 |
} |
cb1c92ec3
|
230 231 232 233 234 235 236 237 238 239 |
/** * batadv_originators_hardif_open - handles debugfs output for the * originator table of an hard interface * @inode: inode pointer to debugfs file * @file: pointer to the seq_file */ static int batadv_originators_hardif_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; |
f138694b1
|
240 |
|
cb1c92ec3
|
241 242 |
return single_open(file, batadv_orig_hardif_seq_print_text, net_dev); } |
9e466250e
|
243 |
static int batadv_gateways_open(struct inode *inode, struct file *file) |
c6c8fea29
|
244 245 |
{ struct net_device *net_dev = (struct net_device *)inode->i_private; |
f138694b1
|
246 |
|
7cf06bc6f
|
247 |
return single_open(file, batadv_gw_client_seq_print_text, net_dev); |
c6c8fea29
|
248 |
} |
9e466250e
|
249 |
static int batadv_transtable_global_open(struct inode *inode, struct file *file) |
c6c8fea29
|
250 251 |
{ struct net_device *net_dev = (struct net_device *)inode->i_private; |
f138694b1
|
252 |
|
08c36d3e8
|
253 |
return single_open(file, batadv_tt_global_seq_print_text, net_dev); |
c6c8fea29
|
254 |
} |
7a5cc2427
|
255 |
#ifdef CONFIG_BATMAN_ADV_BLA |
9e466250e
|
256 |
static int batadv_bla_claim_table_open(struct inode *inode, struct file *file) |
9bf8e4d42
|
257 258 |
{ struct net_device *net_dev = (struct net_device *)inode->i_private; |
f138694b1
|
259 |
|
08adf1512
|
260 261 |
return single_open(file, batadv_bla_claim_table_seq_print_text, net_dev); |
9bf8e4d42
|
262 |
} |
536a23f11
|
263 264 265 266 267 |
static int batadv_bla_backbone_table_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; |
f138694b1
|
268 |
|
536a23f11
|
269 270 271 |
return single_open(file, batadv_bla_backbone_table_seq_print_text, net_dev); } |
7a5cc2427
|
272 |
#endif |
9bf8e4d42
|
273 |
|
172244748
|
274 |
#ifdef CONFIG_BATMAN_ADV_DAT |
2f1dfbe18
|
275 276 277 278 279 280 281 282 |
/** * batadv_dat_cache_open - Prepare file handler for reads from dat_chache * @inode: inode which was opened * @file: file handle to be initialized */ static int batadv_dat_cache_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; |
f138694b1
|
283 |
|
2f1dfbe18
|
284 285 |
return single_open(file, batadv_dat_cache_seq_print_text, net_dev); } |
172244748
|
286 |
#endif |
2f1dfbe18
|
287 |
|
9e466250e
|
288 |
static int batadv_transtable_local_open(struct inode *inode, struct file *file) |
c6c8fea29
|
289 290 |
{ struct net_device *net_dev = (struct net_device *)inode->i_private; |
f138694b1
|
291 |
|
08c36d3e8
|
292 |
return single_open(file, batadv_tt_local_seq_print_text, net_dev); |
c6c8fea29
|
293 |
} |
7f223c0c3
|
294 |
struct batadv_debuginfo { |
c6c8fea29
|
295 296 297 |
struct attribute attr; const struct file_operations fops; }; |
d56b1705e
|
298 299 300 301 |
#ifdef CONFIG_BATMAN_ADV_NC static int batadv_nc_nodes_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; |
f138694b1
|
302 |
|
d56b1705e
|
303 304 305 |
return single_open(file, batadv_nc_nodes_seq_print_text, net_dev); } #endif |
347c80f0f
|
306 |
#define BATADV_DEBUGINFO(_name, _mode, _open) \ |
7f223c0c3
|
307 |
struct batadv_debuginfo batadv_debuginfo_##_name = { \ |
9e466250e
|
308 309 310 311 312 313 314 315 |
.attr = { .name = __stringify(_name), \ .mode = _mode, }, \ .fops = { .owner = THIS_MODULE, \ .open = _open, \ .read = seq_read, \ .llseek = seq_lseek, \ .release = single_release, \ } \ |
2b64df205
|
316 |
} |
c6c8fea29
|
317 |
|
637fbd129
|
318 319 320 |
/* the following attributes are general and therefore they will be directly * placed in the BATADV_DEBUGFS_SUBDIR subdirectory of debugfs */ |
347c80f0f
|
321 |
static BATADV_DEBUGINFO(routing_algos, S_IRUGO, batadv_algorithms_open); |
637fbd129
|
322 323 324 325 326 327 328 |
static struct batadv_debuginfo *batadv_general_debuginfos[] = { &batadv_debuginfo_routing_algos, NULL, }; /* The following attributes are per soft interface */ |
347c80f0f
|
329 330 331 332 |
static BATADV_DEBUGINFO(originators, S_IRUGO, batadv_originators_open); static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open); static BATADV_DEBUGINFO(transtable_global, S_IRUGO, batadv_transtable_global_open); |
7a5cc2427
|
333 |
#ifdef CONFIG_BATMAN_ADV_BLA |
347c80f0f
|
334 |
static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open); |
536a23f11
|
335 336 |
static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO, batadv_bla_backbone_table_open); |
7a5cc2427
|
337 |
#endif |
172244748
|
338 |
#ifdef CONFIG_BATMAN_ADV_DAT |
2f1dfbe18
|
339 |
static BATADV_DEBUGINFO(dat_cache, S_IRUGO, batadv_dat_cache_open); |
172244748
|
340 |
#endif |
347c80f0f
|
341 342 |
static BATADV_DEBUGINFO(transtable_local, S_IRUGO, batadv_transtable_local_open); |
d56b1705e
|
343 344 345 |
#ifdef CONFIG_BATMAN_ADV_NC static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open); #endif |
c6c8fea29
|
346 |
|
7f223c0c3
|
347 |
static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { |
9e466250e
|
348 349 350 |
&batadv_debuginfo_originators, &batadv_debuginfo_gateways, &batadv_debuginfo_transtable_global, |
7a5cc2427
|
351 |
#ifdef CONFIG_BATMAN_ADV_BLA |
9e466250e
|
352 |
&batadv_debuginfo_bla_claim_table, |
536a23f11
|
353 |
&batadv_debuginfo_bla_backbone_table, |
7a5cc2427
|
354 |
#endif |
172244748
|
355 |
#ifdef CONFIG_BATMAN_ADV_DAT |
2f1dfbe18
|
356 |
&batadv_debuginfo_dat_cache, |
172244748
|
357 |
#endif |
9e466250e
|
358 |
&batadv_debuginfo_transtable_local, |
d56b1705e
|
359 360 361 |
#ifdef CONFIG_BATMAN_ADV_NC &batadv_debuginfo_nc_nodes, #endif |
c6c8fea29
|
362 363 |
NULL, }; |
5bc7c1eb4
|
364 365 366 367 368 369 370 371 372 373 374 375 376 |
#define BATADV_HARDIF_DEBUGINFO(_name, _mode, _open) \ struct batadv_debuginfo batadv_hardif_debuginfo_##_name = { \ .attr = { \ .name = __stringify(_name), \ .mode = _mode, \ }, \ .fops = { \ .owner = THIS_MODULE, \ .open = _open, \ .read = seq_read, \ .llseek = seq_lseek, \ .release = single_release, \ }, \ |
2b64df205
|
377 |
} |
cb1c92ec3
|
378 379 |
static BATADV_HARDIF_DEBUGINFO(originators, S_IRUGO, batadv_originators_hardif_open); |
5bc7c1eb4
|
380 381 |
static struct batadv_debuginfo *batadv_hardif_debuginfos[] = { |
cb1c92ec3
|
382 |
&batadv_hardif_debuginfo_originators, |
5bc7c1eb4
|
383 384 |
NULL, }; |
40a072d77
|
385 |
void batadv_debugfs_init(void) |
c6c8fea29
|
386 |
{ |
637fbd129
|
387 |
struct batadv_debuginfo **bat_debug; |
1c280471b
|
388 |
struct dentry *file; |
54590e4d4
|
389 |
batadv_debugfs = debugfs_create_dir(BATADV_DEBUGFS_SUBDIR, NULL); |
9e466250e
|
390 391 |
if (batadv_debugfs == ERR_PTR(-ENODEV)) batadv_debugfs = NULL; |
1c280471b
|
392 |
|
9e466250e
|
393 |
if (!batadv_debugfs) |
637fbd129
|
394 |
goto err; |
1c280471b
|
395 |
|
637fbd129
|
396 397 398 399 400 401 402 403 404 405 406 407 |
for (bat_debug = batadv_general_debuginfos; *bat_debug; ++bat_debug) { file = debugfs_create_file(((*bat_debug)->attr).name, S_IFREG | ((*bat_debug)->attr).mode, batadv_debugfs, NULL, &(*bat_debug)->fops); if (!file) { pr_err("Can't add general debugfs file: %s ", ((*bat_debug)->attr).name); goto err; } } |
1c280471b
|
408 |
|
1c280471b
|
409 |
return; |
637fbd129
|
410 411 |
err: debugfs_remove_recursive(batadv_debugfs); |
5bc7c1eb4
|
412 |
batadv_debugfs = NULL; |
c6c8fea29
|
413 |
} |
40a072d77
|
414 |
void batadv_debugfs_destroy(void) |
c6c8fea29
|
415 |
{ |
3f87c4239
|
416 417 |
debugfs_remove_recursive(batadv_debugfs); batadv_debugfs = NULL; |
c6c8fea29
|
418 |
} |
5bc7c1eb4
|
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
/** * batadv_debugfs_add_hardif - creates the base directory for a hard interface * in debugfs. * @hard_iface: hard interface which should be added. */ int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface) { struct batadv_debuginfo **bat_debug; struct dentry *file; if (!batadv_debugfs) goto out; hard_iface->debug_dir = debugfs_create_dir(hard_iface->net_dev->name, batadv_debugfs); if (!hard_iface->debug_dir) goto out; for (bat_debug = batadv_hardif_debuginfos; *bat_debug; ++bat_debug) { file = debugfs_create_file(((*bat_debug)->attr).name, S_IFREG | ((*bat_debug)->attr).mode, hard_iface->debug_dir, hard_iface->net_dev, &(*bat_debug)->fops); if (!file) goto rem_attr; } return 0; rem_attr: debugfs_remove_recursive(hard_iface->debug_dir); hard_iface->debug_dir = NULL; out: #ifdef CONFIG_DEBUG_FS return -ENOMEM; #else return 0; #endif /* CONFIG_DEBUG_FS */ } /** * batadv_debugfs_del_hardif - delete the base directory for a hard interface * in debugfs. * @hard_iface: hard interface which is deleted. */ void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface) { if (batadv_debugfs) { debugfs_remove_recursive(hard_iface->debug_dir); hard_iface->debug_dir = NULL; } } |
40a072d77
|
471 |
int batadv_debugfs_add_meshif(struct net_device *dev) |
c6c8fea29
|
472 |
{ |
56303d34a
|
473 |
struct batadv_priv *bat_priv = netdev_priv(dev); |
7f223c0c3
|
474 |
struct batadv_debuginfo **bat_debug; |
c6c8fea29
|
475 |
struct dentry *file; |
9e466250e
|
476 |
if (!batadv_debugfs) |
c6c8fea29
|
477 |
goto out; |
9e466250e
|
478 |
bat_priv->debug_dir = debugfs_create_dir(dev->name, batadv_debugfs); |
c6c8fea29
|
479 480 |
if (!bat_priv->debug_dir) goto out; |
9039dc7e8
|
481 |
if (batadv_socket_setup(bat_priv) < 0) |
5346c35eb
|
482 |
goto rem_attr; |
9e466250e
|
483 |
if (batadv_debug_log_setup(bat_priv) < 0) |
5346c35eb
|
484 |
goto rem_attr; |
c6c8fea29
|
485 |
|
9e466250e
|
486 |
for (bat_debug = batadv_mesh_debuginfos; *bat_debug; ++bat_debug) { |
c6c8fea29
|
487 |
file = debugfs_create_file(((*bat_debug)->attr).name, |
0aca2369b
|
488 489 490 |
S_IFREG | ((*bat_debug)->attr).mode, bat_priv->debug_dir, dev, &(*bat_debug)->fops); |
c6c8fea29
|
491 |
if (!file) { |
3e34819e0
|
492 493 494 |
batadv_err(dev, "Can't add debugfs file: %s/%s ", dev->name, ((*bat_debug)->attr).name); |
c6c8fea29
|
495 496 497 |
goto rem_attr; } } |
d56b1705e
|
498 499 |
if (batadv_nc_init_debugfs(bat_priv) < 0) goto rem_attr; |
c6c8fea29
|
500 501 502 503 504 505 506 507 508 509 510 |
return 0; rem_attr: debugfs_remove_recursive(bat_priv->debug_dir); bat_priv->debug_dir = NULL; out: #ifdef CONFIG_DEBUG_FS return -ENOMEM; #else return 0; #endif /* CONFIG_DEBUG_FS */ } |
40a072d77
|
511 |
void batadv_debugfs_del_meshif(struct net_device *dev) |
c6c8fea29
|
512 |
{ |
56303d34a
|
513 |
struct batadv_priv *bat_priv = netdev_priv(dev); |
c6c8fea29
|
514 |
|
9e466250e
|
515 |
batadv_debug_log_cleanup(bat_priv); |
c6c8fea29
|
516 |
|
9e466250e
|
517 |
if (batadv_debugfs) { |
c6c8fea29
|
518 519 520 521 |
debugfs_remove_recursive(bat_priv->debug_dir); bat_priv->debug_dir = NULL; } } |