aboutsummaryrefslogtreecommitdiffstats
path: root/net/phonet/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/phonet/socket.c')
-rw-r--r--net/phonet/socket.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index ada2a35bf7a2..7a4ee397d2f7 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -412,3 +412,102 @@ found:
412 return 0; 412 return 0;
413} 413}
414EXPORT_SYMBOL(pn_sock_get_port); 414EXPORT_SYMBOL(pn_sock_get_port);
415
416#ifdef CONFIG_PROC_FS
417static struct sock *pn_sock_get_idx(struct seq_file *seq, loff_t pos)
418{
419 struct net *net = seq_file_net(seq);
420 struct hlist_node *node;
421 struct sock *sknode;
422
423 sk_for_each(sknode, node, &pnsocks.hlist) {
424 if (!net_eq(net, sock_net(sknode)))
425 continue;
426 if (!pos)
427 return sknode;
428 pos--;
429 }
430 return NULL;
431}
432
433static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk)
434{
435 struct net *net = seq_file_net(seq);
436
437 do
438 sk = sk_next(sk);
439 while (sk && !net_eq(net, sock_net(sk)));
440
441 return sk;
442}
443
444static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos)
445 __acquires(pnsocks.lock)
446{
447 spin_lock_bh(&pnsocks.lock);
448 return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
449}
450
451static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos)
452{
453 struct sock *sk;
454
455 if (v == SEQ_START_TOKEN)
456 sk = pn_sock_get_idx(seq, 0);
457 else
458 sk = pn_sock_get_next(seq, v);
459 (*pos)++;
460 return sk;
461}
462
463static void pn_sock_seq_stop(struct seq_file *seq, void *v)
464 __releases(pnsocks.lock)
465{
466 spin_unlock_bh(&pnsocks.lock);
467}
468
469static int pn_sock_seq_show(struct seq_file *seq, void *v)
470{
471 int len;
472
473 if (v == SEQ_START_TOKEN)
474 seq_printf(seq, "%s%n", "pt loc rem rs st tx_queue rx_queue "
475 " uid inode ref pointer drops", &len);
476 else {
477 struct sock *sk = v;
478 struct pn_sock *pn = pn_sk(sk);
479
480 seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu "
481 "%d %p %d%n",
482 sk->sk_protocol, pn->sobject, 0, pn->resource,
483 sk->sk_state,
484 sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
485 sock_i_uid(sk), sock_i_ino(sk),
486 atomic_read(&sk->sk_refcnt), sk,
487 atomic_read(&sk->sk_drops), &len);
488 }
489 seq_printf(seq, "%*s\n", 127 - len, "");
490 return 0;
491}
492
493static const struct seq_operations pn_sock_seq_ops = {
494 .start = pn_sock_seq_start,
495 .next = pn_sock_seq_next,
496 .stop = pn_sock_seq_stop,
497 .show = pn_sock_seq_show,
498};
499
500static int pn_sock_open(struct inode *inode, struct file *file)
501{
502 return seq_open_net(inode, file, &pn_sock_seq_ops,
503 sizeof(struct seq_net_private));
504}
505
506const struct file_operations pn_sock_seq_fops = {
507 .owner = THIS_MODULE,
508 .open = pn_sock_open,
509 .read = seq_read,
510 .llseek = seq_lseek,
511 .release = seq_release_net,
512};
513#endif