Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux...
[pandora-kernel.git] / net / phonet / socket.c
1 /*
2  * File: socket.c
3  *
4  * Phonet sockets
5  *
6  * Copyright (C) 2008 Nokia Corporation.
7  *
8  * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
9  * Original author: Sakari Ailus <sakari.ailus@nokia.com>
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * version 2 as published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  */
25
26 #include <linux/gfp.h>
27 #include <linux/kernel.h>
28 #include <linux/net.h>
29 #include <linux/poll.h>
30 #include <net/sock.h>
31 #include <net/tcp_states.h>
32
33 #include <linux/phonet.h>
34 #include <net/phonet/phonet.h>
35 #include <net/phonet/pep.h>
36 #include <net/phonet/pn_dev.h>
37
38 static int pn_socket_release(struct socket *sock)
39 {
40         struct sock *sk = sock->sk;
41
42         if (sk) {
43                 sock->sk = NULL;
44                 sk->sk_prot->close(sk, 0);
45         }
46         return 0;
47 }
48
49 #define PN_HASHSIZE     16
50 #define PN_HASHMASK     (PN_HASHSIZE-1)
51
52
53 static struct  {
54         struct hlist_head hlist[PN_HASHSIZE];
55         struct mutex lock;
56 } pnsocks;
57
58 void __init pn_sock_init(void)
59 {
60         unsigned i;
61
62         for (i = 0; i < PN_HASHSIZE; i++)
63                 INIT_HLIST_HEAD(pnsocks.hlist + i);
64         mutex_init(&pnsocks.lock);
65 }
66
67 static struct hlist_head *pn_hash_list(u16 obj)
68 {
69         return pnsocks.hlist + (obj & PN_HASHMASK);
70 }
71
72 /*
73  * Find address based on socket address, match only certain fields.
74  * Also grab sock if it was found. Remember to sock_put it later.
75  */
76 struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
77 {
78         struct hlist_node *node;
79         struct sock *sknode;
80         struct sock *rval = NULL;
81         u16 obj = pn_sockaddr_get_object(spn);
82         u8 res = spn->spn_resource;
83         struct hlist_head *hlist = pn_hash_list(obj);
84
85         rcu_read_lock();
86         sk_for_each_rcu(sknode, node, hlist) {
87                 struct pn_sock *pn = pn_sk(sknode);
88                 BUG_ON(!pn->sobject); /* unbound socket */
89
90                 if (!net_eq(sock_net(sknode), net))
91                         continue;
92                 if (pn_port(obj)) {
93                         /* Look up socket by port */
94                         if (pn_port(pn->sobject) != pn_port(obj))
95                                 continue;
96                 } else {
97                         /* If port is zero, look up by resource */
98                         if (pn->resource != res)
99                                 continue;
100                 }
101                 if (pn_addr(pn->sobject) &&
102                     pn_addr(pn->sobject) != pn_addr(obj))
103                         continue;
104
105                 rval = sknode;
106                 sock_hold(sknode);
107                 break;
108         }
109         rcu_read_unlock();
110
111         return rval;
112 }
113
114 /* Deliver a broadcast packet (only in bottom-half) */
115 void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
116 {
117         struct hlist_head *hlist = pnsocks.hlist;
118         unsigned h;
119
120         rcu_read_lock();
121         for (h = 0; h < PN_HASHSIZE; h++) {
122                 struct hlist_node *node;
123                 struct sock *sknode;
124
125                 sk_for_each(sknode, node, hlist) {
126                         struct sk_buff *clone;
127
128                         if (!net_eq(sock_net(sknode), net))
129                                 continue;
130                         if (!sock_flag(sknode, SOCK_BROADCAST))
131                                 continue;
132
133                         clone = skb_clone(skb, GFP_ATOMIC);
134                         if (clone) {
135                                 sock_hold(sknode);
136                                 sk_receive_skb(sknode, clone, 0);
137                         }
138                 }
139                 hlist++;
140         }
141         rcu_read_unlock();
142 }
143
144 void pn_sock_hash(struct sock *sk)
145 {
146         struct hlist_head *hlist = pn_hash_list(pn_sk(sk)->sobject);
147
148         mutex_lock(&pnsocks.lock);
149         sk_add_node_rcu(sk, hlist);
150         mutex_unlock(&pnsocks.lock);
151 }
152 EXPORT_SYMBOL(pn_sock_hash);
153
154 void pn_sock_unhash(struct sock *sk)
155 {
156         mutex_lock(&pnsocks.lock);
157         sk_del_node_init_rcu(sk);
158         mutex_unlock(&pnsocks.lock);
159         pn_sock_unbind_all_res(sk);
160         synchronize_rcu();
161 }
162 EXPORT_SYMBOL(pn_sock_unhash);
163
164 static DEFINE_MUTEX(port_mutex);
165
166 static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
167 {
168         struct sock *sk = sock->sk;
169         struct pn_sock *pn = pn_sk(sk);
170         struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
171         int err;
172         u16 handle;
173         u8 saddr;
174
175         if (sk->sk_prot->bind)
176                 return sk->sk_prot->bind(sk, addr, len);
177
178         if (len < sizeof(struct sockaddr_pn))
179                 return -EINVAL;
180         if (spn->spn_family != AF_PHONET)
181                 return -EAFNOSUPPORT;
182
183         handle = pn_sockaddr_get_object((struct sockaddr_pn *)addr);
184         saddr = pn_addr(handle);
185         if (saddr && phonet_address_lookup(sock_net(sk), saddr))
186                 return -EADDRNOTAVAIL;
187
188         lock_sock(sk);
189         if (sk->sk_state != TCP_CLOSE || pn_port(pn->sobject)) {
190                 err = -EINVAL; /* attempt to rebind */
191                 goto out;
192         }
193         WARN_ON(sk_hashed(sk));
194         mutex_lock(&port_mutex);
195         err = sk->sk_prot->get_port(sk, pn_port(handle));
196         if (err)
197                 goto out_port;
198
199         /* get_port() sets the port, bind() sets the address if applicable */
200         pn->sobject = pn_object(saddr, pn_port(pn->sobject));
201         pn->resource = spn->spn_resource;
202
203         /* Enable RX on the socket */
204         sk->sk_prot->hash(sk);
205 out_port:
206         mutex_unlock(&port_mutex);
207 out:
208         release_sock(sk);
209         return err;
210 }
211
212 static int pn_socket_autobind(struct socket *sock)
213 {
214         struct sockaddr_pn sa;
215         int err;
216
217         memset(&sa, 0, sizeof(sa));
218         sa.spn_family = AF_PHONET;
219         err = pn_socket_bind(sock, (struct sockaddr *)&sa,
220                                 sizeof(struct sockaddr_pn));
221         if (err != -EINVAL)
222                 return err;
223         BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
224         return 0; /* socket was already bound */
225 }
226
227 static int pn_socket_connect(struct socket *sock, struct sockaddr *addr,
228                 int len, int flags)
229 {
230         struct sock *sk = sock->sk;
231         struct pn_sock *pn = pn_sk(sk);
232         struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
233         struct task_struct *tsk = current;
234         long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
235         int err;
236
237         if (pn_socket_autobind(sock))
238                 return -ENOBUFS;
239         if (len < sizeof(struct sockaddr_pn))
240                 return -EINVAL;
241         if (spn->spn_family != AF_PHONET)
242                 return -EAFNOSUPPORT;
243
244         lock_sock(sk);
245
246         switch (sock->state) {
247         case SS_UNCONNECTED:
248                 if (sk->sk_state != TCP_CLOSE) {
249                         err = -EISCONN;
250                         goto out;
251                 }
252                 break;
253         case SS_CONNECTING:
254                 err = -EALREADY;
255                 goto out;
256         default:
257                 err = -EISCONN;
258                 goto out;
259         }
260
261         pn->dobject = pn_sockaddr_get_object(spn);
262         pn->resource = pn_sockaddr_get_resource(spn);
263         sock->state = SS_CONNECTING;
264
265         err = sk->sk_prot->connect(sk, addr, len);
266         if (err) {
267                 sock->state = SS_UNCONNECTED;
268                 pn->dobject = 0;
269                 goto out;
270         }
271
272         while (sk->sk_state == TCP_SYN_SENT) {
273                 DEFINE_WAIT(wait);
274
275                 if (!timeo) {
276                         err = -EINPROGRESS;
277                         goto out;
278                 }
279                 if (signal_pending(tsk)) {
280                         err = sock_intr_errno(timeo);
281                         goto out;
282                 }
283
284                 prepare_to_wait_exclusive(sk_sleep(sk), &wait,
285                                                 TASK_INTERRUPTIBLE);
286                 release_sock(sk);
287                 timeo = schedule_timeout(timeo);
288                 lock_sock(sk);
289                 finish_wait(sk_sleep(sk), &wait);
290         }
291
292         if ((1 << sk->sk_state) & (TCPF_SYN_RECV|TCPF_ESTABLISHED))
293                 err = 0;
294         else if (sk->sk_state == TCP_CLOSE_WAIT)
295                 err = -ECONNRESET;
296         else
297                 err = -ECONNREFUSED;
298         sock->state = err ? SS_UNCONNECTED : SS_CONNECTED;
299 out:
300         release_sock(sk);
301         return err;
302 }
303
304 static int pn_socket_accept(struct socket *sock, struct socket *newsock,
305                                 int flags)
306 {
307         struct sock *sk = sock->sk;
308         struct sock *newsk;
309         int err;
310
311         if (unlikely(sk->sk_state != TCP_LISTEN))
312                 return -EINVAL;
313
314         newsk = sk->sk_prot->accept(sk, flags, &err);
315         if (!newsk)
316                 return err;
317
318         lock_sock(newsk);
319         sock_graft(newsk, newsock);
320         newsock->state = SS_CONNECTED;
321         release_sock(newsk);
322         return 0;
323 }
324
325 static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
326                                 int *sockaddr_len, int peer)
327 {
328         struct sock *sk = sock->sk;
329         struct pn_sock *pn = pn_sk(sk);
330
331         memset(addr, 0, sizeof(struct sockaddr_pn));
332         addr->sa_family = AF_PHONET;
333         if (!peer) /* Race with bind() here is userland's problem. */
334                 pn_sockaddr_set_object((struct sockaddr_pn *)addr,
335                                         pn->sobject);
336
337         *sockaddr_len = sizeof(struct sockaddr_pn);
338         return 0;
339 }
340
341 static unsigned int pn_socket_poll(struct file *file, struct socket *sock,
342                                         poll_table *wait)
343 {
344         struct sock *sk = sock->sk;
345         struct pep_sock *pn = pep_sk(sk);
346         unsigned int mask = 0;
347
348         poll_wait(file, sk_sleep(sk), wait);
349
350         if (sk->sk_state == TCP_CLOSE)
351                 return POLLERR;
352         if (!skb_queue_empty(&sk->sk_receive_queue))
353                 mask |= POLLIN | POLLRDNORM;
354         if (!skb_queue_empty(&pn->ctrlreq_queue))
355                 mask |= POLLPRI;
356         if (!mask && sk->sk_state == TCP_CLOSE_WAIT)
357                 return POLLHUP;
358
359         if (sk->sk_state == TCP_ESTABLISHED &&
360                 atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf &&
361                 atomic_read(&pn->tx_credits))
362                 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
363
364         return mask;
365 }
366
367 static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
368                                 unsigned long arg)
369 {
370         struct sock *sk = sock->sk;
371         struct pn_sock *pn = pn_sk(sk);
372
373         if (cmd == SIOCPNGETOBJECT) {
374                 struct net_device *dev;
375                 u16 handle;
376                 u8 saddr;
377
378                 if (get_user(handle, (__u16 __user *)arg))
379                         return -EFAULT;
380
381                 lock_sock(sk);
382                 if (sk->sk_bound_dev_if)
383                         dev = dev_get_by_index(sock_net(sk),
384                                                 sk->sk_bound_dev_if);
385                 else
386                         dev = phonet_device_get(sock_net(sk));
387                 if (dev && (dev->flags & IFF_UP))
388                         saddr = phonet_address_get(dev, pn_addr(handle));
389                 else
390                         saddr = PN_NO_ADDR;
391                 release_sock(sk);
392
393                 if (dev)
394                         dev_put(dev);
395                 if (saddr == PN_NO_ADDR)
396                         return -EHOSTUNREACH;
397
398                 handle = pn_object(saddr, pn_port(pn->sobject));
399                 return put_user(handle, (__u16 __user *)arg);
400         }
401
402         return sk->sk_prot->ioctl(sk, cmd, arg);
403 }
404
405 static int pn_socket_listen(struct socket *sock, int backlog)
406 {
407         struct sock *sk = sock->sk;
408         int err = 0;
409
410         if (pn_socket_autobind(sock))
411                 return -ENOBUFS;
412
413         lock_sock(sk);
414         if (sock->state != SS_UNCONNECTED) {
415                 err = -EINVAL;
416                 goto out;
417         }
418
419         if (sk->sk_state != TCP_LISTEN) {
420                 sk->sk_state = TCP_LISTEN;
421                 sk->sk_ack_backlog = 0;
422         }
423         sk->sk_max_ack_backlog = backlog;
424 out:
425         release_sock(sk);
426         return err;
427 }
428
429 static int pn_socket_sendmsg(struct kiocb *iocb, struct socket *sock,
430                                 struct msghdr *m, size_t total_len)
431 {
432         struct sock *sk = sock->sk;
433
434         if (pn_socket_autobind(sock))
435                 return -EAGAIN;
436
437         return sk->sk_prot->sendmsg(iocb, sk, m, total_len);
438 }
439
440 const struct proto_ops phonet_dgram_ops = {
441         .family         = AF_PHONET,
442         .owner          = THIS_MODULE,
443         .release        = pn_socket_release,
444         .bind           = pn_socket_bind,
445         .connect        = sock_no_connect,
446         .socketpair     = sock_no_socketpair,
447         .accept         = sock_no_accept,
448         .getname        = pn_socket_getname,
449         .poll           = datagram_poll,
450         .ioctl          = pn_socket_ioctl,
451         .listen         = sock_no_listen,
452         .shutdown       = sock_no_shutdown,
453         .setsockopt     = sock_no_setsockopt,
454         .getsockopt     = sock_no_getsockopt,
455 #ifdef CONFIG_COMPAT
456         .compat_setsockopt = sock_no_setsockopt,
457         .compat_getsockopt = sock_no_getsockopt,
458 #endif
459         .sendmsg        = pn_socket_sendmsg,
460         .recvmsg        = sock_common_recvmsg,
461         .mmap           = sock_no_mmap,
462         .sendpage       = sock_no_sendpage,
463 };
464
465 const struct proto_ops phonet_stream_ops = {
466         .family         = AF_PHONET,
467         .owner          = THIS_MODULE,
468         .release        = pn_socket_release,
469         .bind           = pn_socket_bind,
470         .connect        = pn_socket_connect,
471         .socketpair     = sock_no_socketpair,
472         .accept         = pn_socket_accept,
473         .getname        = pn_socket_getname,
474         .poll           = pn_socket_poll,
475         .ioctl          = pn_socket_ioctl,
476         .listen         = pn_socket_listen,
477         .shutdown       = sock_no_shutdown,
478         .setsockopt     = sock_common_setsockopt,
479         .getsockopt     = sock_common_getsockopt,
480 #ifdef CONFIG_COMPAT
481         .compat_setsockopt = compat_sock_common_setsockopt,
482         .compat_getsockopt = compat_sock_common_getsockopt,
483 #endif
484         .sendmsg        = pn_socket_sendmsg,
485         .recvmsg        = sock_common_recvmsg,
486         .mmap           = sock_no_mmap,
487         .sendpage       = sock_no_sendpage,
488 };
489 EXPORT_SYMBOL(phonet_stream_ops);
490
491 /* allocate port for a socket */
492 int pn_sock_get_port(struct sock *sk, unsigned short sport)
493 {
494         static int port_cur;
495         struct net *net = sock_net(sk);
496         struct pn_sock *pn = pn_sk(sk);
497         struct sockaddr_pn try_sa;
498         struct sock *tmpsk;
499
500         memset(&try_sa, 0, sizeof(struct sockaddr_pn));
501         try_sa.spn_family = AF_PHONET;
502         WARN_ON(!mutex_is_locked(&port_mutex));
503         if (!sport) {
504                 /* search free port */
505                 int port, pmin, pmax;
506
507                 phonet_get_local_port_range(&pmin, &pmax);
508                 for (port = pmin; port <= pmax; port++) {
509                         port_cur++;
510                         if (port_cur < pmin || port_cur > pmax)
511                                 port_cur = pmin;
512
513                         pn_sockaddr_set_port(&try_sa, port_cur);
514                         tmpsk = pn_find_sock_by_sa(net, &try_sa);
515                         if (tmpsk == NULL) {
516                                 sport = port_cur;
517                                 goto found;
518                         } else
519                                 sock_put(tmpsk);
520                 }
521         } else {
522                 /* try to find specific port */
523                 pn_sockaddr_set_port(&try_sa, sport);
524                 tmpsk = pn_find_sock_by_sa(net, &try_sa);
525                 if (tmpsk == NULL)
526                         /* No sock there! We can use that port... */
527                         goto found;
528                 else
529                         sock_put(tmpsk);
530         }
531         /* the port must be in use already */
532         return -EADDRINUSE;
533
534 found:
535         pn->sobject = pn_object(pn_addr(pn->sobject), sport);
536         return 0;
537 }
538 EXPORT_SYMBOL(pn_sock_get_port);
539
540 #ifdef CONFIG_PROC_FS
541 static struct sock *pn_sock_get_idx(struct seq_file *seq, loff_t pos)
542 {
543         struct net *net = seq_file_net(seq);
544         struct hlist_head *hlist = pnsocks.hlist;
545         struct hlist_node *node;
546         struct sock *sknode;
547         unsigned h;
548
549         for (h = 0; h < PN_HASHSIZE; h++) {
550                 sk_for_each_rcu(sknode, node, hlist) {
551                         if (!net_eq(net, sock_net(sknode)))
552                                 continue;
553                         if (!pos)
554                                 return sknode;
555                         pos--;
556                 }
557                 hlist++;
558         }
559         return NULL;
560 }
561
562 static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk)
563 {
564         struct net *net = seq_file_net(seq);
565
566         do
567                 sk = sk_next(sk);
568         while (sk && !net_eq(net, sock_net(sk)));
569
570         return sk;
571 }
572
573 static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos)
574         __acquires(rcu)
575 {
576         rcu_read_lock();
577         return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
578 }
579
580 static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos)
581 {
582         struct sock *sk;
583
584         if (v == SEQ_START_TOKEN)
585                 sk = pn_sock_get_idx(seq, 0);
586         else
587                 sk = pn_sock_get_next(seq, v);
588         (*pos)++;
589         return sk;
590 }
591
592 static void pn_sock_seq_stop(struct seq_file *seq, void *v)
593         __releases(rcu)
594 {
595         rcu_read_unlock();
596 }
597
598 static int pn_sock_seq_show(struct seq_file *seq, void *v)
599 {
600         int len;
601
602         if (v == SEQ_START_TOKEN)
603                 seq_printf(seq, "%s%n", "pt  loc  rem rs st tx_queue rx_queue "
604                         "  uid inode ref pointer drops", &len);
605         else {
606                 struct sock *sk = v;
607                 struct pn_sock *pn = pn_sk(sk);
608
609                 seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu "
610                         "%d %pK %d%n",
611                         sk->sk_protocol, pn->sobject, pn->dobject,
612                         pn->resource, sk->sk_state,
613                         sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
614                         sock_i_uid(sk), sock_i_ino(sk),
615                         atomic_read(&sk->sk_refcnt), sk,
616                         atomic_read(&sk->sk_drops), &len);
617         }
618         seq_printf(seq, "%*s\n", 127 - len, "");
619         return 0;
620 }
621
622 static const struct seq_operations pn_sock_seq_ops = {
623         .start = pn_sock_seq_start,
624         .next = pn_sock_seq_next,
625         .stop = pn_sock_seq_stop,
626         .show = pn_sock_seq_show,
627 };
628
629 static int pn_sock_open(struct inode *inode, struct file *file)
630 {
631         return seq_open_net(inode, file, &pn_sock_seq_ops,
632                                 sizeof(struct seq_net_private));
633 }
634
635 const struct file_operations pn_sock_seq_fops = {
636         .owner = THIS_MODULE,
637         .open = pn_sock_open,
638         .read = seq_read,
639         .llseek = seq_lseek,
640         .release = seq_release_net,
641 };
642 #endif
643
644 static struct  {
645         struct sock *sk[256];
646 } pnres;
647
648 /*
649  * Find and hold socket based on resource.
650  */
651 struct sock *pn_find_sock_by_res(struct net *net, u8 res)
652 {
653         struct sock *sk;
654
655         if (!net_eq(net, &init_net))
656                 return NULL;
657
658         rcu_read_lock();
659         sk = rcu_dereference(pnres.sk[res]);
660         if (sk)
661                 sock_hold(sk);
662         rcu_read_unlock();
663         return sk;
664 }
665
666 static DEFINE_MUTEX(resource_mutex);
667
668 int pn_sock_bind_res(struct sock *sk, u8 res)
669 {
670         int ret = -EADDRINUSE;
671
672         if (!net_eq(sock_net(sk), &init_net))
673                 return -ENOIOCTLCMD;
674         if (!capable(CAP_SYS_ADMIN))
675                 return -EPERM;
676         if (pn_socket_autobind(sk->sk_socket))
677                 return -EAGAIN;
678
679         mutex_lock(&resource_mutex);
680         if (pnres.sk[res] == NULL) {
681                 sock_hold(sk);
682                 RCU_INIT_POINTER(pnres.sk[res], sk);
683                 ret = 0;
684         }
685         mutex_unlock(&resource_mutex);
686         return ret;
687 }
688
689 int pn_sock_unbind_res(struct sock *sk, u8 res)
690 {
691         int ret = -ENOENT;
692
693         if (!capable(CAP_SYS_ADMIN))
694                 return -EPERM;
695
696         mutex_lock(&resource_mutex);
697         if (pnres.sk[res] == sk) {
698                 RCU_INIT_POINTER(pnres.sk[res], NULL);
699                 ret = 0;
700         }
701         mutex_unlock(&resource_mutex);
702
703         if (ret == 0) {
704                 synchronize_rcu();
705                 sock_put(sk);
706         }
707         return ret;
708 }
709
710 void pn_sock_unbind_all_res(struct sock *sk)
711 {
712         unsigned res, match = 0;
713
714         mutex_lock(&resource_mutex);
715         for (res = 0; res < 256; res++) {
716                 if (pnres.sk[res] == sk) {
717                         RCU_INIT_POINTER(pnres.sk[res], NULL);
718                         match++;
719                 }
720         }
721         mutex_unlock(&resource_mutex);
722
723         while (match > 0) {
724                 __sock_put(sk);
725                 match--;
726         }
727         /* Caller is responsible for RCU sync before final sock_put() */
728 }
729
730 #ifdef CONFIG_PROC_FS
731 static struct sock **pn_res_get_idx(struct seq_file *seq, loff_t pos)
732 {
733         struct net *net = seq_file_net(seq);
734         unsigned i;
735
736         if (!net_eq(net, &init_net))
737                 return NULL;
738
739         for (i = 0; i < 256; i++) {
740                 if (pnres.sk[i] == NULL)
741                         continue;
742                 if (!pos)
743                         return pnres.sk + i;
744                 pos--;
745         }
746         return NULL;
747 }
748
749 static struct sock **pn_res_get_next(struct seq_file *seq, struct sock **sk)
750 {
751         struct net *net = seq_file_net(seq);
752         unsigned i;
753
754         BUG_ON(!net_eq(net, &init_net));
755
756         for (i = (sk - pnres.sk) + 1; i < 256; i++)
757                 if (pnres.sk[i])
758                         return pnres.sk + i;
759         return NULL;
760 }
761
762 static void *pn_res_seq_start(struct seq_file *seq, loff_t *pos)
763         __acquires(resource_mutex)
764 {
765         mutex_lock(&resource_mutex);
766         return *pos ? pn_res_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
767 }
768
769 static void *pn_res_seq_next(struct seq_file *seq, void *v, loff_t *pos)
770 {
771         struct sock **sk;
772
773         if (v == SEQ_START_TOKEN)
774                 sk = pn_res_get_idx(seq, 0);
775         else
776                 sk = pn_res_get_next(seq, v);
777         (*pos)++;
778         return sk;
779 }
780
781 static void pn_res_seq_stop(struct seq_file *seq, void *v)
782         __releases(resource_mutex)
783 {
784         mutex_unlock(&resource_mutex);
785 }
786
787 static int pn_res_seq_show(struct seq_file *seq, void *v)
788 {
789         int len;
790
791         if (v == SEQ_START_TOKEN)
792                 seq_printf(seq, "%s%n", "rs   uid inode", &len);
793         else {
794                 struct sock **psk = v;
795                 struct sock *sk = *psk;
796
797                 seq_printf(seq, "%02X %5d %lu%n",
798                            (int) (psk - pnres.sk), sock_i_uid(sk),
799                            sock_i_ino(sk), &len);
800         }
801         seq_printf(seq, "%*s\n", 63 - len, "");
802         return 0;
803 }
804
805 static const struct seq_operations pn_res_seq_ops = {
806         .start = pn_res_seq_start,
807         .next = pn_res_seq_next,
808         .stop = pn_res_seq_stop,
809         .show = pn_res_seq_show,
810 };
811
812 static int pn_res_open(struct inode *inode, struct file *file)
813 {
814         return seq_open_net(inode, file, &pn_res_seq_ops,
815                                 sizeof(struct seq_net_private));
816 }
817
818 const struct file_operations pn_res_seq_fops = {
819         .owner = THIS_MODULE,
820         .open = pn_res_open,
821         .read = seq_read,
822         .llseek = seq_lseek,
823         .release = seq_release_net,
824 };
825 #endif