diff options
author | Christoph Hellwig <hch@lst.de> | 2015-01-28 12:04:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-29 02:15:07 -0500 |
commit | 7cc05662682da4b0e0a4fdf3c3f190577803ae81 (patch) | |
tree | 0c7fe7b2e90ba7d28cf05d4151813a03fe321b47 | |
parent | a154e6f6efdd13d7254679b5a99d9b912017621f (diff) |
net: remove sock_iocb
The sock_iocb structure is allocate on stack for each read/write-like
operation on sockets, and contains various fields of which only the
embedded msghdr and sometimes a pointer to the scm_cookie is ever used.
Get rid of the sock_iocb and put a msghdr directly on the stack and pass
the scm_cookie explicitly to netlink_mmap_sendmsg.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/sock.h | 23 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 28 | ||||
-rw-r--r-- | net/socket.c | 45 | ||||
-rw-r--r-- | net/unix/af_unix.c | 73 |
4 files changed, 43 insertions, 126 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index 2210fec65669..15341499786c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -1374,29 +1374,6 @@ void sk_prot_clear_portaddr_nulls(struct sock *sk, int size); | |||
1374 | #define SOCK_BINDADDR_LOCK 4 | 1374 | #define SOCK_BINDADDR_LOCK 4 |
1375 | #define SOCK_BINDPORT_LOCK 8 | 1375 | #define SOCK_BINDPORT_LOCK 8 |
1376 | 1376 | ||
1377 | /* sock_iocb: used to kick off async processing of socket ios */ | ||
1378 | struct sock_iocb { | ||
1379 | struct list_head list; | ||
1380 | |||
1381 | int flags; | ||
1382 | int size; | ||
1383 | struct socket *sock; | ||
1384 | struct sock *sk; | ||
1385 | struct scm_cookie *scm; | ||
1386 | struct msghdr *msg, async_msg; | ||
1387 | struct kiocb *kiocb; | ||
1388 | }; | ||
1389 | |||
1390 | static inline struct sock_iocb *kiocb_to_siocb(struct kiocb *iocb) | ||
1391 | { | ||
1392 | return (struct sock_iocb *)iocb->private; | ||
1393 | } | ||
1394 | |||
1395 | static inline struct kiocb *siocb_to_kiocb(struct sock_iocb *si) | ||
1396 | { | ||
1397 | return si->kiocb; | ||
1398 | } | ||
1399 | |||
1400 | struct socket_alloc { | 1377 | struct socket_alloc { |
1401 | struct socket socket; | 1378 | struct socket socket; |
1402 | struct inode vfs_inode; | 1379 | struct inode vfs_inode; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 2197af00673a..a36777b7cfb6 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -695,7 +695,7 @@ static void netlink_ring_setup_skb(struct sk_buff *skb, struct sock *sk, | |||
695 | 695 | ||
696 | static int netlink_mmap_sendmsg(struct sock *sk, struct msghdr *msg, | 696 | static int netlink_mmap_sendmsg(struct sock *sk, struct msghdr *msg, |
697 | u32 dst_portid, u32 dst_group, | 697 | u32 dst_portid, u32 dst_group, |
698 | struct sock_iocb *siocb) | 698 | struct scm_cookie *scm) |
699 | { | 699 | { |
700 | struct netlink_sock *nlk = nlk_sk(sk); | 700 | struct netlink_sock *nlk = nlk_sk(sk); |
701 | struct netlink_ring *ring; | 701 | struct netlink_ring *ring; |
@@ -741,7 +741,7 @@ static int netlink_mmap_sendmsg(struct sock *sk, struct msghdr *msg, | |||
741 | 741 | ||
742 | NETLINK_CB(skb).portid = nlk->portid; | 742 | NETLINK_CB(skb).portid = nlk->portid; |
743 | NETLINK_CB(skb).dst_group = dst_group; | 743 | NETLINK_CB(skb).dst_group = dst_group; |
744 | NETLINK_CB(skb).creds = siocb->scm->creds; | 744 | NETLINK_CB(skb).creds = scm->creds; |
745 | 745 | ||
746 | err = security_netlink_send(sk, skb); | 746 | err = security_netlink_send(sk, skb); |
747 | if (err) { | 747 | if (err) { |
@@ -820,7 +820,7 @@ static void netlink_ring_set_copied(struct sock *sk, struct sk_buff *skb) | |||
820 | #define netlink_tx_is_mmaped(sk) false | 820 | #define netlink_tx_is_mmaped(sk) false |
821 | #define netlink_mmap sock_no_mmap | 821 | #define netlink_mmap sock_no_mmap |
822 | #define netlink_poll datagram_poll | 822 | #define netlink_poll datagram_poll |
823 | #define netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, siocb) 0 | 823 | #define netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, scm) 0 |
824 | #endif /* CONFIG_NETLINK_MMAP */ | 824 | #endif /* CONFIG_NETLINK_MMAP */ |
825 | 825 | ||
826 | static void netlink_skb_destructor(struct sk_buff *skb) | 826 | static void netlink_skb_destructor(struct sk_buff *skb) |
@@ -2259,7 +2259,6 @@ static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) | |||
2259 | static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | 2259 | static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, |
2260 | struct msghdr *msg, size_t len) | 2260 | struct msghdr *msg, size_t len) |
2261 | { | 2261 | { |
2262 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); | ||
2263 | struct sock *sk = sock->sk; | 2262 | struct sock *sk = sock->sk; |
2264 | struct netlink_sock *nlk = nlk_sk(sk); | 2263 | struct netlink_sock *nlk = nlk_sk(sk); |
2265 | DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name); | 2264 | DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name); |
@@ -2273,10 +2272,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
2273 | if (msg->msg_flags&MSG_OOB) | 2272 | if (msg->msg_flags&MSG_OOB) |
2274 | return -EOPNOTSUPP; | 2273 | return -EOPNOTSUPP; |
2275 | 2274 | ||
2276 | if (NULL == siocb->scm) | 2275 | err = scm_send(sock, msg, &scm, true); |
2277 | siocb->scm = &scm; | ||
2278 | |||
2279 | err = scm_send(sock, msg, siocb->scm, true); | ||
2280 | if (err < 0) | 2276 | if (err < 0) |
2281 | return err; | 2277 | return err; |
2282 | 2278 | ||
@@ -2305,7 +2301,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
2305 | if (netlink_tx_is_mmaped(sk) && | 2301 | if (netlink_tx_is_mmaped(sk) && |
2306 | msg->msg_iter.iov->iov_base == NULL) { | 2302 | msg->msg_iter.iov->iov_base == NULL) { |
2307 | err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, | 2303 | err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, |
2308 | siocb); | 2304 | &scm); |
2309 | goto out; | 2305 | goto out; |
2310 | } | 2306 | } |
2311 | 2307 | ||
@@ -2319,7 +2315,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
2319 | 2315 | ||
2320 | NETLINK_CB(skb).portid = nlk->portid; | 2316 | NETLINK_CB(skb).portid = nlk->portid; |
2321 | NETLINK_CB(skb).dst_group = dst_group; | 2317 | NETLINK_CB(skb).dst_group = dst_group; |
2322 | NETLINK_CB(skb).creds = siocb->scm->creds; | 2318 | NETLINK_CB(skb).creds = scm.creds; |
2323 | NETLINK_CB(skb).flags = netlink_skb_flags; | 2319 | NETLINK_CB(skb).flags = netlink_skb_flags; |
2324 | 2320 | ||
2325 | err = -EFAULT; | 2321 | err = -EFAULT; |
@@ -2341,7 +2337,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
2341 | err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT); | 2337 | err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT); |
2342 | 2338 | ||
2343 | out: | 2339 | out: |
2344 | scm_destroy(siocb->scm); | 2340 | scm_destroy(&scm); |
2345 | return err; | 2341 | return err; |
2346 | } | 2342 | } |
2347 | 2343 | ||
@@ -2349,7 +2345,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
2349 | struct msghdr *msg, size_t len, | 2345 | struct msghdr *msg, size_t len, |
2350 | int flags) | 2346 | int flags) |
2351 | { | 2347 | { |
2352 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); | ||
2353 | struct scm_cookie scm; | 2348 | struct scm_cookie scm; |
2354 | struct sock *sk = sock->sk; | 2349 | struct sock *sk = sock->sk; |
2355 | struct netlink_sock *nlk = nlk_sk(sk); | 2350 | struct netlink_sock *nlk = nlk_sk(sk); |
@@ -2412,11 +2407,8 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
2412 | if (nlk->flags & NETLINK_RECV_PKTINFO) | 2407 | if (nlk->flags & NETLINK_RECV_PKTINFO) |
2413 | netlink_cmsg_recv_pktinfo(msg, skb); | 2408 | netlink_cmsg_recv_pktinfo(msg, skb); |
2414 | 2409 | ||
2415 | if (NULL == siocb->scm) { | 2410 | memset(&scm, 0, sizeof(scm)); |
2416 | memset(&scm, 0, sizeof(scm)); | 2411 | scm.creds = *NETLINK_CREDS(skb); |
2417 | siocb->scm = &scm; | ||
2418 | } | ||
2419 | siocb->scm->creds = *NETLINK_CREDS(skb); | ||
2420 | if (flags & MSG_TRUNC) | 2412 | if (flags & MSG_TRUNC) |
2421 | copied = data_skb->len; | 2413 | copied = data_skb->len; |
2422 | 2414 | ||
@@ -2431,7 +2423,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
2431 | } | 2423 | } |
2432 | } | 2424 | } |
2433 | 2425 | ||
2434 | scm_recv(sock, msg, siocb->scm, flags); | 2426 | scm_recv(sock, msg, &scm, flags); |
2435 | out: | 2427 | out: |
2436 | netlink_rcv_wake(sk); | 2428 | netlink_rcv_wake(sk); |
2437 | return err ? : copied; | 2429 | return err ? : copied; |
diff --git a/net/socket.c b/net/socket.c index 3acd35f144d6..3326d67482ac 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -613,13 +613,6 @@ EXPORT_SYMBOL(__sock_tx_timestamp); | |||
613 | static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock, | 613 | static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock, |
614 | struct msghdr *msg, size_t size) | 614 | struct msghdr *msg, size_t size) |
615 | { | 615 | { |
616 | struct sock_iocb *si = kiocb_to_siocb(iocb); | ||
617 | |||
618 | si->sock = sock; | ||
619 | si->scm = NULL; | ||
620 | si->msg = msg; | ||
621 | si->size = size; | ||
622 | |||
623 | return sock->ops->sendmsg(iocb, sock, msg, size); | 616 | return sock->ops->sendmsg(iocb, sock, msg, size); |
624 | } | 617 | } |
625 | 618 | ||
@@ -635,11 +628,9 @@ static int do_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
635 | size_t size, bool nosec) | 628 | size_t size, bool nosec) |
636 | { | 629 | { |
637 | struct kiocb iocb; | 630 | struct kiocb iocb; |
638 | struct sock_iocb siocb; | ||
639 | int ret; | 631 | int ret; |
640 | 632 | ||
641 | init_sync_kiocb(&iocb, NULL); | 633 | init_sync_kiocb(&iocb, NULL); |
642 | iocb.private = &siocb; | ||
643 | ret = nosec ? __sock_sendmsg_nosec(&iocb, sock, msg, size) : | 634 | ret = nosec ? __sock_sendmsg_nosec(&iocb, sock, msg, size) : |
644 | __sock_sendmsg(&iocb, sock, msg, size); | 635 | __sock_sendmsg(&iocb, sock, msg, size); |
645 | if (-EIOCBQUEUED == ret) | 636 | if (-EIOCBQUEUED == ret) |
@@ -756,14 +747,6 @@ EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops); | |||
756 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, | 747 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, |
757 | struct msghdr *msg, size_t size, int flags) | 748 | struct msghdr *msg, size_t size, int flags) |
758 | { | 749 | { |
759 | struct sock_iocb *si = kiocb_to_siocb(iocb); | ||
760 | |||
761 | si->sock = sock; | ||
762 | si->scm = NULL; | ||
763 | si->msg = msg; | ||
764 | si->size = size; | ||
765 | si->flags = flags; | ||
766 | |||
767 | return sock->ops->recvmsg(iocb, sock, msg, size, flags); | 750 | return sock->ops->recvmsg(iocb, sock, msg, size, flags); |
768 | } | 751 | } |
769 | 752 | ||
@@ -779,11 +762,9 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg, | |||
779 | size_t size, int flags) | 762 | size_t size, int flags) |
780 | { | 763 | { |
781 | struct kiocb iocb; | 764 | struct kiocb iocb; |
782 | struct sock_iocb siocb; | ||
783 | int ret; | 765 | int ret; |
784 | 766 | ||
785 | init_sync_kiocb(&iocb, NULL); | 767 | init_sync_kiocb(&iocb, NULL); |
786 | iocb.private = &siocb; | ||
787 | ret = __sock_recvmsg(&iocb, sock, msg, size, flags); | 768 | ret = __sock_recvmsg(&iocb, sock, msg, size, flags); |
788 | if (-EIOCBQUEUED == ret) | 769 | if (-EIOCBQUEUED == ret) |
789 | ret = wait_on_sync_kiocb(&iocb); | 770 | ret = wait_on_sync_kiocb(&iocb); |
@@ -795,11 +776,9 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, | |||
795 | size_t size, int flags) | 776 | size_t size, int flags) |
796 | { | 777 | { |
797 | struct kiocb iocb; | 778 | struct kiocb iocb; |
798 | struct sock_iocb siocb; | ||
799 | int ret; | 779 | int ret; |
800 | 780 | ||
801 | init_sync_kiocb(&iocb, NULL); | 781 | init_sync_kiocb(&iocb, NULL); |
802 | iocb.private = &siocb; | ||
803 | ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags); | 782 | ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags); |
804 | if (-EIOCBQUEUED == ret) | 783 | if (-EIOCBQUEUED == ret) |
805 | ret = wait_on_sync_kiocb(&iocb); | 784 | ret = wait_on_sync_kiocb(&iocb); |
@@ -866,14 +845,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | |||
866 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); | 845 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); |
867 | } | 846 | } |
868 | 847 | ||
869 | static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, | ||
870 | struct sock_iocb *siocb) | ||
871 | { | ||
872 | siocb->kiocb = iocb; | ||
873 | iocb->private = siocb; | ||
874 | return siocb; | ||
875 | } | ||
876 | |||
877 | static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, | 848 | static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, |
878 | struct file *file, const struct iovec *iov, | 849 | struct file *file, const struct iovec *iov, |
879 | unsigned long nr_segs) | 850 | unsigned long nr_segs) |
@@ -893,7 +864,7 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, | |||
893 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, | 864 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
894 | unsigned long nr_segs, loff_t pos) | 865 | unsigned long nr_segs, loff_t pos) |
895 | { | 866 | { |
896 | struct sock_iocb siocb, *x; | 867 | struct msghdr msg; |
897 | 868 | ||
898 | if (pos != 0) | 869 | if (pos != 0) |
899 | return -ESPIPE; | 870 | return -ESPIPE; |
@@ -901,11 +872,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
901 | if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */ | 872 | if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */ |
902 | return 0; | 873 | return 0; |
903 | 874 | ||
904 | 875 | return do_sock_read(&msg, iocb, iocb->ki_filp, iov, nr_segs); | |
905 | x = alloc_sock_iocb(iocb, &siocb); | ||
906 | if (!x) | ||
907 | return -ENOMEM; | ||
908 | return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs); | ||
909 | } | 876 | } |
910 | 877 | ||
911 | static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, | 878 | static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, |
@@ -929,16 +896,12 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, | |||
929 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, | 896 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, |
930 | unsigned long nr_segs, loff_t pos) | 897 | unsigned long nr_segs, loff_t pos) |
931 | { | 898 | { |
932 | struct sock_iocb siocb, *x; | 899 | struct msghdr msg; |
933 | 900 | ||
934 | if (pos != 0) | 901 | if (pos != 0) |
935 | return -ESPIPE; | 902 | return -ESPIPE; |
936 | 903 | ||
937 | x = alloc_sock_iocb(iocb, &siocb); | 904 | return do_sock_write(&msg, iocb, iocb->ki_filp, iov, nr_segs); |
938 | if (!x) | ||
939 | return -ENOMEM; | ||
940 | |||
941 | return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs); | ||
942 | } | 905 | } |
943 | 906 | ||
944 | /* | 907 | /* |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 8e1b10274b02..526b6edab018 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1445,7 +1445,6 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, | |||
1445 | static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | 1445 | static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, |
1446 | struct msghdr *msg, size_t len) | 1446 | struct msghdr *msg, size_t len) |
1447 | { | 1447 | { |
1448 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); | ||
1449 | struct sock *sk = sock->sk; | 1448 | struct sock *sk = sock->sk; |
1450 | struct net *net = sock_net(sk); | 1449 | struct net *net = sock_net(sk); |
1451 | struct unix_sock *u = unix_sk(sk); | 1450 | struct unix_sock *u = unix_sk(sk); |
@@ -1456,14 +1455,12 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1456 | unsigned int hash; | 1455 | unsigned int hash; |
1457 | struct sk_buff *skb; | 1456 | struct sk_buff *skb; |
1458 | long timeo; | 1457 | long timeo; |
1459 | struct scm_cookie tmp_scm; | 1458 | struct scm_cookie scm; |
1460 | int max_level; | 1459 | int max_level; |
1461 | int data_len = 0; | 1460 | int data_len = 0; |
1462 | 1461 | ||
1463 | if (NULL == siocb->scm) | ||
1464 | siocb->scm = &tmp_scm; | ||
1465 | wait_for_unix_gc(); | 1462 | wait_for_unix_gc(); |
1466 | err = scm_send(sock, msg, siocb->scm, false); | 1463 | err = scm_send(sock, msg, &scm, false); |
1467 | if (err < 0) | 1464 | if (err < 0) |
1468 | return err; | 1465 | return err; |
1469 | 1466 | ||
@@ -1507,11 +1504,11 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1507 | if (skb == NULL) | 1504 | if (skb == NULL) |
1508 | goto out; | 1505 | goto out; |
1509 | 1506 | ||
1510 | err = unix_scm_to_skb(siocb->scm, skb, true); | 1507 | err = unix_scm_to_skb(&scm, skb, true); |
1511 | if (err < 0) | 1508 | if (err < 0) |
1512 | goto out_free; | 1509 | goto out_free; |
1513 | max_level = err + 1; | 1510 | max_level = err + 1; |
1514 | unix_get_secdata(siocb->scm, skb); | 1511 | unix_get_secdata(&scm, skb); |
1515 | 1512 | ||
1516 | skb_put(skb, len - data_len); | 1513 | skb_put(skb, len - data_len); |
1517 | skb->data_len = data_len; | 1514 | skb->data_len = data_len; |
@@ -1606,7 +1603,7 @@ restart: | |||
1606 | unix_state_unlock(other); | 1603 | unix_state_unlock(other); |
1607 | other->sk_data_ready(other); | 1604 | other->sk_data_ready(other); |
1608 | sock_put(other); | 1605 | sock_put(other); |
1609 | scm_destroy(siocb->scm); | 1606 | scm_destroy(&scm); |
1610 | return len; | 1607 | return len; |
1611 | 1608 | ||
1612 | out_unlock: | 1609 | out_unlock: |
@@ -1616,7 +1613,7 @@ out_free: | |||
1616 | out: | 1613 | out: |
1617 | if (other) | 1614 | if (other) |
1618 | sock_put(other); | 1615 | sock_put(other); |
1619 | scm_destroy(siocb->scm); | 1616 | scm_destroy(&scm); |
1620 | return err; | 1617 | return err; |
1621 | } | 1618 | } |
1622 | 1619 | ||
@@ -1628,21 +1625,18 @@ out: | |||
1628 | static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | 1625 | static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, |
1629 | struct msghdr *msg, size_t len) | 1626 | struct msghdr *msg, size_t len) |
1630 | { | 1627 | { |
1631 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); | ||
1632 | struct sock *sk = sock->sk; | 1628 | struct sock *sk = sock->sk; |
1633 | struct sock *other = NULL; | 1629 | struct sock *other = NULL; |
1634 | int err, size; | 1630 | int err, size; |
1635 | struct sk_buff *skb; | 1631 | struct sk_buff *skb; |
1636 | int sent = 0; | 1632 | int sent = 0; |
1637 | struct scm_cookie tmp_scm; | 1633 | struct scm_cookie scm; |
1638 | bool fds_sent = false; | 1634 | bool fds_sent = false; |
1639 | int max_level; | 1635 | int max_level; |
1640 | int data_len; | 1636 | int data_len; |
1641 | 1637 | ||
1642 | if (NULL == siocb->scm) | ||
1643 | siocb->scm = &tmp_scm; | ||
1644 | wait_for_unix_gc(); | 1638 | wait_for_unix_gc(); |
1645 | err = scm_send(sock, msg, siocb->scm, false); | 1639 | err = scm_send(sock, msg, &scm, false); |
1646 | if (err < 0) | 1640 | if (err < 0) |
1647 | return err; | 1641 | return err; |
1648 | 1642 | ||
@@ -1683,7 +1677,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1683 | goto out_err; | 1677 | goto out_err; |
1684 | 1678 | ||
1685 | /* Only send the fds in the first buffer */ | 1679 | /* Only send the fds in the first buffer */ |
1686 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); | 1680 | err = unix_scm_to_skb(&scm, skb, !fds_sent); |
1687 | if (err < 0) { | 1681 | if (err < 0) { |
1688 | kfree_skb(skb); | 1682 | kfree_skb(skb); |
1689 | goto out_err; | 1683 | goto out_err; |
@@ -1715,8 +1709,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1715 | sent += size; | 1709 | sent += size; |
1716 | } | 1710 | } |
1717 | 1711 | ||
1718 | scm_destroy(siocb->scm); | 1712 | scm_destroy(&scm); |
1719 | siocb->scm = NULL; | ||
1720 | 1713 | ||
1721 | return sent; | 1714 | return sent; |
1722 | 1715 | ||
@@ -1728,8 +1721,7 @@ pipe_err: | |||
1728 | send_sig(SIGPIPE, current, 0); | 1721 | send_sig(SIGPIPE, current, 0); |
1729 | err = -EPIPE; | 1722 | err = -EPIPE; |
1730 | out_err: | 1723 | out_err: |
1731 | scm_destroy(siocb->scm); | 1724 | scm_destroy(&scm); |
1732 | siocb->scm = NULL; | ||
1733 | return sent ? : err; | 1725 | return sent ? : err; |
1734 | } | 1726 | } |
1735 | 1727 | ||
@@ -1778,8 +1770,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1778 | struct msghdr *msg, size_t size, | 1770 | struct msghdr *msg, size_t size, |
1779 | int flags) | 1771 | int flags) |
1780 | { | 1772 | { |
1781 | struct sock_iocb *siocb = kiocb_to_siocb(iocb); | 1773 | struct scm_cookie scm; |
1782 | struct scm_cookie tmp_scm; | ||
1783 | struct sock *sk = sock->sk; | 1774 | struct sock *sk = sock->sk; |
1784 | struct unix_sock *u = unix_sk(sk); | 1775 | struct unix_sock *u = unix_sk(sk); |
1785 | int noblock = flags & MSG_DONTWAIT; | 1776 | int noblock = flags & MSG_DONTWAIT; |
@@ -1831,16 +1822,14 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1831 | if (sock_flag(sk, SOCK_RCVTSTAMP)) | 1822 | if (sock_flag(sk, SOCK_RCVTSTAMP)) |
1832 | __sock_recv_timestamp(msg, sk, skb); | 1823 | __sock_recv_timestamp(msg, sk, skb); |
1833 | 1824 | ||
1834 | if (!siocb->scm) { | 1825 | memset(&scm, 0, sizeof(scm)); |
1835 | siocb->scm = &tmp_scm; | 1826 | |
1836 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | 1827 | scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); |
1837 | } | 1828 | unix_set_secdata(&scm, skb); |
1838 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); | ||
1839 | unix_set_secdata(siocb->scm, skb); | ||
1840 | 1829 | ||
1841 | if (!(flags & MSG_PEEK)) { | 1830 | if (!(flags & MSG_PEEK)) { |
1842 | if (UNIXCB(skb).fp) | 1831 | if (UNIXCB(skb).fp) |
1843 | unix_detach_fds(siocb->scm, skb); | 1832 | unix_detach_fds(&scm, skb); |
1844 | 1833 | ||
1845 | sk_peek_offset_bwd(sk, skb->len); | 1834 | sk_peek_offset_bwd(sk, skb->len); |
1846 | } else { | 1835 | } else { |
@@ -1860,11 +1849,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1860 | sk_peek_offset_fwd(sk, size); | 1849 | sk_peek_offset_fwd(sk, size); |
1861 | 1850 | ||
1862 | if (UNIXCB(skb).fp) | 1851 | if (UNIXCB(skb).fp) |
1863 | siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); | 1852 | scm.fp = scm_fp_dup(UNIXCB(skb).fp); |
1864 | } | 1853 | } |
1865 | err = (flags & MSG_TRUNC) ? skb->len - skip : size; | 1854 | err = (flags & MSG_TRUNC) ? skb->len - skip : size; |
1866 | 1855 | ||
1867 | scm_recv(sock, msg, siocb->scm, flags); | 1856 | scm_recv(sock, msg, &scm, flags); |
1868 | 1857 | ||
1869 | out_free: | 1858 | out_free: |
1870 | skb_free_datagram(sk, skb); | 1859 | skb_free_datagram(sk, skb); |
@@ -1915,8 +1904,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1915 | struct msghdr *msg, size_t size, | 1904 | struct msghdr *msg, size_t size, |
1916 | int flags) | 1905 | int flags) |
1917 | { | 1906 | { |
1918 | struct sock_iocb *siocb = kiocb_to_siocb(iocb); | 1907 | struct scm_cookie scm; |
1919 | struct scm_cookie tmp_scm; | ||
1920 | struct sock *sk = sock->sk; | 1908 | struct sock *sk = sock->sk; |
1921 | struct unix_sock *u = unix_sk(sk); | 1909 | struct unix_sock *u = unix_sk(sk); |
1922 | DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name); | 1910 | DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name); |
@@ -1943,10 +1931,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1943 | * while sleeps in memcpy_tomsg | 1931 | * while sleeps in memcpy_tomsg |
1944 | */ | 1932 | */ |
1945 | 1933 | ||
1946 | if (!siocb->scm) { | 1934 | memset(&scm, 0, sizeof(scm)); |
1947 | siocb->scm = &tmp_scm; | ||
1948 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | ||
1949 | } | ||
1950 | 1935 | ||
1951 | err = mutex_lock_interruptible(&u->readlock); | 1936 | err = mutex_lock_interruptible(&u->readlock); |
1952 | if (unlikely(err)) { | 1937 | if (unlikely(err)) { |
@@ -2012,13 +1997,13 @@ again: | |||
2012 | 1997 | ||
2013 | if (check_creds) { | 1998 | if (check_creds) { |
2014 | /* Never glue messages from different writers */ | 1999 | /* Never glue messages from different writers */ |
2015 | if ((UNIXCB(skb).pid != siocb->scm->pid) || | 2000 | if ((UNIXCB(skb).pid != scm.pid) || |
2016 | !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) || | 2001 | !uid_eq(UNIXCB(skb).uid, scm.creds.uid) || |
2017 | !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid)) | 2002 | !gid_eq(UNIXCB(skb).gid, scm.creds.gid)) |
2018 | break; | 2003 | break; |
2019 | } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { | 2004 | } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { |
2020 | /* Copy credentials */ | 2005 | /* Copy credentials */ |
2021 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); | 2006 | scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); |
2022 | check_creds = 1; | 2007 | check_creds = 1; |
2023 | } | 2008 | } |
2024 | 2009 | ||
@@ -2045,7 +2030,7 @@ again: | |||
2045 | sk_peek_offset_bwd(sk, chunk); | 2030 | sk_peek_offset_bwd(sk, chunk); |
2046 | 2031 | ||
2047 | if (UNIXCB(skb).fp) | 2032 | if (UNIXCB(skb).fp) |
2048 | unix_detach_fds(siocb->scm, skb); | 2033 | unix_detach_fds(&scm, skb); |
2049 | 2034 | ||
2050 | if (unix_skb_len(skb)) | 2035 | if (unix_skb_len(skb)) |
2051 | break; | 2036 | break; |
@@ -2053,13 +2038,13 @@ again: | |||
2053 | skb_unlink(skb, &sk->sk_receive_queue); | 2038 | skb_unlink(skb, &sk->sk_receive_queue); |
2054 | consume_skb(skb); | 2039 | consume_skb(skb); |
2055 | 2040 | ||
2056 | if (siocb->scm->fp) | 2041 | if (scm.fp) |
2057 | break; | 2042 | break; |
2058 | } else { | 2043 | } else { |
2059 | /* It is questionable, see note in unix_dgram_recvmsg. | 2044 | /* It is questionable, see note in unix_dgram_recvmsg. |
2060 | */ | 2045 | */ |
2061 | if (UNIXCB(skb).fp) | 2046 | if (UNIXCB(skb).fp) |
2062 | siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); | 2047 | scm.fp = scm_fp_dup(UNIXCB(skb).fp); |
2063 | 2048 | ||
2064 | sk_peek_offset_fwd(sk, chunk); | 2049 | sk_peek_offset_fwd(sk, chunk); |
2065 | 2050 | ||
@@ -2068,7 +2053,7 @@ again: | |||
2068 | } while (size); | 2053 | } while (size); |
2069 | 2054 | ||
2070 | mutex_unlock(&u->readlock); | 2055 | mutex_unlock(&u->readlock); |
2071 | scm_recv(sock, msg, siocb->scm, flags); | 2056 | scm_recv(sock, msg, &scm, flags); |
2072 | out: | 2057 | out: |
2073 | return copied ? : err; | 2058 | return copied ? : err; |
2074 | } | 2059 | } |