aboutsummaryrefslogtreecommitdiffstats
path: root/net/phonet/socket.c
diff options
context:
space:
mode:
authorRémi Denis-Courmont <remi.denis-courmont@nokia.com>2010-09-15 08:30:14 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-16 00:31:33 -0400
commit507215f8d04f9e61f38c975e61d93bcafd30815f (patch)
tree79a88610eaf8abcc3f160ca0ced0a1b4e72dfd80 /net/phonet/socket.c
parentb6a563b2af4ec5b0363cf89869ba234c0e2cd3da (diff)
Phonet: list subscribed resources via proc_fs
Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/phonet/socket.c')
-rw-r--r--net/phonet/socket.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index d4f41afc0583..6bf6e3c97d5c 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -654,3 +654,99 @@ void pn_sock_unbind_all_res(struct sock *sk)
654 match--; 654 match--;
655 } 655 }
656} 656}
657
658#ifdef CONFIG_PROC_FS
659static struct sock **pn_res_get_idx(struct seq_file *seq, loff_t pos)
660{
661 struct net *net = seq_file_net(seq);
662 unsigned i;
663
664 if (!net_eq(net, &init_net))
665 return NULL;
666
667 for (i = 0; i < 256; i++) {
668 if (pnres.sk[i] == NULL)
669 continue;
670 if (!pos)
671 return pnres.sk + i;
672 pos--;
673 }
674 return NULL;
675}
676
677static struct sock **pn_res_get_next(struct seq_file *seq, struct sock **sk)
678{
679 struct net *net = seq_file_net(seq);
680 unsigned i;
681
682 BUG_ON(!net_eq(net, &init_net));
683
684 for (i = (sk - pnres.sk) + 1; i < 256; i++)
685 if (pnres.sk[i])
686 return pnres.sk + i;
687 return NULL;
688}
689
690static void *pn_res_seq_start(struct seq_file *seq, loff_t *pos)
691 __acquires(resource_mutex)
692{
693 mutex_lock(&resource_mutex);
694 return *pos ? pn_res_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
695}
696
697static void *pn_res_seq_next(struct seq_file *seq, void *v, loff_t *pos)
698{
699 struct sock **sk;
700
701 if (v == SEQ_START_TOKEN)
702 sk = pn_res_get_idx(seq, 0);
703 else
704 sk = pn_res_get_next(seq, v);
705 (*pos)++;
706 return sk;
707}
708
709static void pn_res_seq_stop(struct seq_file *seq, void *v)
710 __releases(resource_mutex)
711{
712 mutex_unlock(&resource_mutex);
713}
714
715static int pn_res_seq_show(struct seq_file *seq, void *v)
716{
717 int len;
718
719 if (v == SEQ_START_TOKEN)
720 seq_printf(seq, "%s%n", "rs uid inode", &len);
721 else {
722 struct sock **psk = v;
723 struct sock *sk = *psk;
724
725 seq_printf(seq, "%02X %5d %lu%n",
726 psk - pnres.sk, sock_i_uid(sk), sock_i_ino(sk), &len);
727 }
728 seq_printf(seq, "%*s\n", 63 - len, "");
729 return 0;
730}
731
732static const struct seq_operations pn_res_seq_ops = {
733 .start = pn_res_seq_start,
734 .next = pn_res_seq_next,
735 .stop = pn_res_seq_stop,
736 .show = pn_res_seq_show,
737};
738
739static int pn_res_open(struct inode *inode, struct file *file)
740{
741 return seq_open_net(inode, file, &pn_res_seq_ops,
742 sizeof(struct seq_net_private));
743}
744
745const struct file_operations pn_res_seq_fops = {
746 .owner = THIS_MODULE,
747 .open = pn_res_open,
748 .read = seq_read,
749 .llseek = seq_lseek,
750 .release = seq_release_net,
751};
752#endif