0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/gfp.h>
0014 #include <linux/kernel.h>
0015 #include <linux/net.h>
0016 #include <linux/poll.h>
0017 #include <linux/sched/signal.h>
0018
0019 #include <net/sock.h>
0020 #include <net/tcp_states.h>
0021
0022 #include <linux/phonet.h>
0023 #include <linux/export.h>
0024 #include <net/phonet/phonet.h>
0025 #include <net/phonet/pep.h>
0026 #include <net/phonet/pn_dev.h>
0027
0028 static int pn_socket_release(struct socket *sock)
0029 {
0030 struct sock *sk = sock->sk;
0031
0032 if (sk) {
0033 sock->sk = NULL;
0034 sk->sk_prot->close(sk, 0);
0035 }
0036 return 0;
0037 }
0038
0039 #define PN_HASHSIZE 16
0040 #define PN_HASHMASK (PN_HASHSIZE-1)
0041
0042
0043 static struct {
0044 struct hlist_head hlist[PN_HASHSIZE];
0045 struct mutex lock;
0046 } pnsocks;
0047
0048 void __init pn_sock_init(void)
0049 {
0050 unsigned int i;
0051
0052 for (i = 0; i < PN_HASHSIZE; i++)
0053 INIT_HLIST_HEAD(pnsocks.hlist + i);
0054 mutex_init(&pnsocks.lock);
0055 }
0056
0057 static struct hlist_head *pn_hash_list(u16 obj)
0058 {
0059 return pnsocks.hlist + (obj & PN_HASHMASK);
0060 }
0061
0062
0063
0064
0065
0066 struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
0067 {
0068 struct sock *sknode;
0069 struct sock *rval = NULL;
0070 u16 obj = pn_sockaddr_get_object(spn);
0071 u8 res = spn->spn_resource;
0072 struct hlist_head *hlist = pn_hash_list(obj);
0073
0074 rcu_read_lock();
0075 sk_for_each_rcu(sknode, hlist) {
0076 struct pn_sock *pn = pn_sk(sknode);
0077 BUG_ON(!pn->sobject);
0078
0079 if (!net_eq(sock_net(sknode), net))
0080 continue;
0081 if (pn_port(obj)) {
0082
0083 if (pn_port(pn->sobject) != pn_port(obj))
0084 continue;
0085 } else {
0086
0087 if (pn->resource != res)
0088 continue;
0089 }
0090 if (pn_addr(pn->sobject) &&
0091 pn_addr(pn->sobject) != pn_addr(obj))
0092 continue;
0093
0094 rval = sknode;
0095 sock_hold(sknode);
0096 break;
0097 }
0098 rcu_read_unlock();
0099
0100 return rval;
0101 }
0102
0103
0104 void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
0105 {
0106 struct hlist_head *hlist = pnsocks.hlist;
0107 unsigned int h;
0108
0109 rcu_read_lock();
0110 for (h = 0; h < PN_HASHSIZE; h++) {
0111 struct sock *sknode;
0112
0113 sk_for_each(sknode, hlist) {
0114 struct sk_buff *clone;
0115
0116 if (!net_eq(sock_net(sknode), net))
0117 continue;
0118 if (!sock_flag(sknode, SOCK_BROADCAST))
0119 continue;
0120
0121 clone = skb_clone(skb, GFP_ATOMIC);
0122 if (clone) {
0123 sock_hold(sknode);
0124 sk_receive_skb(sknode, clone, 0);
0125 }
0126 }
0127 hlist++;
0128 }
0129 rcu_read_unlock();
0130 }
0131
0132 int pn_sock_hash(struct sock *sk)
0133 {
0134 struct hlist_head *hlist = pn_hash_list(pn_sk(sk)->sobject);
0135
0136 mutex_lock(&pnsocks.lock);
0137 sk_add_node_rcu(sk, hlist);
0138 mutex_unlock(&pnsocks.lock);
0139
0140 return 0;
0141 }
0142 EXPORT_SYMBOL(pn_sock_hash);
0143
0144 void pn_sock_unhash(struct sock *sk)
0145 {
0146 mutex_lock(&pnsocks.lock);
0147 sk_del_node_init_rcu(sk);
0148 mutex_unlock(&pnsocks.lock);
0149 pn_sock_unbind_all_res(sk);
0150 synchronize_rcu();
0151 }
0152 EXPORT_SYMBOL(pn_sock_unhash);
0153
0154 static DEFINE_MUTEX(port_mutex);
0155
0156 static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
0157 {
0158 struct sock *sk = sock->sk;
0159 struct pn_sock *pn = pn_sk(sk);
0160 struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
0161 int err;
0162 u16 handle;
0163 u8 saddr;
0164
0165 if (sk->sk_prot->bind)
0166 return sk->sk_prot->bind(sk, addr, len);
0167
0168 if (len < sizeof(struct sockaddr_pn))
0169 return -EINVAL;
0170 if (spn->spn_family != AF_PHONET)
0171 return -EAFNOSUPPORT;
0172
0173 handle = pn_sockaddr_get_object((struct sockaddr_pn *)addr);
0174 saddr = pn_addr(handle);
0175 if (saddr && phonet_address_lookup(sock_net(sk), saddr))
0176 return -EADDRNOTAVAIL;
0177
0178 lock_sock(sk);
0179 if (sk->sk_state != TCP_CLOSE || pn_port(pn->sobject)) {
0180 err = -EINVAL;
0181 goto out;
0182 }
0183 WARN_ON(sk_hashed(sk));
0184 mutex_lock(&port_mutex);
0185 err = sk->sk_prot->get_port(sk, pn_port(handle));
0186 if (err)
0187 goto out_port;
0188
0189
0190 pn->sobject = pn_object(saddr, pn_port(pn->sobject));
0191 pn->resource = spn->spn_resource;
0192
0193
0194 err = sk->sk_prot->hash(sk);
0195 out_port:
0196 mutex_unlock(&port_mutex);
0197 out:
0198 release_sock(sk);
0199 return err;
0200 }
0201
0202 static int pn_socket_autobind(struct socket *sock)
0203 {
0204 struct sockaddr_pn sa;
0205 int err;
0206
0207 memset(&sa, 0, sizeof(sa));
0208 sa.spn_family = AF_PHONET;
0209 err = pn_socket_bind(sock, (struct sockaddr *)&sa,
0210 sizeof(struct sockaddr_pn));
0211 if (err != -EINVAL)
0212 return err;
0213 BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
0214 return 0;
0215 }
0216
0217 static int pn_socket_connect(struct socket *sock, struct sockaddr *addr,
0218 int len, int flags)
0219 {
0220 struct sock *sk = sock->sk;
0221 struct pn_sock *pn = pn_sk(sk);
0222 struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
0223 struct task_struct *tsk = current;
0224 long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
0225 int err;
0226
0227 if (pn_socket_autobind(sock))
0228 return -ENOBUFS;
0229 if (len < sizeof(struct sockaddr_pn))
0230 return -EINVAL;
0231 if (spn->spn_family != AF_PHONET)
0232 return -EAFNOSUPPORT;
0233
0234 lock_sock(sk);
0235
0236 switch (sock->state) {
0237 case SS_UNCONNECTED:
0238 if (sk->sk_state != TCP_CLOSE) {
0239 err = -EISCONN;
0240 goto out;
0241 }
0242 break;
0243 case SS_CONNECTING:
0244 err = -EALREADY;
0245 goto out;
0246 default:
0247 err = -EISCONN;
0248 goto out;
0249 }
0250
0251 pn->dobject = pn_sockaddr_get_object(spn);
0252 pn->resource = pn_sockaddr_get_resource(spn);
0253 sock->state = SS_CONNECTING;
0254
0255 err = sk->sk_prot->connect(sk, addr, len);
0256 if (err) {
0257 sock->state = SS_UNCONNECTED;
0258 pn->dobject = 0;
0259 goto out;
0260 }
0261
0262 while (sk->sk_state == TCP_SYN_SENT) {
0263 DEFINE_WAIT(wait);
0264
0265 if (!timeo) {
0266 err = -EINPROGRESS;
0267 goto out;
0268 }
0269 if (signal_pending(tsk)) {
0270 err = sock_intr_errno(timeo);
0271 goto out;
0272 }
0273
0274 prepare_to_wait_exclusive(sk_sleep(sk), &wait,
0275 TASK_INTERRUPTIBLE);
0276 release_sock(sk);
0277 timeo = schedule_timeout(timeo);
0278 lock_sock(sk);
0279 finish_wait(sk_sleep(sk), &wait);
0280 }
0281
0282 if ((1 << sk->sk_state) & (TCPF_SYN_RECV|TCPF_ESTABLISHED))
0283 err = 0;
0284 else if (sk->sk_state == TCP_CLOSE_WAIT)
0285 err = -ECONNRESET;
0286 else
0287 err = -ECONNREFUSED;
0288 sock->state = err ? SS_UNCONNECTED : SS_CONNECTED;
0289 out:
0290 release_sock(sk);
0291 return err;
0292 }
0293
0294 static int pn_socket_accept(struct socket *sock, struct socket *newsock,
0295 int flags, bool kern)
0296 {
0297 struct sock *sk = sock->sk;
0298 struct sock *newsk;
0299 int err;
0300
0301 if (unlikely(sk->sk_state != TCP_LISTEN))
0302 return -EINVAL;
0303
0304 newsk = sk->sk_prot->accept(sk, flags, &err, kern);
0305 if (!newsk)
0306 return err;
0307
0308 lock_sock(newsk);
0309 sock_graft(newsk, newsock);
0310 newsock->state = SS_CONNECTED;
0311 release_sock(newsk);
0312 return 0;
0313 }
0314
0315 static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
0316 int peer)
0317 {
0318 struct sock *sk = sock->sk;
0319 struct pn_sock *pn = pn_sk(sk);
0320
0321 memset(addr, 0, sizeof(struct sockaddr_pn));
0322 addr->sa_family = AF_PHONET;
0323 if (!peer)
0324 pn_sockaddr_set_object((struct sockaddr_pn *)addr,
0325 pn->sobject);
0326
0327 return sizeof(struct sockaddr_pn);
0328 }
0329
0330 static __poll_t pn_socket_poll(struct file *file, struct socket *sock,
0331 poll_table *wait)
0332 {
0333 struct sock *sk = sock->sk;
0334 struct pep_sock *pn = pep_sk(sk);
0335 __poll_t mask = 0;
0336
0337 poll_wait(file, sk_sleep(sk), wait);
0338
0339 if (sk->sk_state == TCP_CLOSE)
0340 return EPOLLERR;
0341 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
0342 mask |= EPOLLIN | EPOLLRDNORM;
0343 if (!skb_queue_empty_lockless(&pn->ctrlreq_queue))
0344 mask |= EPOLLPRI;
0345 if (!mask && sk->sk_state == TCP_CLOSE_WAIT)
0346 return EPOLLHUP;
0347
0348 if (sk->sk_state == TCP_ESTABLISHED &&
0349 refcount_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf &&
0350 atomic_read(&pn->tx_credits))
0351 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
0352
0353 return mask;
0354 }
0355
0356 static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
0357 unsigned long arg)
0358 {
0359 struct sock *sk = sock->sk;
0360 struct pn_sock *pn = pn_sk(sk);
0361
0362 if (cmd == SIOCPNGETOBJECT) {
0363 struct net_device *dev;
0364 u16 handle;
0365 u8 saddr;
0366
0367 if (get_user(handle, (__u16 __user *)arg))
0368 return -EFAULT;
0369
0370 lock_sock(sk);
0371 if (sk->sk_bound_dev_if)
0372 dev = dev_get_by_index(sock_net(sk),
0373 sk->sk_bound_dev_if);
0374 else
0375 dev = phonet_device_get(sock_net(sk));
0376 if (dev && (dev->flags & IFF_UP))
0377 saddr = phonet_address_get(dev, pn_addr(handle));
0378 else
0379 saddr = PN_NO_ADDR;
0380 release_sock(sk);
0381
0382 dev_put(dev);
0383 if (saddr == PN_NO_ADDR)
0384 return -EHOSTUNREACH;
0385
0386 handle = pn_object(saddr, pn_port(pn->sobject));
0387 return put_user(handle, (__u16 __user *)arg);
0388 }
0389
0390 return sk->sk_prot->ioctl(sk, cmd, arg);
0391 }
0392
0393 static int pn_socket_listen(struct socket *sock, int backlog)
0394 {
0395 struct sock *sk = sock->sk;
0396 int err = 0;
0397
0398 if (pn_socket_autobind(sock))
0399 return -ENOBUFS;
0400
0401 lock_sock(sk);
0402 if (sock->state != SS_UNCONNECTED) {
0403 err = -EINVAL;
0404 goto out;
0405 }
0406
0407 if (sk->sk_state != TCP_LISTEN) {
0408 sk->sk_state = TCP_LISTEN;
0409 sk->sk_ack_backlog = 0;
0410 }
0411 sk->sk_max_ack_backlog = backlog;
0412 out:
0413 release_sock(sk);
0414 return err;
0415 }
0416
0417 static int pn_socket_sendmsg(struct socket *sock, struct msghdr *m,
0418 size_t total_len)
0419 {
0420 struct sock *sk = sock->sk;
0421
0422 if (pn_socket_autobind(sock))
0423 return -EAGAIN;
0424
0425 return sk->sk_prot->sendmsg(sk, m, total_len);
0426 }
0427
0428 const struct proto_ops phonet_dgram_ops = {
0429 .family = AF_PHONET,
0430 .owner = THIS_MODULE,
0431 .release = pn_socket_release,
0432 .bind = pn_socket_bind,
0433 .connect = sock_no_connect,
0434 .socketpair = sock_no_socketpair,
0435 .accept = sock_no_accept,
0436 .getname = pn_socket_getname,
0437 .poll = datagram_poll,
0438 .ioctl = pn_socket_ioctl,
0439 .listen = sock_no_listen,
0440 .shutdown = sock_no_shutdown,
0441 .sendmsg = pn_socket_sendmsg,
0442 .recvmsg = sock_common_recvmsg,
0443 .mmap = sock_no_mmap,
0444 .sendpage = sock_no_sendpage,
0445 };
0446
0447 const struct proto_ops phonet_stream_ops = {
0448 .family = AF_PHONET,
0449 .owner = THIS_MODULE,
0450 .release = pn_socket_release,
0451 .bind = pn_socket_bind,
0452 .connect = pn_socket_connect,
0453 .socketpair = sock_no_socketpair,
0454 .accept = pn_socket_accept,
0455 .getname = pn_socket_getname,
0456 .poll = pn_socket_poll,
0457 .ioctl = pn_socket_ioctl,
0458 .listen = pn_socket_listen,
0459 .shutdown = sock_no_shutdown,
0460 .setsockopt = sock_common_setsockopt,
0461 .getsockopt = sock_common_getsockopt,
0462 .sendmsg = pn_socket_sendmsg,
0463 .recvmsg = sock_common_recvmsg,
0464 .mmap = sock_no_mmap,
0465 .sendpage = sock_no_sendpage,
0466 };
0467 EXPORT_SYMBOL(phonet_stream_ops);
0468
0469
0470 int pn_sock_get_port(struct sock *sk, unsigned short sport)
0471 {
0472 static int port_cur;
0473 struct net *net = sock_net(sk);
0474 struct pn_sock *pn = pn_sk(sk);
0475 struct sockaddr_pn try_sa;
0476 struct sock *tmpsk;
0477
0478 memset(&try_sa, 0, sizeof(struct sockaddr_pn));
0479 try_sa.spn_family = AF_PHONET;
0480 WARN_ON(!mutex_is_locked(&port_mutex));
0481 if (!sport) {
0482
0483 int port, pmin, pmax;
0484
0485 phonet_get_local_port_range(&pmin, &pmax);
0486 for (port = pmin; port <= pmax; port++) {
0487 port_cur++;
0488 if (port_cur < pmin || port_cur > pmax)
0489 port_cur = pmin;
0490
0491 pn_sockaddr_set_port(&try_sa, port_cur);
0492 tmpsk = pn_find_sock_by_sa(net, &try_sa);
0493 if (tmpsk == NULL) {
0494 sport = port_cur;
0495 goto found;
0496 } else
0497 sock_put(tmpsk);
0498 }
0499 } else {
0500
0501 pn_sockaddr_set_port(&try_sa, sport);
0502 tmpsk = pn_find_sock_by_sa(net, &try_sa);
0503 if (tmpsk == NULL)
0504
0505 goto found;
0506 else
0507 sock_put(tmpsk);
0508 }
0509
0510 return -EADDRINUSE;
0511
0512 found:
0513 pn->sobject = pn_object(pn_addr(pn->sobject), sport);
0514 return 0;
0515 }
0516 EXPORT_SYMBOL(pn_sock_get_port);
0517
0518 #ifdef CONFIG_PROC_FS
0519 static struct sock *pn_sock_get_idx(struct seq_file *seq, loff_t pos)
0520 {
0521 struct net *net = seq_file_net(seq);
0522 struct hlist_head *hlist = pnsocks.hlist;
0523 struct sock *sknode;
0524 unsigned int h;
0525
0526 for (h = 0; h < PN_HASHSIZE; h++) {
0527 sk_for_each_rcu(sknode, hlist) {
0528 if (!net_eq(net, sock_net(sknode)))
0529 continue;
0530 if (!pos)
0531 return sknode;
0532 pos--;
0533 }
0534 hlist++;
0535 }
0536 return NULL;
0537 }
0538
0539 static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk)
0540 {
0541 struct net *net = seq_file_net(seq);
0542
0543 do
0544 sk = sk_next(sk);
0545 while (sk && !net_eq(net, sock_net(sk)));
0546
0547 return sk;
0548 }
0549
0550 static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos)
0551 __acquires(rcu)
0552 {
0553 rcu_read_lock();
0554 return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
0555 }
0556
0557 static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos)
0558 {
0559 struct sock *sk;
0560
0561 if (v == SEQ_START_TOKEN)
0562 sk = pn_sock_get_idx(seq, 0);
0563 else
0564 sk = pn_sock_get_next(seq, v);
0565 (*pos)++;
0566 return sk;
0567 }
0568
0569 static void pn_sock_seq_stop(struct seq_file *seq, void *v)
0570 __releases(rcu)
0571 {
0572 rcu_read_unlock();
0573 }
0574
0575 static int pn_sock_seq_show(struct seq_file *seq, void *v)
0576 {
0577 seq_setwidth(seq, 127);
0578 if (v == SEQ_START_TOKEN)
0579 seq_puts(seq, "pt loc rem rs st tx_queue rx_queue "
0580 " uid inode ref pointer drops");
0581 else {
0582 struct sock *sk = v;
0583 struct pn_sock *pn = pn_sk(sk);
0584
0585 seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu "
0586 "%d %pK %u",
0587 sk->sk_protocol, pn->sobject, pn->dobject,
0588 pn->resource, sk->sk_state,
0589 sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
0590 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
0591 sock_i_ino(sk),
0592 refcount_read(&sk->sk_refcnt), sk,
0593 atomic_read(&sk->sk_drops));
0594 }
0595 seq_pad(seq, '\n');
0596 return 0;
0597 }
0598
0599 const struct seq_operations pn_sock_seq_ops = {
0600 .start = pn_sock_seq_start,
0601 .next = pn_sock_seq_next,
0602 .stop = pn_sock_seq_stop,
0603 .show = pn_sock_seq_show,
0604 };
0605 #endif
0606
0607 static struct {
0608 struct sock *sk[256];
0609 } pnres;
0610
0611
0612
0613
0614 struct sock *pn_find_sock_by_res(struct net *net, u8 res)
0615 {
0616 struct sock *sk;
0617
0618 if (!net_eq(net, &init_net))
0619 return NULL;
0620
0621 rcu_read_lock();
0622 sk = rcu_dereference(pnres.sk[res]);
0623 if (sk)
0624 sock_hold(sk);
0625 rcu_read_unlock();
0626 return sk;
0627 }
0628
0629 static DEFINE_MUTEX(resource_mutex);
0630
0631 int pn_sock_bind_res(struct sock *sk, u8 res)
0632 {
0633 int ret = -EADDRINUSE;
0634
0635 if (!net_eq(sock_net(sk), &init_net))
0636 return -ENOIOCTLCMD;
0637 if (!capable(CAP_SYS_ADMIN))
0638 return -EPERM;
0639 if (pn_socket_autobind(sk->sk_socket))
0640 return -EAGAIN;
0641
0642 mutex_lock(&resource_mutex);
0643 if (pnres.sk[res] == NULL) {
0644 sock_hold(sk);
0645 rcu_assign_pointer(pnres.sk[res], sk);
0646 ret = 0;
0647 }
0648 mutex_unlock(&resource_mutex);
0649 return ret;
0650 }
0651
0652 int pn_sock_unbind_res(struct sock *sk, u8 res)
0653 {
0654 int ret = -ENOENT;
0655
0656 if (!capable(CAP_SYS_ADMIN))
0657 return -EPERM;
0658
0659 mutex_lock(&resource_mutex);
0660 if (pnres.sk[res] == sk) {
0661 RCU_INIT_POINTER(pnres.sk[res], NULL);
0662 ret = 0;
0663 }
0664 mutex_unlock(&resource_mutex);
0665
0666 if (ret == 0) {
0667 synchronize_rcu();
0668 sock_put(sk);
0669 }
0670 return ret;
0671 }
0672
0673 void pn_sock_unbind_all_res(struct sock *sk)
0674 {
0675 unsigned int res, match = 0;
0676
0677 mutex_lock(&resource_mutex);
0678 for (res = 0; res < 256; res++) {
0679 if (pnres.sk[res] == sk) {
0680 RCU_INIT_POINTER(pnres.sk[res], NULL);
0681 match++;
0682 }
0683 }
0684 mutex_unlock(&resource_mutex);
0685
0686 while (match > 0) {
0687 __sock_put(sk);
0688 match--;
0689 }
0690
0691 }
0692
0693 #ifdef CONFIG_PROC_FS
0694 static struct sock **pn_res_get_idx(struct seq_file *seq, loff_t pos)
0695 {
0696 struct net *net = seq_file_net(seq);
0697 unsigned int i;
0698
0699 if (!net_eq(net, &init_net))
0700 return NULL;
0701
0702 for (i = 0; i < 256; i++) {
0703 if (pnres.sk[i] == NULL)
0704 continue;
0705 if (!pos)
0706 return pnres.sk + i;
0707 pos--;
0708 }
0709 return NULL;
0710 }
0711
0712 static struct sock **pn_res_get_next(struct seq_file *seq, struct sock **sk)
0713 {
0714 struct net *net = seq_file_net(seq);
0715 unsigned int i;
0716
0717 BUG_ON(!net_eq(net, &init_net));
0718
0719 for (i = (sk - pnres.sk) + 1; i < 256; i++)
0720 if (pnres.sk[i])
0721 return pnres.sk + i;
0722 return NULL;
0723 }
0724
0725 static void *pn_res_seq_start(struct seq_file *seq, loff_t *pos)
0726 __acquires(resource_mutex)
0727 {
0728 mutex_lock(&resource_mutex);
0729 return *pos ? pn_res_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
0730 }
0731
0732 static void *pn_res_seq_next(struct seq_file *seq, void *v, loff_t *pos)
0733 {
0734 struct sock **sk;
0735
0736 if (v == SEQ_START_TOKEN)
0737 sk = pn_res_get_idx(seq, 0);
0738 else
0739 sk = pn_res_get_next(seq, v);
0740 (*pos)++;
0741 return sk;
0742 }
0743
0744 static void pn_res_seq_stop(struct seq_file *seq, void *v)
0745 __releases(resource_mutex)
0746 {
0747 mutex_unlock(&resource_mutex);
0748 }
0749
0750 static int pn_res_seq_show(struct seq_file *seq, void *v)
0751 {
0752 seq_setwidth(seq, 63);
0753 if (v == SEQ_START_TOKEN)
0754 seq_puts(seq, "rs uid inode");
0755 else {
0756 struct sock **psk = v;
0757 struct sock *sk = *psk;
0758
0759 seq_printf(seq, "%02X %5u %lu",
0760 (int) (psk - pnres.sk),
0761 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
0762 sock_i_ino(sk));
0763 }
0764 seq_pad(seq, '\n');
0765 return 0;
0766 }
0767
0768 const struct seq_operations pn_res_seq_ops = {
0769 .start = pn_res_seq_start,
0770 .next = pn_res_seq_next,
0771 .stop = pn_res_seq_stop,
0772 .show = pn_res_seq_show,
0773 };
0774 #endif