net: Fix recvmmsg timeout handling
Subsystems (30)
PATCH 1/1 net: Fix recvmmsg timeout handling
Hi David,
Trying to get this merged, finally. I has whas has been
discussed so far and agreed wrt the timeout handling.
There is a separate issues related to possibly delivering errors to
threads that haven't caused them, for that I'll send a separate patch in a minute.
Michael et al, if you guys could please take a last look at
this, lets try to get this finally merged :-)
- Arnaldo
Quoted 1 line
From
f58e6ca36075f0c0b48933e2e1fe59dec74cf6d7Mon Sep 17 00:00:00 2001
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Fri, 18 Jul 2014 15:23:44 -0300
Subject: [PATCH 1/2] net: Fix recvmmsg timeout handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As reported by Elie de Brauwer the timeout handling in the recvmmsg syscall had issues that boil down to it not properly passing the remaining time to each underlying recvmsg() call.
Fix it by adding a timeout pointer to the recvmsg implementations, so that it can use that using a variation of sock_rcvtimeo, that overrides the value in SO_RCVTIMEO with the timeout passed, and returns the remaining time in that pointer, this way each underlying recvmsg call receives the remaining time.
It ends up in most cases being just a forward of this pointer from recvmmsg to skb_recv_datagram().
--- crypto/algif_hash.c | 2 +- crypto/algif_skcipher.c | 2 +- drivers/isdn/mISDN/socket.c | 4 +- drivers/net/macvtap.c | 2 +- drivers/net/ppp/pppoe.c | 4 +- drivers/net/tun.c | 4 +- drivers/vhost/net.c | 4 +- include/linux/net.h | 7 +++- include/linux/skbuff.h | 4 +- include/net/af_vsock.h | 2 +- include/net/bluetooth/bluetooth.h | 4 +- include/net/inet_common.h | 2 +- include/net/ping.h | 2 +- include/net/sctp/sctp.h | 2 +- include/net/sock.h | 11 +++-- include/net/tcp.h | 2 +- net/appletalk/ddp.c | 4 +- net/atm/common.c | 4 +- net/atm/common.h | 2 +- net/ax25/af_ax25.c | 4 +- net/bluetooth/af_bluetooth.c | 10 +++-- net/bluetooth/hci_sock.c | 4 +- net/bluetooth/l2cap_sock.c | 6 +-- net/bluetooth/rfcomm/sock.c | 4 +- net/bluetooth/sco.c | 4 +- net/caif/caif_socket.c | 10 +++-- net/can/bcm.c | 4 +- net/can/raw.c | 4 +- net/core/datagram.c | 19 ++++++--- net/core/sock.c | 6 +-- net/dccp/dccp.h | 2 +- net/dccp/proto.c | 6 ++- net/decnet/af_decnet.c | 7 ++-- net/ieee802154/dgram.c | 4 +- net/ieee802154/raw.c | 4 +- net/ipv4/af_inet.c | 4 +- net/ipv4/ping.c | 4 +- net/ipv4/raw.c | 4 +- net/ipv4/tcp.c | 16 ++++--- net/ipv4/udp.c | 4 +- net/ipv4/udp_impl.h | 2 +- net/ipv6/raw.c | 4 +- net/ipv6/udp.c | 4 +- net/ipv6/udp_impl.h | 2 +- net/ipx/af_ipx.c | 4 +- net/irda/af_irda.c | 16 ++++--- net/iucv/af_iucv.c | 4 +- net/key/af_key.c | 4 +- net/l2tp/l2tp_ip.c | 4 +- net/l2tp/l2tp_ip6.c | 4 +- net/l2tp/l2tp_ppp.c | 4 +- net/llc/af_llc.c | 6 ++- net/netlink/af_netlink.c | 4 +- net/netrom/af_netrom.c | 4 +- net/nfc/llcp_sock.c | 4 +- net/nfc/rawsock.c | 4 +- net/packet/af_packet.c | 4 +- net/phonet/datagram.c | 4 +- net/phonet/pep.c | 6 +-- net/rds/rds.h | 2 +- net/rds/recv.c | 6 ++- net/rose/af_rose.c | 4 +- net/rxrpc/ar-input.c | 2 +- net/rxrpc/ar-internal.h | 2 +- net/rxrpc/ar-recvmsg.c | 21 ++++++---- net/sctp/socket.c | 18 ++++---- net/sctp/ulpevent.c | 2 +- net/socket.c | 87 +++++++++++++++++++++++++-------------- net/sunrpc/svcsock.c | 2 +- net/sunrpc/xprtsock.c | 4 +- net/tipc/socket.c | 8 ++-- net/unix/af_unix.c | 23 ++++++----- net/vmw_vsock/af_vsock.c | 10 +++-- net/vmw_vsock/vmci_transport.c | 4 +- net/x25/af_x25.c | 4 +- 75 files changed, 276 insertions(+), 209 deletions(-)
crypto/algif_hash.c +1 -1
@@ -151,7 +151,7 @@ unlock: }static int hash_recvmsg (struct kiocb *unused,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct alg_sock *ask =alg_sk (sk);
crypto/algif_skcipher.c +1 -1
@@ -419,7 +419,7 @@ unlock: }static int skcipher_recvmsg (struct kiocb *unused,struct socket *sock, -struct msghdr *msg,size_t ignored,int flags) +struct msghdr *msg,size_t ignored,int flags,long *timeop) {struct sock *sk = sock->sk;struct alg_sock *ask =alg_sk (sk);
drivers/isdn/mISDN/socket.c +2 -2
@@ -113,7 +113,7 @@ mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)static int mISDN_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sk_buff *skb;struct sock *sk = sock->sk;
@@ -130,7 +130,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (sk->sk_state ==MISDN_CLOSED )return 0 ; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);if (!skb)return err;
drivers/net/macvtap.c +1 -1
@@ -1111,7 +1111,7 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock,static int macvtap_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags) +int flags,long *timeop) { struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);int ret;
drivers/net/ppp/pppoe.c +2 -2
@@ -963,7 +963,7 @@ static const struct ppp_channel_ops pppoe_chan_ops = { };static int pppoe_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t total_len,int flags) +struct msghdr *m,size_t total_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -975,7 +975,7 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, } skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &error); + flags &MSG_DONTWAIT , &error, timeop);if (error <0 ) goto end;
drivers/net/tun.c +2 -2
@@ -1343,7 +1343,7 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,/* Read frames from queue */ skb =__skb_recv_datagram (tfile->socket.sk, noblock ?MSG_DONTWAIT :0 , - &peeked, &off, &err); + &peeked, &off, &err,NULL );if (skb) { ret =tun_put_user (tun, tfile, skb, iv, len);kfree_skb (skb);
@@ -1452,7 +1452,7 @@ static int tun_sendmsg(struct kiocb *iocb, struct socket *sock,static int tun_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags) +int flags,long *timeop) { struct tun_file *tfile = container_of(sock, struct tun_file, socket);struct tun_struct *tun =__tun_get (tfile);
drivers/vhost/net.c +2 -2
@@ -602,7 +602,7 @@ static void handle_rx(struct vhost_net *net)if (unlikely (headcount >UIO_MAXIOV )) { msg.msg_iovlen =1 ; err = sock->ops->recvmsg (NULL , sock, &msg, -1 ,MSG_DONTWAIT |MSG_TRUNC ); +1 ,MSG_DONTWAIT |MSG_TRUNC ,NULL );pr_debug ("Discarded rx packet: len %zd\n" , sock_len);continue ; }
@@ -628,7 +628,7 @@ static void handle_rx(struct vhost_net *net)copy_iovec_hdr (vq->iov, nvq->hdr, sock_hlen, in); msg.msg_iovlen = in; err = sock->ops->recvmsg (NULL , sock, &msg, - sock_len,MSG_DONTWAIT |MSG_TRUNC ); + sock_len,MSG_DONTWAIT |MSG_TRUNC ,NULL );/* Userspace might have consumed the packet meanwhile: * it's not supposed to do this usually, but might be hard * to prevent. Discard data we got (if any) and keep going. */
include/linux/net.h +5 -2
@@ -171,10 +171,13 @@ struct proto_ops {* returning uninitialized memory to user space. The recvfrom * handlers can assume that msg.msg_name is either NULL or has * a minimum size of sizeof(struct sockaddr_storage). +* timeop contains a per call timeout (as opposed as per socket, +* used by recvmmsg, set it to NULL to disable it. It should return +* the remaining time, if not NULL. */ int (*recvmsg) (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags); +int flags,long *timeop);int (*mmap) (struct file *file,struct socket *sock,struct vm_area_struct * vma); ssize_t (*sendpage) (struct socket *sock, struct page *page,
@@ -215,7 +218,7 @@ int sock_create_lite(int family, int type, int proto, struct socket **res);void sock_release (struct socket *sock);int sock_sendmsg (struct socket *sock,struct msghdr *msg,size_t len);int sock_recvmsg (struct socket *sock,struct msghdr *msg,size_t size, -int flags); +int flags,long *timeop);struct file *sock_alloc_file (struct socket *sock,int flags,const char *dname);struct socket *sockfd_lookup (int fd,int *err);struct socket *sock_from_file (struct file *file,int *err);
include/linux/skbuff.h +2 -2
@@ -2520,9 +2520,9 @@ static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag)for (iter =skb_shinfo (skb)->frag_list; iter; iter = iter->next) struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, -int *peeked,int *off,int *err); +int *peeked,int *off,int *err,long *timeop);struct sk_buff *skb_recv_datagram (struct sock *sk,unsigned flags,int noblock, -int *err); +int *err,long *timeop);unsigned int datagram_poll (struct file *file,struct socket *sock,struct poll_table_struct *wait); int skb_copy_datagram_iovec(const struct sk_buff *from, int offset,
include/net/af_vsock.h +1 -1
@@ -101,7 +101,7 @@ struct vsock_transport {/* DGRAM. */ int (*dgram_bind)(struct vsock_sock *,struct sockaddr_vm *);int (*dgram_dequeue)(struct kiocb *kiocb,struct vsock_sock *vsk, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);int (*dgram_enqueue)(struct vsock_sock *,struct sockaddr_vm *,struct iovec *,size_t len);bool (*dgram_allow)(u32 cid,u32 port);
include/net/bluetooth/bluetooth.h +2 -2
@@ -246,9 +246,9 @@ void bt_sock_unregister(int proto);void bt_sock_link (struct bt_sock_list *l,struct sock *s);void bt_sock_unlink (struct bt_sock_list *l,struct sock *s);int bt_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);int bt_sock_stream_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);uint bt_sock_poll (struct file *file,struct socket *sock,poll_table *wait);int bt_sock_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg);int bt_sock_wait_state (struct sock *sk,int state,unsigned long timeo);
include/net/inet_common.h +1 -1
@@ -26,7 +26,7 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,ssize_t inet_sendpage (struct socket *sock,struct page *page,int offset,size_t size,int flags);int inet_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags); +size_t size,int flags,long *timeop);int inet_shutdown (struct socket *sock,int how);int inet_listen (struct socket *sock,int backlog);void inet_sock_destruct (struct sock *sk);
include/net/ping.h +1 -1
@@ -76,7 +76,7 @@ int ping_getfrag(void *from, char *to, int offset, int fraglen, int odd, struct sk_buff *);int ping_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int ping_common_sendmsg (int family,struct msghdr *msg,size_t len,void *user_icmph,size_t icmph_len); int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
include/net/sctp/sctp.h +1 -1
@@ -109,7 +109,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, struct sctp_association *asoc);extern struct percpu_counter sctp_sockets_allocated;int sctp_asconf_mgmt (struct sctp_sock *,struct sctp_sockaddr_entry *); -struct sk_buff *sctp_skb_recv_datagram (struct sock *,int ,int ,int *); +struct sk_buff *sctp_skb_recv_datagram (struct sock *,int ,int ,int *,long *);/* * sctp/primitive.c
include/net/sock.h +8 -3
@@ -979,7 +979,7 @@ struct proto {int (*recvmsg)(struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock,int flags, -int *addr_len); +int *addr_len,long *timeop);int (*sendpage)(struct sock *sk,struct page *page,int offset,size_t size,int flags); int (*bind)(struct sock *sk,
@@ -1611,7 +1611,7 @@ int sock_no_getsockopt(struct socket *, int , int, char __user *, int __user *);int sock_no_setsockopt (struct socket *,int ,int ,char __user *,unsigned int );int sock_no_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );int sock_no_recvmsg (struct kiocb *,struct socket *,struct msghdr *,size_t , -int ); +int ,long *);int sock_no_mmap (struct file *file,struct socket *sock,struct vm_area_struct *vma); ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset,
@@ -1624,7 +1624,7 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset,int sock_common_getsockopt (struct socket *sock,int level,int optname,char __user *optval,int __user *optlen);int sock_common_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags); +struct msghdr *msg,size_t size,int flags,long *timeop);int sock_common_setsockopt (struct socket *sock,int level,int optname,char __user *optval,unsigned int optlen); int compat_sock_common_getsockopt(struct socket *sock, int level,
@@ -2131,6 +2131,11 @@ static inline long sock_rcvtimeo(const struct sock *sk, bool noblock)return noblock ?0 : sk->sk_rcvtimeo; } +static inline long sock_rcvtimeop (const struct sock *sk,long *timeop,bool noblock) +{ +return noblock ?0 : (timeop ? *timeop : sk->sk_rcvtimeo); +} +static inline long sock_sndtimeo (const struct sock *sk,bool noblock) {return noblock ?0 : sk->sk_sndtimeo;
include/net/tcp.h +1 -1
@@ -437,7 +437,7 @@ int compat_tcp_setsockopt(struct sock *sk, int level, int optname,void tcp_set_keepalive (struct sock *sk,int val);void tcp_syn_ack_timeout (struct sock *sk,struct request_sock *req);int tcp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len); +size_t len,int nonblock,int flags,int *addr_len,long *timeop);void tcp_parse_options (const struct sk_buff *skb,struct tcp_options_received *opt_rx,int estab,struct tcp_fastopen_cookie *foc);
net/appletalk/ddp.c +2 -2
@@ -1729,7 +1729,7 @@ out: }static int atalk_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct ddpehdr *ddp;
@@ -1739,7 +1739,7 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdrstruct sk_buff *skb; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);lock_sock (sk);if (!skb)
net/atm/common.c +2 -2
@@ -524,7 +524,7 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci) }int vcc_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct atm_vcc *vcc;
@@ -544,7 +544,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, !test_bit(ATM_VF_READY, &vcc->flags))return 0 ; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &error); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &error, timeop);if (!skb)return error;
net/atm/common.h +1 -1
@@ -14,7 +14,7 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family);int vcc_release (struct socket *sock);int vcc_connect (struct socket *sock,int itf,short vpi,int vci);int vcc_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags); +size_t size,int flags,long *timeop);int vcc_sendmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len);unsigned int vcc_poll (struct file *file,struct socket *sock,poll_table *wait);
net/ax25/af_ax25.c +2 -2
@@ -1600,7 +1600,7 @@ out: }static int ax25_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -1619,7 +1619,7 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,/* Now we can treat all alike */ skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (skb ==NULL ) goto out;
net/bluetooth/af_bluetooth.c +6 -4
@@ -209,7 +209,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)EXPORT_SYMBOL (bt_accept_dequeue);int bt_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -222,7 +222,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (flags & (MSG_OOB ))return -EOPNOTSUPP ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {if (sk->sk_shutdown &RCV_SHUTDOWN )return 0 ;
@@ -282,7 +282,7 @@ static long bt_sock_data_wait(struct sock *sk, long timeo) }int bt_sock_stream_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int err =0 ;
@@ -297,7 +297,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,lock_sock (sk); target =sock_rcvlowat (sk, flags &MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); do { struct sk_buff *skb;
@@ -381,6 +381,8 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, }while (size); out: +if (timeop) + *timeop = timeo;release_sock (sk);return copied ? : err; }
net/bluetooth/hci_sock.c +2 -2
@@ -833,7 +833,7 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, }static int hci_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -848,7 +848,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (sk->sk_state ==BT_CLOSED )return 0 ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb)return err;
net/bluetooth/l2cap_sock.c +3 -3
@@ -972,7 +972,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int l2cap_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct l2cap_pinfo *pi =l2cap_pi (sk);
@@ -999,9 +999,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (sk);if (sock->type ==SOCK_STREAM ) - err =bt_sock_stream_recvmsg (iocb, sock, msg, len, flags); + err =bt_sock_stream_recvmsg (iocb, sock, msg, len, flags, timeop);else - err =bt_sock_recvmsg (iocb, sock, msg, len, flags); + err =bt_sock_recvmsg (iocb, sock, msg, len, flags, timeop);if (pi->chan->mode !=L2CAP_MODE_ERTM )return err;
net/bluetooth/rfcomm/sock.c +2 -2
@@ -617,7 +617,7 @@ done: }static int rfcomm_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct rfcomm_dlc *d =rfcomm_pi (sk)->dlc;
@@ -628,7 +628,7 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,return 0 ; } - len =bt_sock_stream_recvmsg (iocb, sock, msg, size, flags); + len =bt_sock_stream_recvmsg (iocb, sock, msg, size, flags, timeop);lock_sock (sk);if (!(flags &MSG_PEEK ) && len >0 )
net/bluetooth/sco.c +2 -2
@@ -700,7 +700,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting) }static int sco_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sco_pinfo *pi =sco_pi (sk);
@@ -718,7 +718,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (sk); -return bt_sock_recvmsg (iocb, sock, msg, len, flags); +return bt_sock_recvmsg (iocb, sock, msg, len, flags, timeop); }static int sco_sock_setsockopt (struct socket *sock,int level,int optname,char __user *optval,unsigned int optlen)
net/caif/caif_socket.c +6 -4
@@ -272,7 +272,7 @@ static void caif_check_flow_release(struct sock *sk)* changed locking, address handling and added MSG_TRUNC. */ static int caif_seqpkt_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t len,int flags) +struct msghdr *m,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;
@@ -284,7 +284,7 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,if (m->msg_flags&MSG_OOB ) goto read_error; - skb =skb_recv_datagram (sk, flags,0 , &ret); + skb =skb_recv_datagram (sk, flags,0 , &ret, timeop);if (!skb) goto read_error; copylen = skb->len;
@@ -345,7 +345,7 @@ static long caif_stream_data_wait(struct sock *sk, long timeo)*/ static int caif_stream_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;int copied =0 ;
@@ -367,7 +367,7 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,caif_read_lock (sk); target =sock_rcvlowat (sk, flags&MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, flags&MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags&MSG_DONTWAIT ); do { int chunk;
@@ -450,6 +450,8 @@ unlock:caif_read_unlock (sk); out: +if (timeop) + *timeop = timeo;return copied ? : err; }
net/can/bcm.c +2 -2
@@ -1541,7 +1541,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, }static int bcm_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -1551,7 +1551,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock, noblock = flags &MSG_DONTWAIT ; flags &= ~MSG_DONTWAIT ; - skb =skb_recv_datagram (sk, flags, noblock, &error); + skb =skb_recv_datagram (sk, flags, noblock, &error, timeop);if (!skb)return error;
net/can/raw.c +2 -2
@@ -731,7 +731,7 @@ send_failed: }static int raw_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -741,7 +741,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, noblock = flags &MSG_DONTWAIT ; flags &= ~MSG_DONTWAIT ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb)return err;
net/core/datagram.c +13 -6
@@ -138,6 +138,9 @@ out_noerr:* @off: an offset in bytes to peek skb from. Returns an offset * within an skb where data actually starts * @err: error code returned +* @timeop: per call timeout (as opposed as per socket via SO_RCVTIMEO), +* will return the remaining time, used in recvmmsg, ignored +* if set to NULL. * * Get a datagram skbuff, understands the peeking, nonblocking wakeups * and possible races. This replaces identical code in packet, raw and
@@ -162,7 +165,7 @@ out_noerr:* the standard around please. */ struct sk_buff *__skb_recv_datagram (struct sock *sk,unsigned int flags, -int *peeked,int *off,int *err) +int *peeked,int *off,int *err,long *timeop) {struct sk_buff *skb, *last;long timeo;
@@ -174,7 +177,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,if (error) goto no_packet; - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); do { /* Again only user level code calls this function, so nothing
@@ -205,6 +208,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,spin_unlock_irqrestore (&queue->lock, cpu_flags); *off = _off; +if (timeop) + *timeop = timeo;return skb; }spin_unlock_irqrestore (&queue->lock, cpu_flags);
@@ -219,22 +224,24 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, goto no_packet; }while (!wait_for_more_packets (sk, err, &timeo, last)); - +out: +if (timeop) + *timeop = timeo;return NULL ; no_packet: *err = error; -return NULL ; + goto out; }EXPORT_SYMBOL (__skb_recv_datagram);struct sk_buff *skb_recv_datagram (struct sock *sk,unsigned int flags, -int noblock,int *err) +int noblock,int *err,long *timeop) {int peeked, off =0 ;return __skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, err); + &peeked, &off, err, timeop); }EXPORT_SYMBOL (skb_recv_datagram);
net/core/sock.c +3 -3
@@ -2191,7 +2191,7 @@ int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,EXPORT_SYMBOL (sock_no_sendmsg);int sock_no_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m, -size_t len,int flags) +size_t len,int flags,long *timeop) {return -EOPNOTSUPP ; }
@@ -2577,14 +2577,14 @@ EXPORT_SYMBOL(compat_sock_common_getsockopt);#endif int sock_common_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int addr_len =0 ;int err; err = sk->sk_prot->recvmsg (iocb, sk, msg, size, flags &MSG_DONTWAIT , - flags & ~MSG_DONTWAIT , &addr_len); + flags & ~MSG_DONTWAIT , &addr_len, timeop);if (err >=0 ) msg->msg_namelen = addr_len;return err;
net/dccp/dccp.h +1 -1
@@ -314,7 +314,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size);int dccp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int nonblock,int flags, -int *addr_len); +int *addr_len,long *timeop);void dccp_shutdown (struct sock *sk,int how);int inet_dccp_listen (struct socket *sock,int backlog); unsigned int dccp_poll(struct file *file, struct socket *sock,
net/dccp/proto.c +4 -2
@@ -808,7 +808,7 @@ out_discard:EXPORT_SYMBOL_GPL (dccp_sendmsg);int dccp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len) +size_t len,int nonblock,int flags,int *addr_len,long *timeop) {const struct dccp_hdr *dh;long timeo;
@@ -820,7 +820,7 @@ int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out; } - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock); do { struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
@@ -910,6 +910,8 @@ verify_sock_status: }while (1 ); out:release_sock (sk); +if (timeop) + *timeop = timeo;return len; }
net/decnet/af_decnet.c +4 -3
@@ -1669,7 +1669,7 @@ static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, intstatic int dn_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct dn_scp *scp =DN_SK (sk);
@@ -1680,7 +1680,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,struct sk_buff *skb, *n;struct dn_skb_cb *cb =NULL ;unsigned char eor =0 ; -long timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); +long timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT );lock_sock (sk);
@@ -1814,7 +1814,8 @@ out: }release_sock (sk); - +if (timeop) + *timeop = timeo;return rv; }
net/ieee802154/dgram.c +2 -2
@@ -306,14 +306,14 @@ out:static int dgram_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {size_t copied =0 ;int err = -EOPNOTSUPP ;struct sk_buff *skb; DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ieee802154/raw.c +2 -2
@@ -179,13 +179,13 @@ out: }static int raw_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {size_t copied =0 ;int err = -EOPNOTSUPP ;struct sk_buff *skb; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ipv4/af_inet.c +2 -2
@@ -757,7 +757,7 @@ ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,EXPORT_SYMBOL (inet_sendpage);int inet_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int addr_len =0 ;
@@ -766,7 +766,7 @@ int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,sock_rps_record_flow (sk); err = sk->sk_prot->recvmsg (iocb, sk, msg, size, flags &MSG_DONTWAIT , - flags & ~MSG_DONTWAIT , &addr_len); + flags & ~MSG_DONTWAIT , &addr_len, timeop);if (err >=0 ) msg->msg_namelen = addr_len;return err;
net/ipv4/ping.c +2 -2
@@ -840,7 +840,7 @@ do_confirm: }int ping_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *isk =inet_sk (sk);int family = sk->sk_family;
@@ -864,7 +864,7 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ipv4/raw.c +2 -2
@@ -689,7 +689,7 @@ out: return ret;*/ static int raw_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk);size_t copied =0 ;
@@ -705,7 +705,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out; } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ipv4/tcp.c +7 -9
@@ -1602,7 +1602,7 @@ EXPORT_SYMBOL(tcp_read_sock);*/ int tcp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len) +size_t len,int nonblock,int flags,int *addr_len,long *timeop) {struct tcp_sock *tp =tcp_sk (sk);int copied =0 ;
@@ -1627,7 +1627,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,if (sk->sk_state ==TCP_LISTEN ) goto out; - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock);/* Urgent data needs to be handled specially. */ if (flags &MSG_OOB )
@@ -1994,20 +1994,18 @@ skip_copy:/* Clean up data we have read: This will do ACK frames. */ tcp_cleanup_rbuf (sk, copied); - -release_sock (sk); -return copied; - out:release_sock (sk); -return err; +if (timeop) + *timeop = timeo; +return copied; recv_urg: - err =tcp_recv_urg (sk, msg, len, flags); + copied =tcp_recv_urg (sk, msg, len, flags); goto out; recv_sndq: - err =tcp_peek_sndq (sk, msg, len); + copied =tcp_peek_sndq (sk, msg, len); goto out; }EXPORT_SYMBOL (tcp_recvmsg);
net/ipv4/udp.c +2 -2
@@ -1241,7 +1241,7 @@ EXPORT_SYMBOL(udp_ioctl);*/ int udp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk); DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
@@ -1257,7 +1257,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, try_again: skb =__skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, &err); + &peeked, &off, &err, timeop);if (!skb) goto out;
net/ipv4/udp_impl.h +1 -1
@@ -22,7 +22,7 @@ int compat_udp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);#endif int udp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int udp_sendpage (struct sock *sk,struct page *page,int offset,size_t size,int flags);int udp_queue_rcv_skb (struct sock *sk,struct sk_buff *skb);
net/ipv6/raw.c +2 -2
@@ -458,7 +458,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)static int rawv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len, -int noblock,int flags,int *addr_len) +int noblock,int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk); DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
@@ -475,7 +475,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,if (np->rxpmtu && np->rxopt.bits.rxpmtu)return ipv6_recv_rxpmtu (sk, msg, len, addr_len); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ipv6/udp.c +2 -2
@@ -379,7 +379,7 @@ EXPORT_SYMBOL_GPL(udp6_lib_lookup);int udpv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len, -int noblock,int flags,int *addr_len) +int noblock,int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk);struct inet_sock *inet =inet_sk (sk);
@@ -399,7 +399,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, try_again: skb =__skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, &err); + &peeked, &off, &err, timeop);if (!skb) goto out;
net/ipv6/udp_impl.h +1 -1
@@ -26,7 +26,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,int udpv6_sendmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len);int udpv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int udpv6_queue_rcv_skb (struct sock *sk,struct sk_buff *skb);void udpv6_destroy_sock (struct sock *sk);
net/ipx/af_ipx.c +2 -2
@@ -1756,7 +1756,7 @@ out:static int ipx_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct ipx_sock *ipxs =ipx_sk (sk);
@@ -1791,7 +1791,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &rc); + flags &MSG_DONTWAIT , &rc, timeop);if (!skb) {if (rc == -EAGAIN && (sk->sk_shutdown &RCV_SHUTDOWN )) rc =0 ;
net/irda/af_irda.c +10 -6
@@ -1372,7 +1372,7 @@ out:* after being read, regardless of how much the user actually read */ static int irda_recvmsg_dgram (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct irda_sock *self =irda_sk (sk);
@@ -1383,7 +1383,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,IRDA_DEBUG (4 ,"%s()\n" , __func__); skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (!skb)return err;
@@ -1421,7 +1421,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,* Function irda_recvmsg_stream (iocb, sock, msg, size, flags) */ static int irda_recvmsg_stream (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct irda_sock *self =irda_sk (sk);
@@ -1444,7 +1444,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, err =0 ; target =sock_rcvlowat (sk, flags &MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, noblock); + timeo =sock_rcvtimeop (sk, timeop, noblock); do { int chunk;
@@ -1479,8 +1479,10 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,finish_wait (sk_sleep (sk), &wait); -if (err) -return err; +if (err) { + copied = err; +break ; + }if (sk->sk_shutdown &RCV_SHUTDOWN )break ;
@@ -1533,6 +1535,8 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, } } +if (timeop) + *timeop = timeo;return copied; }
net/iucv/af_iucv.c +2 -2
@@ -1320,7 +1320,7 @@ static void iucv_process_message_q(struct sock *sk) }static int iucv_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -1341,7 +1341,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,/* receive/dequeue next skb: * the function understands MSG_PEEK and, thus, does not dequeue skb */ - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {if (sk->sk_shutdown &RCV_SHUTDOWN )return 0 ;
net/key/af_key.c +2 -2
@@ -3632,7 +3632,7 @@ out:static int pfkey_recvmsg (struct kiocb *kiocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;struct pfkey_sock *pfk =pfkey_sk (sk);
@@ -3643,7 +3643,7 @@ static int pfkey_recvmsg(struct kiocb *kiocb,if (flags & ~(MSG_PEEK |MSG_DONTWAIT |MSG_TRUNC |MSG_CMSG_COMPAT )) goto out; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);if (skb ==NULL ) goto out;
net/l2tp/l2tp_ip.c +2 -2
@@ -507,7 +507,7 @@ no_route: }static int l2tp_ip_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk);size_t copied =0 ;
@@ -518,7 +518,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *mif (flags &MSG_OOB ) goto out; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/l2tp/l2tp_ip6.c +2 -2
@@ -645,7 +645,7 @@ do_confirm:static int l2tp_ip6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk); DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);
@@ -662,7 +662,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,if (flags &MSG_ERRQUEUE )return ipv6_recv_error (sk, msg, len, addr_len); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/l2tp/l2tp_ppp.c +2 -2
@@ -187,7 +187,7 @@ static int pppol2tp_recv_payload_hook(struct sk_buff *skb)*/ static int pppol2tp_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {int err;struct sk_buff *skb;
@@ -199,7 +199,7 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, err =0 ; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (!skb) goto end;
net/llc/af_llc.c +4 -2
@@ -705,7 +705,7 @@ out:* Returns non-negative upon success, negative otherwise. */ static int llc_ui_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) { DECLARE_SOCKADDR(struct sockaddr_llc *, uaddr, msg->msg_name);const int nonblock = flags &MSG_DONTWAIT ;
@@ -725,7 +725,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,if (unlikely (sk->sk_type ==SOCK_STREAM && sk->sk_state ==TCP_LISTEN )) goto out; - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock); seq = &llc->copied_seq;if (flags &MSG_PEEK ) {
@@ -851,6 +851,8 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, out:release_sock (sk); +if (timeop) + *timeop = timeo;return copied; copy_uaddr:if (uaddr !=NULL && skb !=NULL ) {
net/netlink/af_netlink.c +2 -2
@@ -2399,7 +2399,7 @@ out:static int netlink_recvmsg (struct kiocb *kiocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (kiocb);struct scm_cookie scm;
@@ -2415,7 +2415,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, copied =0 ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (skb ==NULL ) goto out;
net/netrom/af_netrom.c +2 -2
@@ -1134,7 +1134,7 @@ out: }static int nr_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk; DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);
@@ -1154,7 +1154,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, }/* Now we can treat all alike */ -if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er)) ==NULL ) { +if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er, timeop)) ==NULL ) {release_sock (sk);return er; }
net/nfc/llcp_sock.c +2 -2
@@ -794,7 +794,7 @@ static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int llcp_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -817,7 +817,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (flags & (MSG_OOB ))return -EOPNOTSUPP ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {pr_err ("Recv datagram failed state %d %d %d" , sk->sk_state, err,sock_error (sk));
net/nfc/rawsock.c +2 -2
@@ -249,7 +249,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int rawsock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -259,7 +259,7 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,pr_debug ("sock=%p sk=%p len=%zu flags=%d\n" , sock, sk, len, flags); - skb =skb_recv_datagram (sk, flags, noblock, &rc); + skb =skb_recv_datagram (sk, flags, noblock, &rc, timeop);if (!skb)return rc;
net/packet/af_packet.c +2 -2
@@ -2852,7 +2852,7 @@ out:*/ static int packet_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -2884,7 +2884,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,* but then it will block. */ - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);/* * An error occurred so return it. Because skb_recv_datagram()
net/phonet/datagram.c +2 -2
@@ -127,7 +127,7 @@ static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,static int pn_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sk_buff *skb =NULL ;struct sockaddr_pn sa;
@@ -138,7 +138,7 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, MSG_CMSG_COMPAT)) goto out_nofree; - skb =skb_recv_datagram (sk, flags, noblock, &rval); + skb =skb_recv_datagram (sk, flags, noblock, &rval, timeop);if (skb ==NULL ) goto out_nofree;
net/phonet/pep.c +3 -3
@@ -783,7 +783,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)u8 pipe_handle, enabled, n_sb;u8 aligned =0 ; - skb =skb_recv_datagram (sk,0 , flags &O_NONBLOCK , errp); + skb =skb_recv_datagram (sk,0 , flags &O_NONBLOCK , errp,NULL );if (!skb)return NULL ;
@@ -1248,7 +1248,7 @@ struct sk_buff *pep_read(struct sock *sk)static int pep_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sk_buff *skb;int err;
@@ -1277,7 +1277,7 @@ static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,return -EINVAL ; } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);lock_sock (sk);if (skb ==NULL ) {if (err == -ENOTCONN && sk->sk_state ==TCP_CLOSE_WAIT )
net/rds/rds.h +1 -1
@@ -706,7 +706,7 @@ void rds_inc_put(struct rds_incoming *inc);void rds_recv_incoming (struct rds_connection *conn,__be32 saddr,__be32 daddr,struct rds_incoming *inc,gfp_t gfp);int rds_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int msg_flags); +size_t size,int msg_flags,long *timeop);void rds_clear_recv_queue (struct rds_sock *rs);int rds_notify_queue_get (struct rds_sock *rs,struct msghdr *msg); void rds_inc_info_copy(struct rds_incoming *inc,
net/rds/recv.c +4 -2
@@ -396,7 +396,7 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg) }int rds_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int msg_flags) +size_t size,int msg_flags,long *timeop) {struct sock *sk = sock->sk;struct rds_sock *rs =rds_sk_to_rs (sk);
@@ -406,7 +406,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,struct rds_incoming *inc =NULL ;/* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock);rdsdebug ("size %zu flags 0x%x timeo %ld\n" , size, msg_flags, timeo);
@@ -493,6 +493,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,rds_inc_put (inc); out: +if (timeop) + *timeop = timeo;return ret; }
net/rose/af_rose.c +2 -2
@@ -1212,7 +1212,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,static int rose_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct rose_sock *rose =rose_sk (sk);
@@ -1229,7 +1229,7 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,return -ENOTCONN ;/* Now we can treat all alike */ -if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er)) ==NULL ) +if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er, timeop)) ==NULL )return er; qbit = (skb->data[0 ] &ROSE_Q_BIT ) ==ROSE_Q_BIT ;
net/rxrpc/ar-input.c +1 -1
@@ -655,7 +655,7 @@ void rxrpc_data_ready(struct sock *sk)return ; } - skb =skb_recv_datagram (sk,0 ,1 , &ret); + skb =skb_recv_datagram (sk,0 ,1 , &ret,NULL );if (!skb) {rxrpc_put_local (local);if (ret == -EAGAIN )
net/rxrpc/ar-internal.h +1 -1
@@ -573,7 +573,7 @@ extern const struct file_operations rxrpc_connection_seq_fops;*/ void rxrpc_remove_user_ID (struct rxrpc_sock *,struct rxrpc_call *);int rxrpc_recvmsg (struct kiocb *,struct socket *,struct msghdr *,size_t , -int ); +int ,long *);/* * ar-security.c
net/rxrpc/ar-recvmsg.c +13 -8
@@ -44,7 +44,7 @@ void rxrpc_remove_user_ID(struct rxrpc_sock *rx, struct rxrpc_call *call)* simultaneously */ int rxrpc_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct rxrpc_skb_priv *sp;struct rxrpc_call *call =NULL , *continue_call =NULL ;
@@ -63,7 +63,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, ullen = msg->msg_flags &MSG_CMSG_COMPAT ?4 :sizeof (unsigned long ); - timeo =sock_rcvtimeo (&rx->sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (&rx->sk, timeop, flags &MSG_DONTWAIT ); msg->msg_flags |=MSG_MORE ;lock_sock (&rx->sk);
@@ -78,7 +78,8 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (&rx->sk);if (continue_call)rxrpc_put_call (continue_call); -return -ENODATA ; + copied = -ENODATA ; + goto out_copied; } }
@@ -135,7 +136,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (&rx->sk);rxrpc_put_call (continue_call);_leave (" = %d [noncont]" , copied); -return copied; + goto out_copied; } }
@@ -252,6 +253,9 @@ out:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d [data]" , copied); +out_copied: +if (timeop) + *timeop = timeo;return copied;/* handle non-DATA messages such as aborts, incoming connections and
@@ -328,7 +332,8 @@ terminal_message:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d" , ret); -return ret; + copied = ret; + goto out_copied; copy_error:_debug ("copy error" );
@@ -337,7 +342,8 @@ copy_error:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d" , ret); -return ret; + copied = ret; + goto out_copied; wait_interrupted: ret =sock_intr_errno (timeo);
@@ -348,8 +354,7 @@ wait_error:if (copied) copied = ret;_leave (" = %d [waitfail %d]" , copied, ret); -return copied; - + goto out_copied; }/**
net/sctp/socket.c +11 -7
@@ -2062,7 +2062,7 @@ static int sctp_skb_pull(struct sk_buff *skb, int len)*/ static int sctp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sctp_ulpevent *event =NULL ;struct sctp_sock *sp =sctp_sk (sk);
@@ -2082,7 +2082,7 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, goto out; } - skb =sctp_skb_recv_datagram (sk, flags, noblock, &err); + skb =sctp_skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
@@ -6741,13 +6741,13 @@ out:* with a few changes to make lksctp work. */ struct sk_buff *sctp_skb_recv_datagram (struct sock *sk,int flags, -int noblock,int *err) +int noblock,int *err,long *timeop) {int error;struct sk_buff *skb;long timeo; - timeo =sock_rcvtimeo (sk, noblock); + timeo =sock_rcvtimeop (sk, timeop, noblock);pr_debug ("%s: timeo:%ld, max:%ld\n" , __func__, timeo,MAX_SCHEDULE_TIMEOUT );
@@ -6771,7 +6771,7 @@ struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, }if (skb) -return skb; +break ;/* Caller is allowed not to check sk->sk_err before calling. */ error =sock_error (sk);
@@ -6791,11 +6791,15 @@ struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, goto no_packet; }while (sctp_wait_for_packet (sk, err, &timeo) ==0 ); -return NULL ; +out: +if (timeop) + *timeop = timeo; + +return skb; no_packet: *err = error; -return NULL ; + goto out; }/* If sndbuf has changed, wake up per association sndbuf waiters. */
net/sctp/ulpevent.c +1 -1
@@ -940,7 +940,7 @@ void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event,struct sk_buff *skb;int err; - skb =sctp_skb_recv_datagram (sk,MSG_PEEK ,1 , &err); + skb =sctp_skb_recv_datagram (sk,MSG_PEEK ,1 , &err,NULL );if (skb !=NULL ) {__sctp_ulpevent_read_nxtinfo (sctp_skb2event (skb), msghdr, skb);
net/socket.c +56 -31
200 lines not on this page · raw message
net/sunrpc/svcsock.c +1 -1
@@ -551,7 +551,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) err =kernel_recvmsg (svsk->sk_sock, &msg,NULL ,0 ,0 ,MSG_PEEK |MSG_DONTWAIT );if (err >=0 ) - skb =skb_recv_datagram (svsk->sk_sk,0 ,1 , &err); + skb =skb_recv_datagram (svsk->sk_sk,0 ,1 , &err,NULL );if (skb ==NULL ) {if (err != -EAGAIN ) {
net/sunrpc/xprtsock.c +2 -2
@@ -965,7 +965,7 @@ static void xs_local_data_ready(struct sock *sk)if (xprt ==NULL ) goto out; - skb =skb_recv_datagram (sk,0 ,1 , &err); + skb =skb_recv_datagram (sk,0 ,1 , &err,NULL );if (skb ==NULL ) goto out;
@@ -1027,7 +1027,7 @@ static void xs_udp_data_ready(struct sock *sk)if (!(xprt =xprt_from_sock (sk))) goto out; -if ((skb =skb_recv_datagram (sk,0 ,1 , &err)) ==NULL ) +if ((skb =skb_recv_datagram (sk,0 ,1 , &err,NULL )) ==NULL ) goto out; repsize = skb->len -sizeof (struct udphdr );
net/tipc/socket.c +5 -3
@@ -1150,7 +1150,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)* Returns size of returned message data, errno otherwise */ static int tipc_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t buf_len,int flags) +struct msghdr *m,size_t buf_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct tipc_sock *tsk =tipc_sk (sk);
@@ -1173,7 +1173,7 @@ static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock, goto exit; } - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); restart:/* Look for a message in receive queue; wait if necessary */
@@ -1230,6 +1230,8 @@ restart:advance_rx_queue (sk); } exit: +if (timeop) + *timeop = timeo;release_sock (sk);return res; }
@@ -1247,7 +1249,7 @@ exit:* Returns size of returned message data, errno otherwise */ static int tipc_recv_stream (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t buf_len,int flags) +struct msghdr *m,size_t buf_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct tipc_sock *tsk =tipc_sk (sk);
net/unix/af_unix.c +12 -11
@@ -519,17 +519,17 @@ static int unix_shutdown(struct socket *, int);static int unix_stream_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_stream_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_dgram_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_dgram_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_dgram_connect (struct socket *,struct sockaddr *,int ,int );static int unix_seqpacket_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_seqpacket_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_set_peek_off (struct sock *sk,int val) {
@@ -1283,7 +1283,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)* so that no locks are necessary. */ - skb =skb_recv_datagram (sk,0 , flags&O_NONBLOCK , &err); + skb =skb_recv_datagram (sk,0 , flags&O_NONBLOCK , &err,NULL );if (!skb) {/* This means receive shutdown. */ if (err ==0 )
@@ -1755,14 +1755,14 @@ static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock,static int unix_seqpacket_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;if (sk->sk_state !=TCP_ESTABLISHED )return -ENOTCONN ; -return unix_dgram_recvmsg (iocb, sock, msg, size, flags); +return unix_dgram_recvmsg (iocb, sock, msg, size, flags, timeop); }static void unix_copy_addr (struct msghdr *msg,struct sock *sk)
@@ -1777,7 +1777,7 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)static int unix_dgram_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (iocb);struct scm_cookie tmp_scm;
@@ -1803,7 +1803,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, skip =sk_peek_offset (sk, flags); - skb =__skb_recv_datagram (sk, flags, &peeked, &skip, &err); + skb =__skb_recv_datagram (sk, flags, &peeked, &skip, &err, timeop);if (!skb) {unix_state_lock (sk);/* Signal EOF on disconnected non-blocking SEQPACKET socket. */
@@ -1914,7 +1914,7 @@ static unsigned int unix_skb_len(const struct sk_buff *skb)static int unix_stream_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (iocb);struct scm_cookie tmp_scm;
@@ -1926,7 +1926,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,int check_creds =0 ;int target;int err =0 ; -long timeo; +long timeo =sock_rcvtimeop (sk, timeop, noblock);int skip; err = -EINVAL ;
@@ -1938,7 +1938,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; target =sock_rcvlowat (sk, flags&MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, noblock);/* Lock the socket to prevent queue disordering * while sleeps in memcpy_tomsg
@@ -2071,6 +2070,8 @@ again:mutex_unlock (&u->readlock);scm_recv (sock, msg, siocb->scm, flags); out: +if (timeop) + *timeop = timeo;return copied ? : err; }
net/vmw_vsock/af_vsock.c +6 -4
@@ -1063,10 +1063,10 @@ out: }static int vsock_dgram_recvmsg (struct kiocb *kiocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {return transport->dgram_dequeue (kiocb,vsock_sk (sock->sk), msg, len, - flags); + flags, timeop); }static const struct proto_ops vsock_dgram_ops = {
@@ -1646,7 +1646,7 @@ out:static int vsock_stream_recvmsg (struct kiocb *kiocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk;struct vsock_sock *vsk;
@@ -1661,6 +1661,7 @@ vsock_stream_recvmsg(struct kiocb *kiocb, sk = sock->sk; vsk =vsock_sk (sk); err =0 ; + timeout =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT );lock_sock (sk);
@@ -1711,7 +1712,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb, err = -ENOMEM ; goto out; } - timeout =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); copied =0 ; err = transport->notify_recv_init (vsk, target, &recv_data);
@@ -1821,6 +1821,8 @@ vsock_stream_recvmsg(struct kiocb *kiocb, out_wait:finish_wait (sk_sleep (sk), &wait); out: +if (timeop) + *timeop = timeout;release_sock (sk);return err; }
net/vmw_vsock/vmci_transport.c +2 -2
@@ -1733,7 +1733,7 @@ static int vmci_transport_dgram_enqueue(static int vmci_transport_dgram_dequeue (struct kiocb *kiocb,struct vsock_sock *vsk,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {int err;int noblock;
@@ -1748,7 +1748,7 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,/* Retrieve the head sk_buff from the socket's receive queue. */ err =0 ; - skb =skb_recv_datagram (&vsk->sk, flags, noblock, &err); + skb =skb_recv_datagram (&vsk->sk, flags, noblock, &err, timeop);if (err)return err;
net/x25/af_x25.c +2 -2
@@ -1254,7 +1254,7 @@ out_kfree_skb:static int x25_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;struct x25_sock *x25 =x25_sk (sk);
@@ -1306,7 +1306,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,/* Now we can treat all alike */ release_sock (sk); skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &rc); + flags &MSG_DONTWAIT , &rc, timeop);lock_sock (sk);if (!skb) goto out;
Signature · 1 line
1.9.3
FWIW, fine by me.
Signature · 2 lines
Rémi Denis-Courmont http://www.remlab.net/
Arnaldo Carvalho de Melo
Acked-by Rémi Denis-CourmontEm Mon, Jul 21, 2014 at 10:26:45PM +0300, Rémi Denis-Courmont escreveu:
Quoted 1 line
FWIW, fine by me.
Ok, and it is worth something, yes, can we make it a:
That is the way to have what you just said registered in the patch itself, ok?
If so, David, can you slap that there, please?
- Arnaldo
David Miller
maintainerFrom: Arnaldo Carvalho de Melo <[email protected]>
Date: Mon, 21 Jul 2014 16:21:31 -0300
Quoted 2 lines
Trying to get this merged, finally. I has whas has been
discussed so far and agreed wrt the timeout handling.
This gets lots of rejects against the current 'net' tree.
Please respin and integrate Remi's Acked-by, thanks.
Quoted 10 lines · David Miller
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Mon, 21 Jul 2014 16:21:31 -0300Quoted 2 lines
Trying to get this merged, finally. I has whas has been
discussed so far and agreed wrt the timeout handling.This gets lots of rejects against the current 'net' tree.
Please respin and integrate Remi's Acked-by, thanks.
+1 -- then this patch could be tested...
Cheers,
Michael
Signature · 3 lines
Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/
Em Tue, Jul 22, 2014 at 08:59:40PM +0200, Michael Kerrisk (man-pages) escreveu:
Quoted 7 lines · David Miller
Quoted 6 lines
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Mon, 21 Jul 2014 16:21:31 -0300Quoted 2 lines
Trying to get this merged, finally. I has whas has been
discussed so far and agreed wrt the timeout handling.
Quoted 6 lines
Quoted 4 lines
This gets lots of rejects against the current 'net' tree.
Please respin and integrate Remi's Acked-by, thanks.
+1 -- then this patch could be tested...
It was done on top of the net-next tree, I'm finishing a make allmodconfig to post it on top of davem/net.
- Arnaldo
PATCH 1/1 net: Fix recvmmsg timeout handling
In reply to David MillerEm Mon, Jul 21, 2014 at 08:45:38PM -0700, David Miller escreveu:
Quoted 9 lines
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Mon, 21 Jul 2014 16:21:31 -0300Quoted 2 lines
Trying to get this merged, finally. I has whas has been
discussed so far and agreed wrt the timeout handling.This gets lots of rejects against the current 'net' tree.
Please respin and integrate Remi's Acked-by, thanks.
Here it is, I think we should wait a bit till Michael (and whoever else is up to test this today) can test it, Michael?
It was done on top of:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
from early today.
- Arnaldo
commit 93d40dc3a3266d6d4ed905b9333b6809b5fe24fc
Author: Arnaldo Carvalho de Melo <[email protected]> Date: Fri Jul 18 15:23:44 2014 -0300
net: Fix recvmmsg timeout handling
As reported by Elie de Brauwer the timeout handling in the recvmmsg syscall had issues that boil down to it not properly passing the remaining time to each underlying recvmsg() call.
Fix it by adding a timeout pointer to the recvmsg implementations, so that it can use that using a variation of sock_rcvtimeo, that overrides the value in SO_RCVTIMEO with the timeout passed, and returns the remaining time in that pointer, this way each underlying recvmsg call receives the remaining time.
It ends up in most cases being just a forward of this pointer from recvmmsg to skb_recv_datagram().
crypto/algif_hash.c +1 -1
@@ -151,7 +151,7 @@ unlock: }static int hash_recvmsg (struct kiocb *unused,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct alg_sock *ask =alg_sk (sk);
crypto/algif_skcipher.c +1 -1
@@ -419,7 +419,7 @@ unlock: }static int skcipher_recvmsg (struct kiocb *unused,struct socket *sock, -struct msghdr *msg,size_t ignored,int flags) +struct msghdr *msg,size_t ignored,int flags,long *timeop) {struct sock *sk = sock->sk;struct alg_sock *ask =alg_sk (sk);
drivers/isdn/mISDN/socket.c +2 -2
@@ -113,7 +113,7 @@ mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)static int mISDN_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sk_buff *skb;struct sock *sk = sock->sk;
@@ -130,7 +130,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (sk->sk_state ==MISDN_CLOSED )return 0 ; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);if (!skb)return err;
drivers/net/macvtap.c +1 -1
@@ -1111,7 +1111,7 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock,static int macvtap_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags) +int flags,long *timeop) { struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);int ret;
drivers/net/ppp/pppoe.c +2 -2
@@ -963,7 +963,7 @@ static const struct ppp_channel_ops pppoe_chan_ops = { };static int pppoe_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t total_len,int flags) +struct msghdr *m,size_t total_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -975,7 +975,7 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, } skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &error); + flags &MSG_DONTWAIT , &error, timeop);if (error <0 ) goto end;
drivers/net/tun.c +2 -2
@@ -1343,7 +1343,7 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,/* Read frames from queue */ skb =__skb_recv_datagram (tfile->socket.sk, noblock ?MSG_DONTWAIT :0 , - &peeked, &off, &err); + &peeked, &off, &err,NULL );if (skb) { ret =tun_put_user (tun, tfile, skb, iv, len);kfree_skb (skb);
@@ -1452,7 +1452,7 @@ static int tun_sendmsg(struct kiocb *iocb, struct socket *sock,static int tun_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags) +int flags,long *timeop) { struct tun_file *tfile = container_of(sock, struct tun_file, socket);struct tun_struct *tun =__tun_get (tfile);
drivers/vhost/net.c +2 -2
@@ -602,7 +602,7 @@ static void handle_rx(struct vhost_net *net)if (unlikely (headcount >UIO_MAXIOV )) { msg.msg_iovlen =1 ; err = sock->ops->recvmsg (NULL , sock, &msg, -1 ,MSG_DONTWAIT |MSG_TRUNC ); +1 ,MSG_DONTWAIT |MSG_TRUNC ,NULL );pr_debug ("Discarded rx packet: len %zd\n" , sock_len);continue ; }
@@ -628,7 +628,7 @@ static void handle_rx(struct vhost_net *net)copy_iovec_hdr (vq->iov, nvq->hdr, sock_hlen, in); msg.msg_iovlen = in; err = sock->ops->recvmsg (NULL , sock, &msg, - sock_len,MSG_DONTWAIT |MSG_TRUNC ); + sock_len,MSG_DONTWAIT |MSG_TRUNC ,NULL );/* Userspace might have consumed the packet meanwhile: * it's not supposed to do this usually, but might be hard * to prevent. Discard data we got (if any) and keep going. */
include/linux/net.h +5 -2
@@ -171,10 +171,13 @@ struct proto_ops {* returning uninitialized memory to user space. The recvfrom * handlers can assume that msg.msg_name is either NULL or has * a minimum size of sizeof(struct sockaddr_storage). +* timeop contains a per call timeout (as opposed as per socket, +* used by recvmmsg, set it to NULL to disable it. It should return +* the remaining time, if not NULL. */ int (*recvmsg) (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags); +int flags,long *timeop);int (*mmap) (struct file *file,struct socket *sock,struct vm_area_struct * vma); ssize_t (*sendpage) (struct socket *sock, struct page *page,
@@ -215,7 +218,7 @@ int sock_create_lite(int family, int type, int proto, struct socket **res);void sock_release (struct socket *sock);int sock_sendmsg (struct socket *sock,struct msghdr *msg,size_t len);int sock_recvmsg (struct socket *sock,struct msghdr *msg,size_t size, -int flags); +int flags,long *timeop);struct file *sock_alloc_file (struct socket *sock,int flags,const char *dname);struct socket *sockfd_lookup (int fd,int *err);struct socket *sock_from_file (struct file *file,int *err);
include/linux/skbuff.h +2 -2
@@ -2513,9 +2513,9 @@ static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag)for (iter =skb_shinfo (skb)->frag_list; iter; iter = iter->next) struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, -int *peeked,int *off,int *err); +int *peeked,int *off,int *err,long *timeop);struct sk_buff *skb_recv_datagram (struct sock *sk,unsigned flags,int noblock, -int *err); +int *err,long *timeop);unsigned int datagram_poll (struct file *file,struct socket *sock,struct poll_table_struct *wait); int skb_copy_datagram_iovec(const struct sk_buff *from, int offset,
include/net/af_vsock.h +1 -1
@@ -101,7 +101,7 @@ struct vsock_transport {/* DGRAM. */ int (*dgram_bind)(struct vsock_sock *,struct sockaddr_vm *);int (*dgram_dequeue)(struct kiocb *kiocb,struct vsock_sock *vsk, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);int (*dgram_enqueue)(struct vsock_sock *,struct sockaddr_vm *,struct iovec *,size_t len);bool (*dgram_allow)(u32 cid,u32 port);
include/net/bluetooth/bluetooth.h +2 -2
@@ -246,9 +246,9 @@ void bt_sock_unregister(int proto);void bt_sock_link (struct bt_sock_list *l,struct sock *s);void bt_sock_unlink (struct bt_sock_list *l,struct sock *s);int bt_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);int bt_sock_stream_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);uint bt_sock_poll (struct file *file,struct socket *sock,poll_table *wait);int bt_sock_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg);int bt_sock_wait_state (struct sock *sk,int state,unsigned long timeo);
include/net/inet_common.h +1 -1
@@ -26,7 +26,7 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,ssize_t inet_sendpage (struct socket *sock,struct page *page,int offset,size_t size,int flags);int inet_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags); +size_t size,int flags,long *timeop);int inet_shutdown (struct socket *sock,int how);int inet_listen (struct socket *sock,int backlog);void inet_sock_destruct (struct sock *sk);
include/net/ping.h +1 -1
@@ -76,7 +76,7 @@ int ping_getfrag(void *from, char *to, int offset, int fraglen, int odd, struct sk_buff *);int ping_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int ping_common_sendmsg (int family,struct msghdr *msg,size_t len,void *user_icmph,size_t icmph_len); int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
include/net/sock.h +8 -3
@@ -961,7 +961,7 @@ struct proto {int (*recvmsg)(struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock,int flags, -int *addr_len); +int *addr_len,long *timeop);int (*sendpage)(struct sock *sk,struct page *page,int offset,size_t size,int flags); int (*bind)(struct sock *sk,
@@ -1593,7 +1593,7 @@ int sock_no_getsockopt(struct socket *, int , int, char __user *, int __user *);int sock_no_setsockopt (struct socket *,int ,int ,char __user *,unsigned int );int sock_no_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );int sock_no_recvmsg (struct kiocb *,struct socket *,struct msghdr *,size_t , -int ); +int ,long *);int sock_no_mmap (struct file *file,struct socket *sock,struct vm_area_struct *vma); ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset,
@@ -1606,7 +1606,7 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset,int sock_common_getsockopt (struct socket *sock,int level,int optname,char __user *optval,int __user *optlen);int sock_common_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags); +struct msghdr *msg,size_t size,int flags,long *timeop);int sock_common_setsockopt (struct socket *sock,int level,int optname,char __user *optval,unsigned int optlen); int compat_sock_common_getsockopt(struct socket *sock, int level,
@@ -2104,6 +2104,11 @@ static inline long sock_rcvtimeo(const struct sock *sk, bool noblock)return noblock ?0 : sk->sk_rcvtimeo; } +static inline long sock_rcvtimeop (const struct sock *sk,long *timeop,bool noblock) +{ +return noblock ?0 : (timeop ? *timeop : sk->sk_rcvtimeo); +} +static inline long sock_sndtimeo (const struct sock *sk,bool noblock) {return noblock ?0 : sk->sk_sndtimeo;
include/net/tcp.h +1 -1
@@ -437,7 +437,7 @@ int compat_tcp_setsockopt(struct sock *sk, int level, int optname,void tcp_set_keepalive (struct sock *sk,int val);void tcp_syn_ack_timeout (struct sock *sk,struct request_sock *req);int tcp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len); +size_t len,int nonblock,int flags,int *addr_len,long *timeop);void tcp_parse_options (const struct sk_buff *skb,struct tcp_options_received *opt_rx,int estab,struct tcp_fastopen_cookie *foc);
net/appletalk/ddp.c +2 -2
@@ -1729,7 +1729,7 @@ out: }static int atalk_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct ddpehdr *ddp;
@@ -1739,7 +1739,7 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdrstruct sk_buff *skb; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);lock_sock (sk);if (!skb)
net/atm/common.c +2 -2
@@ -524,7 +524,7 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci) }int vcc_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct atm_vcc *vcc;
@@ -544,7 +544,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, !test_bit(ATM_VF_READY, &vcc->flags))return 0 ; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &error); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &error, timeop);if (!skb)return error;
net/atm/common.h +1 -1
@@ -14,7 +14,7 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family);int vcc_release (struct socket *sock);int vcc_connect (struct socket *sock,int itf,short vpi,int vci);int vcc_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags); +size_t size,int flags,long *timeop);int vcc_sendmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len);unsigned int vcc_poll (struct file *file,struct socket *sock,poll_table *wait);
net/ax25/af_ax25.c +2 -2
@@ -1600,7 +1600,7 @@ out: }static int ax25_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -1619,7 +1619,7 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,/* Now we can treat all alike */ skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (skb ==NULL ) goto out;
net/bluetooth/af_bluetooth.c +6 -4
@@ -209,7 +209,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)EXPORT_SYMBOL (bt_accept_dequeue);int bt_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -222,7 +222,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (flags & (MSG_OOB ))return -EOPNOTSUPP ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {if (sk->sk_shutdown &RCV_SHUTDOWN )return 0 ;
@@ -282,7 +282,7 @@ static long bt_sock_data_wait(struct sock *sk, long timeo) }int bt_sock_stream_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int err =0 ;
@@ -297,7 +297,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,lock_sock (sk); target =sock_rcvlowat (sk, flags &MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); do { struct sk_buff *skb;
@@ -381,6 +381,8 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, }while (size); out: +if (timeop) + *timeop = timeo;release_sock (sk);return copied ? : err; }
net/bluetooth/hci_sock.c +2 -2
@@ -829,7 +829,7 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, }static int hci_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -844,7 +844,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (sk->sk_state ==BT_CLOSED )return 0 ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb)return err;
net/bluetooth/l2cap_sock.c +3 -3
@@ -971,7 +971,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int l2cap_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct l2cap_pinfo *pi =l2cap_pi (sk);
@@ -998,9 +998,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (sk);if (sock->type ==SOCK_STREAM ) - err =bt_sock_stream_recvmsg (iocb, sock, msg, len, flags); + err =bt_sock_stream_recvmsg (iocb, sock, msg, len, flags, timeop);else - err =bt_sock_recvmsg (iocb, sock, msg, len, flags); + err =bt_sock_recvmsg (iocb, sock, msg, len, flags, timeop);if (pi->chan->mode !=L2CAP_MODE_ERTM )return err;
net/bluetooth/rfcomm/sock.c +2 -2
@@ -617,7 +617,7 @@ done: }static int rfcomm_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct rfcomm_dlc *d =rfcomm_pi (sk)->dlc;
@@ -628,7 +628,7 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,return 0 ; } - len =bt_sock_stream_recvmsg (iocb, sock, msg, size, flags); + len =bt_sock_stream_recvmsg (iocb, sock, msg, size, flags, timeop);lock_sock (sk);if (!(flags &MSG_PEEK ) && len >0 )
net/bluetooth/sco.c +2 -2
@@ -700,7 +700,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting) }static int sco_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sco_pinfo *pi =sco_pi (sk);
@@ -718,7 +718,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (sk); -return bt_sock_recvmsg (iocb, sock, msg, len, flags); +return bt_sock_recvmsg (iocb, sock, msg, len, flags, timeop); }static int sco_sock_setsockopt (struct socket *sock,int level,int optname,char __user *optval,unsigned int optlen)
net/caif/caif_socket.c +6 -4
@@ -272,7 +272,7 @@ static void caif_check_flow_release(struct sock *sk)* changed locking, address handling and added MSG_TRUNC. */ static int caif_seqpkt_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t len,int flags) +struct msghdr *m,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;
@@ -284,7 +284,7 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,if (m->msg_flags&MSG_OOB ) goto read_error; - skb =skb_recv_datagram (sk, flags,0 , &ret); + skb =skb_recv_datagram (sk, flags,0 , &ret, timeop);if (!skb) goto read_error; copylen = skb->len;
@@ -345,7 +345,7 @@ static long caif_stream_data_wait(struct sock *sk, long timeo)*/ static int caif_stream_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;int copied =0 ;
@@ -367,7 +367,7 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,caif_read_lock (sk); target =sock_rcvlowat (sk, flags&MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, flags&MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags&MSG_DONTWAIT ); do { int chunk;
@@ -450,6 +450,8 @@ unlock:caif_read_unlock (sk); out: +if (timeop) + *timeop = timeo;return copied ? : err; }
net/can/bcm.c +2 -2
@@ -1541,7 +1541,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, }static int bcm_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -1551,7 +1551,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock, noblock = flags &MSG_DONTWAIT ; flags &= ~MSG_DONTWAIT ; - skb =skb_recv_datagram (sk, flags, noblock, &error); + skb =skb_recv_datagram (sk, flags, noblock, &error, timeop);if (!skb)return error;
net/can/raw.c +2 -2
@@ -731,7 +731,7 @@ send_failed: }static int raw_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -741,7 +741,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, noblock = flags &MSG_DONTWAIT ; flags &= ~MSG_DONTWAIT ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb)return err;
net/core/datagram.c +13 -6
@@ -138,6 +138,9 @@ out_noerr:* @off: an offset in bytes to peek skb from. Returns an offset * within an skb where data actually starts * @err: error code returned +* @timeop: per call timeout (as opposed as per socket via SO_RCVTIMEO), +* will return the remaining time, used in recvmmsg, ignored +* if set to NULL. * * Get a datagram skbuff, understands the peeking, nonblocking wakeups * and possible races. This replaces identical code in packet, raw and
@@ -162,7 +165,7 @@ out_noerr:* the standard around please. */ struct sk_buff *__skb_recv_datagram (struct sock *sk,unsigned int flags, -int *peeked,int *off,int *err) +int *peeked,int *off,int *err,long *timeop) {struct sk_buff *skb, *last;long timeo;
@@ -174,7 +177,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,if (error) goto no_packet; - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); do { /* Again only user level code calls this function, so nothing
@@ -205,6 +208,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,spin_unlock_irqrestore (&queue->lock, cpu_flags); *off = _off; +if (timeop) + *timeop = timeo;return skb; }spin_unlock_irqrestore (&queue->lock, cpu_flags);
@@ -219,22 +224,24 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, goto no_packet; }while (!wait_for_more_packets (sk, err, &timeo, last)); - +out: +if (timeop) + *timeop = timeo;return NULL ; no_packet: *err = error; -return NULL ; + goto out; }EXPORT_SYMBOL (__skb_recv_datagram);struct sk_buff *skb_recv_datagram (struct sock *sk,unsigned int flags, -int noblock,int *err) +int noblock,int *err,long *timeop) {int peeked, off =0 ;return __skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, err); + &peeked, &off, err, timeop); }EXPORT_SYMBOL (skb_recv_datagram);
net/core/sock.c +3 -3
@@ -2191,7 +2191,7 @@ int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,EXPORT_SYMBOL (sock_no_sendmsg);int sock_no_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m, -size_t len,int flags) +size_t len,int flags,long *timeop) {return -EOPNOTSUPP ; }
@@ -2577,14 +2577,14 @@ EXPORT_SYMBOL(compat_sock_common_getsockopt);#endif int sock_common_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int addr_len =0 ;int err; err = sk->sk_prot->recvmsg (iocb, sk, msg, size, flags &MSG_DONTWAIT , - flags & ~MSG_DONTWAIT , &addr_len); + flags & ~MSG_DONTWAIT , &addr_len, timeop);if (err >=0 ) msg->msg_namelen = addr_len;return err;
net/dccp/dccp.h +1 -1
@@ -314,7 +314,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size);int dccp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int nonblock,int flags, -int *addr_len); +int *addr_len,long *timeop);void dccp_shutdown (struct sock *sk,int how);int inet_dccp_listen (struct socket *sock,int backlog); unsigned int dccp_poll(struct file *file, struct socket *sock,
net/dccp/proto.c +4 -2
@@ -808,7 +808,7 @@ out_discard:EXPORT_SYMBOL_GPL (dccp_sendmsg);int dccp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len) +size_t len,int nonblock,int flags,int *addr_len,long *timeop) {const struct dccp_hdr *dh;long timeo;
@@ -820,7 +820,7 @@ int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out; } - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock); do { struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
@@ -910,6 +910,8 @@ verify_sock_status: }while (1 ); out:release_sock (sk); +if (timeop) + *timeop = timeo;return len; }
net/decnet/af_decnet.c +4 -3
@@ -1669,7 +1669,7 @@ static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, intstatic int dn_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct dn_scp *scp =DN_SK (sk);
@@ -1680,7 +1680,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,struct sk_buff *skb, *n;struct dn_skb_cb *cb =NULL ;unsigned char eor =0 ; -long timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); +long timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT );lock_sock (sk);
@@ -1814,7 +1814,8 @@ out: }release_sock (sk); - +if (timeop) + *timeop = timeo;return rv; }
net/ieee802154/dgram.c +2 -2
@@ -305,14 +305,14 @@ out:static int dgram_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock,int flags, -int *addr_len) +int *addr_len,long *timeop) {size_t copied =0 ;int err = -EOPNOTSUPP ;struct sk_buff *skb; DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ieee802154/raw.c +2 -2
@@ -179,13 +179,13 @@ out: }static int raw_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {size_t copied =0 ;int err = -EOPNOTSUPP ;struct sk_buff *skb; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ipv4/af_inet.c +2 -2
@@ -757,7 +757,7 @@ ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,EXPORT_SYMBOL (inet_sendpage);int inet_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int addr_len =0 ;
@@ -766,7 +766,7 @@ int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,sock_rps_record_flow (sk); err = sk->sk_prot->recvmsg (iocb, sk, msg, size, flags &MSG_DONTWAIT , - flags & ~MSG_DONTWAIT , &addr_len); + flags & ~MSG_DONTWAIT , &addr_len, timeop);if (err >=0 ) msg->msg_namelen = addr_len;return err;
net/ipv4/ping.c +2 -2
@@ -840,7 +840,7 @@ do_confirm: }int ping_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *isk =inet_sk (sk);int family = sk->sk_family;
@@ -864,7 +864,7 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ipv4/raw.c +2 -2
@@ -685,7 +685,7 @@ out: return ret;*/ static int raw_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk);size_t copied =0 ;
@@ -701,7 +701,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out; } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ipv4/tcp.c +7 -9
@@ -1602,7 +1602,7 @@ EXPORT_SYMBOL(tcp_read_sock);*/ int tcp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len) +size_t len,int nonblock,int flags,int *addr_len,long *timeop) {struct tcp_sock *tp =tcp_sk (sk);int copied =0 ;
@@ -1627,7 +1627,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,if (sk->sk_state ==TCP_LISTEN ) goto out; - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock);/* Urgent data needs to be handled specially. */ if (flags &MSG_OOB )
@@ -1994,20 +1994,18 @@ skip_copy:/* Clean up data we have read: This will do ACK frames. */ tcp_cleanup_rbuf (sk, copied); - -release_sock (sk); -return copied; - out:release_sock (sk); -return err; +if (timeop) + *timeop = timeo; +return copied; recv_urg: - err =tcp_recv_urg (sk, msg, len, flags); + copied =tcp_recv_urg (sk, msg, len, flags); goto out; recv_sndq: - err =tcp_peek_sndq (sk, msg, len); + copied =tcp_peek_sndq (sk, msg, len); goto out; }EXPORT_SYMBOL (tcp_recvmsg);
net/ipv4/udp.c +2 -2
@@ -1262,7 +1262,7 @@ EXPORT_SYMBOL(udp_ioctl);*/ int udp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk); DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
@@ -1278,7 +1278,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, try_again: skb =__skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, &err); + &peeked, &off, &err, timeop);if (!skb) goto out;
net/ipv4/udp_impl.h +1 -1
@@ -22,7 +22,7 @@ int compat_udp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);#endif int udp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int udp_sendpage (struct sock *sk,struct page *page,int offset,size_t size,int flags);int udp_queue_rcv_skb (struct sock *sk,struct sk_buff *skb);
net/ipv6/raw.c +2 -2
@@ -458,7 +458,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)static int rawv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len, -int noblock,int flags,int *addr_len) +int noblock,int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk); DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
@@ -475,7 +475,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,if (np->rxpmtu && np->rxopt.bits.rxpmtu)return ipv6_recv_rxpmtu (sk, msg, len, addr_len); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/ipv6/udp.c +2 -2
@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(udp6_lib_lookup);int udpv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len, -int noblock,int flags,int *addr_len) +int noblock,int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk);struct inet_sock *inet =inet_sk (sk);
@@ -400,7 +400,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, try_again: skb =__skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, &err); + &peeked, &off, &err, timeop);if (!skb) goto out;
net/ipv6/udp_impl.h +1 -1
@@ -26,7 +26,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,int udpv6_sendmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len);int udpv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int udpv6_queue_rcv_skb (struct sock *sk,struct sk_buff *skb);void udpv6_destroy_sock (struct sock *sk);
net/ipx/af_ipx.c +2 -2
@@ -1756,7 +1756,7 @@ out:static int ipx_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct ipx_sock *ipxs =ipx_sk (sk);
@@ -1791,7 +1791,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &rc); + flags &MSG_DONTWAIT , &rc, timeop);if (!skb) {if (rc == -EAGAIN && (sk->sk_shutdown &RCV_SHUTDOWN )) rc =0 ;
net/irda/af_irda.c +10 -6
@@ -1373,7 +1373,7 @@ out:* after being read, regardless of how much the user actually read */ static int irda_recvmsg_dgram (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct irda_sock *self =irda_sk (sk);
@@ -1384,7 +1384,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,IRDA_DEBUG (4 ,"%s()\n" , __func__); skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (!skb)return err;
@@ -1422,7 +1422,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,* Function irda_recvmsg_stream (iocb, sock, msg, size, flags) */ static int irda_recvmsg_stream (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct irda_sock *self =irda_sk (sk);
@@ -1445,7 +1445,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, err =0 ; target =sock_rcvlowat (sk, flags &MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, noblock); + timeo =sock_rcvtimeop (sk, timeop, noblock); do { int chunk;
@@ -1480,8 +1480,10 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,finish_wait (sk_sleep (sk), &wait); -if (err) -return err; +if (err) { + copied = err; +break ; + }if (sk->sk_shutdown &RCV_SHUTDOWN )break ;
@@ -1534,6 +1536,8 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, } } +if (timeop) + *timeop = timeo;return copied; }
net/iucv/af_iucv.c +2 -2
@@ -1321,7 +1321,7 @@ static void iucv_process_message_q(struct sock *sk) }static int iucv_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -1342,7 +1342,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,/* receive/dequeue next skb: * the function understands MSG_PEEK and, thus, does not dequeue skb */ - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {if (sk->sk_shutdown &RCV_SHUTDOWN )return 0 ;
net/key/af_key.c +2 -2
@@ -3635,7 +3635,7 @@ out:static int pfkey_recvmsg (struct kiocb *kiocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;struct pfkey_sock *pfk =pfkey_sk (sk);
@@ -3646,7 +3646,7 @@ static int pfkey_recvmsg(struct kiocb *kiocb,if (flags & ~(MSG_PEEK |MSG_DONTWAIT |MSG_TRUNC |MSG_CMSG_COMPAT )) goto out; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);if (skb ==NULL ) goto out;
net/l2tp/l2tp_ip.c +2 -2
@@ -507,7 +507,7 @@ no_route: }static int l2tp_ip_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk);size_t copied =0 ;
@@ -518,7 +518,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *mif (flags &MSG_OOB ) goto out; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/l2tp/l2tp_ip6.c +2 -2
@@ -645,7 +645,7 @@ do_confirm:static int l2tp_ip6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk); DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);
@@ -662,7 +662,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,if (flags &MSG_ERRQUEUE )return ipv6_recv_error (sk, msg, len, addr_len); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
net/l2tp/l2tp_ppp.c +2 -2
@@ -187,7 +187,7 @@ static int pppol2tp_recv_payload_hook(struct sk_buff *skb)*/ static int pppol2tp_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {int err;struct sk_buff *skb;
@@ -199,7 +199,7 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, err =0 ; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (!skb) goto end;
net/llc/af_llc.c +4 -2
@@ -705,7 +705,7 @@ out:* Returns non-negative upon success, negative otherwise. */ static int llc_ui_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) { DECLARE_SOCKADDR(struct sockaddr_llc *, uaddr, msg->msg_name);const int nonblock = flags &MSG_DONTWAIT ;
@@ -725,7 +725,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,if (unlikely (sk->sk_type ==SOCK_STREAM && sk->sk_state ==TCP_LISTEN )) goto out; - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock); seq = &llc->copied_seq;if (flags &MSG_PEEK ) {
@@ -851,6 +851,8 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, out:release_sock (sk); +if (timeop) + *timeop = timeo;return copied; copy_uaddr:if (uaddr !=NULL && skb !=NULL ) {
net/netlink/af_netlink.c +2 -2
@@ -2404,7 +2404,7 @@ out:static int netlink_recvmsg (struct kiocb *kiocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (kiocb);struct scm_cookie scm;
@@ -2420,7 +2420,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, copied =0 ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (skb ==NULL ) goto out;
net/netrom/af_netrom.c +2 -2
@@ -1134,7 +1134,7 @@ out: }static int nr_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk; DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);
@@ -1154,7 +1154,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, }/* Now we can treat all alike */ -if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er)) ==NULL ) { +if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er, timeop)) ==NULL ) {release_sock (sk);return er; }
net/nfc/llcp_sock.c +2 -2
@@ -794,7 +794,7 @@ static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int llcp_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -817,7 +817,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (flags & (MSG_OOB ))return -EOPNOTSUPP ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {pr_err ("Recv datagram failed state %d %d %d" , sk->sk_state, err,sock_error (sk));
net/nfc/rawsock.c +2 -2
@@ -249,7 +249,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int rawsock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;
@@ -259,7 +259,7 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,pr_debug ("sock=%p sk=%p len=%zu flags=%d\n" , sock, sk, len, flags); - skb =skb_recv_datagram (sk, flags, noblock, &rc); + skb =skb_recv_datagram (sk, flags, noblock, &rc, timeop);if (!skb)return rc;
net/packet/af_packet.c +2 -2
@@ -2852,7 +2852,7 @@ out:*/ static int packet_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;
@@ -2884,7 +2884,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,* but then it will block. */ - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);/* * An error occurred so return it. Because skb_recv_datagram()
net/phonet/datagram.c +2 -2
@@ -127,7 +127,7 @@ static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,static int pn_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sk_buff *skb =NULL ;struct sockaddr_pn sa;
@@ -138,7 +138,7 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, MSG_CMSG_COMPAT)) goto out_nofree; - skb =skb_recv_datagram (sk, flags, noblock, &rval); + skb =skb_recv_datagram (sk, flags, noblock, &rval, timeop);if (skb ==NULL ) goto out_nofree;
net/phonet/pep.c +3 -3
@@ -783,7 +783,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)u8 pipe_handle, enabled, n_sb;u8 aligned =0 ; - skb =skb_recv_datagram (sk,0 , flags &O_NONBLOCK , errp); + skb =skb_recv_datagram (sk,0 , flags &O_NONBLOCK , errp,NULL );if (!skb)return NULL ;
@@ -1248,7 +1248,7 @@ struct sk_buff *pep_read(struct sock *sk)static int pep_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sk_buff *skb;int err;
@@ -1277,7 +1277,7 @@ static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,return -EINVAL ; } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);lock_sock (sk);if (skb ==NULL ) {if (err == -ENOTCONN && sk->sk_state ==TCP_CLOSE_WAIT )
net/rds/rds.h +1 -1
@@ -706,7 +706,7 @@ void rds_inc_put(struct rds_incoming *inc);void rds_recv_incoming (struct rds_connection *conn,__be32 saddr,__be32 daddr,struct rds_incoming *inc,gfp_t gfp);int rds_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int msg_flags); +size_t size,int msg_flags,long *timeop);void rds_clear_recv_queue (struct rds_sock *rs);int rds_notify_queue_get (struct rds_sock *rs,struct msghdr *msg); void rds_inc_info_copy(struct rds_incoming *inc,
net/rds/recv.c +4 -2
@@ -396,7 +396,7 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg) }int rds_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int msg_flags) +size_t size,int msg_flags,long *timeop) {struct sock *sk = sock->sk;struct rds_sock *rs =rds_sk_to_rs (sk);
@@ -406,7 +406,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,struct rds_incoming *inc =NULL ;/* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock);rdsdebug ("size %zu flags 0x%x timeo %ld\n" , size, msg_flags, timeo);
@@ -493,6 +493,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,rds_inc_put (inc); out: +if (timeop) + *timeop = timeo;return ret; }
net/rose/af_rose.c +2 -2
@@ -1212,7 +1212,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,static int rose_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct rose_sock *rose =rose_sk (sk);
@@ -1229,7 +1229,7 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,return -ENOTCONN ;/* Now we can treat all alike */ -if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er)) ==NULL ) +if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er, timeop)) ==NULL )return er; qbit = (skb->data[0 ] &ROSE_Q_BIT ) ==ROSE_Q_BIT ;
net/rxrpc/ar-input.c +1 -1
@@ -655,7 +655,7 @@ void rxrpc_data_ready(struct sock *sk)return ; } - skb =skb_recv_datagram (sk,0 ,1 , &ret); + skb =skb_recv_datagram (sk,0 ,1 , &ret,NULL );if (!skb) {rxrpc_put_local (local);if (ret == -EAGAIN )
net/rxrpc/ar-internal.h +1 -1
@@ -573,7 +573,7 @@ extern const struct file_operations rxrpc_connection_seq_fops;*/ void rxrpc_remove_user_ID (struct rxrpc_sock *,struct rxrpc_call *);int rxrpc_recvmsg (struct kiocb *,struct socket *,struct msghdr *,size_t , -int ); +int ,long *);/* * ar-security.c
net/rxrpc/ar-recvmsg.c +13 -8
@@ -44,7 +44,7 @@ void rxrpc_remove_user_ID(struct rxrpc_sock *rx, struct rxrpc_call *call)* simultaneously */ int rxrpc_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct rxrpc_skb_priv *sp;struct rxrpc_call *call =NULL , *continue_call =NULL ;
@@ -63,7 +63,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, ullen = msg->msg_flags &MSG_CMSG_COMPAT ?4 :sizeof (unsigned long ); - timeo =sock_rcvtimeo (&rx->sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (&rx->sk, timeop, flags &MSG_DONTWAIT ); msg->msg_flags |=MSG_MORE ;lock_sock (&rx->sk);
@@ -78,7 +78,8 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (&rx->sk);if (continue_call)rxrpc_put_call (continue_call); -return -ENODATA ; + copied = -ENODATA ; + goto out_copied; } }
@@ -135,7 +136,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (&rx->sk);rxrpc_put_call (continue_call);_leave (" = %d [noncont]" , copied); -return copied; + goto out_copied; } }
@@ -252,6 +253,9 @@ out:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d [data]" , copied); +out_copied: +if (timeop) + *timeop = timeo;return copied;/* handle non-DATA messages such as aborts, incoming connections and
@@ -328,7 +332,8 @@ terminal_message:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d" , ret); -return ret; + copied = ret; + goto out_copied; copy_error:_debug ("copy error" );
@@ -337,7 +342,8 @@ copy_error:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d" , ret); -return ret; + copied = ret; + goto out_copied; wait_interrupted: ret =sock_intr_errno (timeo);
@@ -348,8 +354,7 @@ wait_error:if (copied) copied = ret;_leave (" = %d [waitfail %d]" , copied, ret); -return copied; - + goto out_copied; }/**
net/sctp/socket.c +12 -8
@@ -2042,11 +2042,11 @@ static int sctp_skb_pull(struct sk_buff *skb, int len)* flags - flags sent or received with the user message, see Section * 5 for complete description of the flags. */ -static struct sk_buff *sctp_skb_recv_datagram (struct sock *,int ,int ,int *); +static struct sk_buff *sctp_skb_recv_datagram (struct sock *,int ,int ,int *,long *);static int sctp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sctp_ulpevent *event =NULL ;struct sctp_sock *sp =sctp_sk (sk);
@@ -2066,7 +2066,7 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, goto out; } - skb =sctp_skb_recv_datagram (sk, flags, noblock, &err); + skb =sctp_skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;
@@ -6519,13 +6519,13 @@ out:* with a few changes to make lksctp work. */ static struct sk_buff *sctp_skb_recv_datagram (struct sock *sk,int flags, -int noblock,int *err) +int noblock,int *err,long *timeop) {int error;struct sk_buff *skb;long timeo; - timeo =sock_rcvtimeo (sk, noblock); + timeo =sock_rcvtimeop (sk, timeop, noblock);pr_debug ("%s: timeo:%ld, max:%ld\n" , __func__, timeo,MAX_SCHEDULE_TIMEOUT );
@@ -6549,7 +6549,7 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, }if (skb) -return skb; +break ;/* Caller is allowed not to check sk->sk_err before calling. */ error =sock_error (sk);
@@ -6569,11 +6569,15 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, goto no_packet; }while (sctp_wait_for_packet (sk, err, &timeo) ==0 ); -return NULL ; +out: +if (timeop) + *timeop = timeo; + +return skb; no_packet: *err = error; -return NULL ; + goto out; }/* If sndbuf has changed, wake up per association sndbuf waiters. */
net/socket.c +56 -31
200 lines not on this page · raw message
net/sunrpc/svcsock.c +1 -1
@@ -551,7 +551,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) err =kernel_recvmsg (svsk->sk_sock, &msg,NULL ,0 ,0 ,MSG_PEEK |MSG_DONTWAIT );if (err >=0 ) - skb =skb_recv_datagram (svsk->sk_sk,0 ,1 , &err); + skb =skb_recv_datagram (svsk->sk_sk,0 ,1 , &err,NULL );if (skb ==NULL ) {if (err != -EAGAIN ) {
net/sunrpc/xprtsock.c +2 -2
@@ -965,7 +965,7 @@ static void xs_local_data_ready(struct sock *sk)if (xprt ==NULL ) goto out; - skb =skb_recv_datagram (sk,0 ,1 , &err); + skb =skb_recv_datagram (sk,0 ,1 , &err,NULL );if (skb ==NULL ) goto out;
@@ -1027,7 +1027,7 @@ static void xs_udp_data_ready(struct sock *sk)if (!(xprt =xprt_from_sock (sk))) goto out; -if ((skb =skb_recv_datagram (sk,0 ,1 , &err)) ==NULL ) +if ((skb =skb_recv_datagram (sk,0 ,1 , &err,NULL )) ==NULL ) goto out; repsize = skb->len -sizeof (struct udphdr );
net/tipc/socket.c +5 -3
@@ -1031,7 +1031,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)* Returns size of returned message data, errno otherwise */ static int tipc_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t buf_len,int flags) +struct msghdr *m,size_t buf_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct tipc_sock *tsk =tipc_sk (sk);
@@ -1054,7 +1054,7 @@ static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock, goto exit; } - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); restart:/* Look for a message in receive queue; wait if necessary */
@@ -1109,6 +1109,8 @@ restart:advance_rx_queue (sk); } exit: +if (timeop) + *timeop = timeo;release_sock (sk);return res; }
@@ -1126,7 +1128,7 @@ exit:* Returns size of returned message data, errno otherwise */ static int tipc_recv_stream (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t buf_len,int flags) +struct msghdr *m,size_t buf_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct tipc_sock *tsk =tipc_sk (sk);
net/unix/af_unix.c +12 -11
@@ -519,17 +519,17 @@ static int unix_shutdown(struct socket *, int);static int unix_stream_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_stream_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_dgram_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_dgram_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_dgram_connect (struct socket *,struct sockaddr *,int ,int );static int unix_seqpacket_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_seqpacket_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_set_peek_off (struct sock *sk,int val) {
@@ -1283,7 +1283,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)* so that no locks are necessary. */ - skb =skb_recv_datagram (sk,0 , flags&O_NONBLOCK , &err); + skb =skb_recv_datagram (sk,0 , flags&O_NONBLOCK , &err,NULL );if (!skb) {/* This means receive shutdown. */ if (err ==0 )
@@ -1755,14 +1755,14 @@ static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock,static int unix_seqpacket_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;if (sk->sk_state !=TCP_ESTABLISHED )return -ENOTCONN ; -return unix_dgram_recvmsg (iocb, sock, msg, size, flags); +return unix_dgram_recvmsg (iocb, sock, msg, size, flags, timeop); }static void unix_copy_addr (struct msghdr *msg,struct sock *sk)
@@ -1777,7 +1777,7 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)static int unix_dgram_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (iocb);struct scm_cookie tmp_scm;
@@ -1803,7 +1803,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, skip =sk_peek_offset (sk, flags); - skb =__skb_recv_datagram (sk, flags, &peeked, &skip, &err); + skb =__skb_recv_datagram (sk, flags, &peeked, &skip, &err, timeop);if (!skb) {unix_state_lock (sk);/* Signal EOF on disconnected non-blocking SEQPACKET socket. */
@@ -1914,7 +1914,7 @@ static unsigned int unix_skb_len(const struct sk_buff *skb)static int unix_stream_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (iocb);struct scm_cookie tmp_scm;
@@ -1926,7 +1926,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,int check_creds =0 ;int target;int err =0 ; -long timeo; +long timeo =sock_rcvtimeop (sk, timeop, noblock);int skip; err = -EINVAL ;
@@ -1938,7 +1938,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; target =sock_rcvlowat (sk, flags&MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, noblock);/* Lock the socket to prevent queue disordering * while sleeps in memcpy_tomsg
@@ -2071,6 +2070,8 @@ again:mutex_unlock (&u->readlock);scm_recv (sock, msg, siocb->scm, flags); out: +if (timeop) + *timeop = timeo;return copied ? : err; }
net/vmw_vsock/af_vsock.c +6 -4
@@ -1063,10 +1063,10 @@ out: }static int vsock_dgram_recvmsg (struct kiocb *kiocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {return transport->dgram_dequeue (kiocb,vsock_sk (sock->sk), msg, len, - flags); + flags, timeop); }static const struct proto_ops vsock_dgram_ops = {
@@ -1646,7 +1646,7 @@ out:static int vsock_stream_recvmsg (struct kiocb *kiocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk;struct vsock_sock *vsk;
@@ -1661,6 +1661,7 @@ vsock_stream_recvmsg(struct kiocb *kiocb, sk = sock->sk; vsk =vsock_sk (sk); err =0 ; + timeout =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT );lock_sock (sk);
@@ -1711,7 +1712,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb, err = -ENOMEM ; goto out; } - timeout =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); copied =0 ; err = transport->notify_recv_init (vsk, target, &recv_data);
@@ -1821,6 +1821,8 @@ vsock_stream_recvmsg(struct kiocb *kiocb, out_wait:finish_wait (sk_sleep (sk), &wait); out: +if (timeop) + *timeop = timeout;release_sock (sk);return err; }
net/vmw_vsock/vmci_transport.c +2 -2
@@ -1733,7 +1733,7 @@ static int vmci_transport_dgram_enqueue(static int vmci_transport_dgram_dequeue (struct kiocb *kiocb,struct vsock_sock *vsk,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {int err;int noblock;
@@ -1748,7 +1748,7 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,/* Retrieve the head sk_buff from the socket's receive queue. */ err =0 ; - skb =skb_recv_datagram (&vsk->sk, flags, noblock, &err); + skb =skb_recv_datagram (&vsk->sk, flags, noblock, &err, timeop);if (err)return err;
net/x25/af_x25.c +2 -2
@@ -1254,7 +1254,7 @@ out_kfree_skb:static int x25_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;struct x25_sock *x25 =x25_sk (sk);
@@ -1306,7 +1306,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,/* Now we can treat all alike */ release_sock (sk); skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &rc); + flags &MSG_DONTWAIT , &rc, timeop);lock_sock (sk);if (!skb) goto out;
David Miller
maintainerFrom: Arnaldo Carvalho de Melo <[email protected]>
Date: Tue, 22 Jul 2014 16:48:51 -0300
Quoted 7 lines
Em Mon, Jul 21, 2014 at 08:45:38PM -0700, David Miller escreveu:
Quoted 6 lines
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Mon, 21 Jul 2014 16:21:31 -0300Quoted 2 lines
Trying to get this merged, finally. I has whas has been
discussed so far and agreed wrt the timeout handling.
Quoted 6 lines
Quoted 3 lines
This gets lots of rejects against the current 'net' tree.
Please respin and integrate Remi's Acked-by, thanks.
Here it is, I think we should wait a bit till Michael (and whoever else is up to test this today) can test it, Michael?
I don't see any testing feedback yet.
Also, Arnaldo, if you could submit patches in the standard way that would help me a lot. Subject line is fine, but you're then just inserting the output of something like "git show" into the email body.
That makes a lot of work for me, therefore it helps a lot if you submit things in a format that just works if I feed your email into "git am".
This means the email body is the commit message body, then you can put the standard separator "---" and then any anchillary messages or information you want to tell me like "let's wait for so and so to test this" that you don't want to make it into the git commit itself.
Then you provide the patch after all that.
This is exactly what you would obtain if you used git send-email or similar, editing the final result to your liking.
Thanks.
Em Wed, Jul 23, 2014 at 02:51:24PM -0700, David Miller escreveu:
Quoted 9 lines
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Tue, 22 Jul 2014 16:48:51 -0300Quoted 6 lines
Em Mon, Jul 21, 2014 at 08:45:38PM -0700, David Miller escreveu:
Quoted 5 lines
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Mon, 21 Jul 2014 16:21:31 -0300Quoted 2 lines
Trying to get this merged, finally. I has whas has been
discussed so far and agreed wrt the timeout handling.
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
This gets lots of rejects against the current 'net' tree.
Please respin and integrate Remi's Acked-by, thanks.
Here it is, I think we should wait a bit till Michael (and whoever else is up to test this today) can test it, Michael?
I don't see any testing feedback yet.
:-\
Quoted 4 lines
Also, Arnaldo, if you could submit patches in the standard way that would help me a lot. Subject line is fine, but you're then just inserting the output of something like "git show" into the email body.
/me stands corrected, should've know better.
I'll wait some more time and then resubmit, doing the whole process myself so that it works in the standard way, git-am, etc.
- Arnaldo
Hello Arnaldo,
Quoted 11 lines · Arnaldo Carvalho de Melo
Em Mon, Jul 21, 2014 at 08:45:38PM -0700, David Miller escreveu:
Quoted 9 lines
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Mon, 21 Jul 2014 16:21:31 -0300Quoted 2 lines
Trying to get this merged, finally. I has whas has been
discussed so far and agreed wrt the timeout handling.This gets lots of rejects against the current 'net' tree.
Please respin and integrate Remi's Acked-by, thanks.
Quoted 8 lines
Here it is, I think we should wait a bit till Michael (and whoever else is up to test this today) can test it, Michael?
It was done on top of:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.gitfrom early today.
Okay, this applied cleanly against a recent pull of the 'net' tree.
However, the failure case that I pointed out (for the second time already) in http://thread.gmane.org/gmane.linux.kernel/1711197/focus=6435
is *still* failing. (Are you actually testing this case for your patches? It appears not.) However, this time the failure mode is slightly different:
Suppose the following scenario:
1. We do a recvmmsg() with 10 second timeout, asking for 5 messages.
2. 3 messages arrive
3. 6 seconds after the call, a signal handler interrupts the call.
4. recvmmsg() returns success, telling us it got 3 messages.
So far, so good. But
5. We make a further recvmmsg() call.
6. That call returns immediately, with the (unknown error) value 512 in errno. (In the previous patch version, we (wrongly) got EINTR at this point.)
I also see now a second failure mode in this patch set (I'm not sure if it was present in your earlier patch sets). If the timespec structure pointed to by 'timeout' contains {0, 0} then the call blocks indefinitely, whereas it should return immediately (with, I think, an EAGAIN error) if there are no messages.
My test program (a modified version of the test program I posted earlier) is below. I've also added a test program that sends datagrams. To save some time, on the next iteration of your patch, could you please note which of the above failure modes you have tested for. Also, I think it would be good to include a detailed description of the expected semantics of the 'timeout' argument as part of the commit message. Then we all understand what the intended semantics are, and what needs to be tested. Something like this (may need fixing, if you think it is different):
[[
The 'timeout' argument implements three cases:
1) 'timeout' is NULL: the call blocks until 'vlen' datagrams are received.
2) 'timeout' points to {0, 0}: the call (immediately) returns up to 'vlen' datagrams if they are available. If no datagrams are available, the call returns immediately, with the error EAGAIN.
3) 'timeout'points to a structure in which at least one of the fields is nonzero. The call blocks until either:
a) the specified timeout expires
b) 'vlen' messages are received
In case (a), if one or more messages has been received, the call returns the number of messages received; otherwise, if no messages were received, the call fails with the error EAGAIN.
If, while blocking, the call is interrupted by a signal handler, then:
* if 1 or more datagrams have been received, then those datagrams are returned (and interruption by a signal handler is not (directly) reported by this or any subsequent call to recvmmsg()).
* if no datagrams have so far been received, then the call fails with the error EINTR.
]]
(In the cases where I mention EAGAIN above, the call could instead return 0, but EAGAIN seems more consistent with other APIs.)
Of course, if we'd had such a spec to begin with, then probably the problems with the 'timeout' argument would have been detected much sooner. (But, recvmmsg() is hardly the first, nor the last, of many, many examples of Linux API problems that occurred because of that omission.)
Thanks,
Michael
/* t_recvmmsg.c
(C) 2014, Michael Kerrisk, Licensed under the GNU General Public License, version 2 or later.
*/
#define _GNU_SOURCE
#include <sys/time.h>
#include <signal.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)static int /* Public interfaces: inetBind() and inetListen() */createBoundSocket(const char *service, int type, socklen_t *addrlen)
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
hints.ai_socktype = type;
hints.ai_family = AF_UNSPEC; /* Allows IPv4 or IPv6 */
hints.ai_flags = AI_PASSIVE; /* Use wildcard IP address */
s = getaddrinfo(NULL, service, &hints, &result);
if (s != 0)
return -1;
/* Walk through returned list until we find an address structure
that can be used to successfully create and bind a socket */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sfd == -1)
continue; /* On error, try next address */
if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
break; /* Success */
/* bind() failed: close this socket and try next address */
close(sfd);
}
if (rp != NULL && addrlen != NULL)
*addrlen = rp->ai_addrlen; /* Return address structure size */
freeaddrinfo(result);
return (rp == NULL) ? -1 : sfd;
}static voidhandler()
{
/* Just interrupt a syscall */
}intmain(int argc, char *argv[])
{
int sfd, vlen, j, s;
struct mmsghdr *msgvecp;
struct timespec ts, ts_saved;
struct timespec *tsp;
struct sigaction sa;
if (argc < 4) {
fprintf(stderr, "Usage: %s port tmo-secs buf-len...\n", argv[0]);
exit(EXIT_FAILURE);
}
sfd = createBoundSocket(argv[1], SOCK_DGRAM, NULL);
if (sfd == -1) {
fprintf(stderr, "Could not create server socket (%s)",
strerror(errno));
exit(EXIT_FAILURE);
}
/* Handle a signal, so we can test behaviour when recvmmsg()
is interrupted by a signal */
sa.sa_handler = handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
if (sigaction (SIGQUIT, &sa, NULL) == -1)
errExit("sigaction");
/* argv[2] specifies recvmmsg() timeout in seconds, or is '-', meaning
using NULL argument to get infinite timeout */
if (argv[2][0] == '-') {
tsp = NULL;
} else {
ts.tv_sec = atoi(argv[2]);
ts.tv_nsec = 0;
ts_saved = ts;
tsp = &ts;
}
/* Remaining command-line arguments specify the size of recvmmsg()
buffers */
/* The second argument to recvmmsg() is a pointer to an array of
mmsghdr structures. Each element of that array has a field,
'struct msghdr msg_hdr', that is used to store information from a
single received datagram. Among the fields in the msghdr structure
is a 'struct iovec *msg_iov'--that is, a pointer to a scatter/gather
I/O vector. To keep things simple for this example, our scatter/gather
vectors always consists of a single element.
*/
/* Allocate the mmssghdr vector, whose size corresponds to the
number of remaining command-line arguments */
vlen = argc - 3;
msgvecp = calloc(vlen, sizeof(struct mmsghdr));
if (msgvecp == NULL)
errExit("calloc");
for (j = 0; j < vlen; j++) {
msgvecp[j].msg_hdr.msg_name = NULL;
msgvecp[j].msg_hdr.msg_namelen = 0;
msgvecp[j].msg_hdr.msg_control = NULL;
msgvecp[j].msg_hdr.msg_controllen = 0;
/* Allocate an iovec for this mmsghdr element. The vector
contains just a single item. */
msgvecp[j].msg_hdr.msg_iovlen = 1;
msgvecp[j].msg_hdr.msg_iov = malloc(sizeof(struct iovec));
if (msgvecp[j].msg_hdr.msg_iov == NULL)
errExit("malloc");
/* The single iovec element contains a pointer to a buffer
that is sized according to the number given in the
corresponding command-line argument */
s = atoi(argv[j + 3]);
msgvecp[j].msg_hdr.msg_iov[0].iov_len = s;
msgvecp[j].msg_hdr.msg_iov[0].iov_base = malloc(s);
}
if (tsp != NULL)
printf("Timespec before call = %ld.%09ld\n",
(long) tsp->tv_sec, (long) tsp->tv_nsec);
/* Now we're ready to make the recvmmsg() call */
s = recvmmsg(sfd, msgvecp, vlen, 0, tsp);
if (s == -1) {
if (errno == EINTR)
printf("EINTR! (interrupted system call)\n");
else
errExit("recvmmsg");
}
printf("recvmmsg() returned %d\n", s);
if (tsp != NULL)
printf("Timespec after call = %ld.%09ld\n",
(long) tsp->tv_sec, (long) tsp->tv_nsec);
/* Display datagrams retrieved by recvmmsg() */
for (j = 0; j < s; j++) {
printf("%d: %u - %.*s\n", j,
msgvecp[j].msg_len, msgvecp[j].msg_len,
(char *) msgvecp[j].msg_hdr.msg_iov[0].iov_base);
}#ifdef SECOND_CALL
ts = ts_saved;
printf("About to make second recvmmsg() call\n");
if (tsp != NULL)
printf("Timespec before call = %ld.%09ld\n",
(long) tsp->tv_sec, (long) tsp->tv_nsec);
s = recvmmsg(sfd, msgvecp, vlen, 0, tsp);
if (s == -1) {
if (errno == EINTR)
printf("Second recvmmsg(): EINTR! (interrupted system call)\n");
else
errExit("recvmmsg");
}
printf("Second recvmmsg(): returned %d\n", s);#endif
exit(EXIT_SUCCESS); }
And this test program can be used to send datagrams:
/* id_sendto.c
(C) 2014, Michael Kerrisk, Licensed under the GNU General Public License, version 2 or later.
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
/* Create socket and connect it to the address specified by
'host' + 'service'/'type'. Return socket descriptor on success, or -1 on error */
static intinetConnect(const char *host, const char *service, int type)
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
hints.ai_family = AF_UNSPEC; /* Allows IPv4 or IPv6 */
hints.ai_socktype = type;
s = getaddrinfo(host, service, &hints, &result);
if (s != 0) {
errno = ENOSYS;
return -1;
}
/* Walk through returned list until we find an address structure
that can be used to successfully connect a socket */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sfd == -1)
continue; /* On error, try next address */
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* Success */
/* Connect failed: close this socket and try next address */
close(sfd);
}
freeaddrinfo(result);
return (rp == NULL) ? -1 : sfd;
}intmain(int argc, char *argv[])
{
int sfd, j;
if (argc < 3 || strcmp(argv[1], "--help") == 0) {
fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
exit(EXIT_FAILURE);
}
sfd = inetConnect(argv[1], argv[2], SOCK_DGRAM);
for (j = 3; j < argc; j++) {
if (send(sfd, argv[j], strlen(argv[j]), 0)
!= strlen(argv[j]))
perror("sendto");
}
exit(EXIT_SUCCESS);
}Quoted 2,180 lines
- Arnaldo
commit
93d40dc3a3266d6d4ed905b9333b6809b5fe24fcAuthor: Arnaldo Carvalho de Melo <[email protected]> Date: Fri Jul 18 15:23:44 2014 -0300net: Fix recvmmsg timeout handling
As reported by Elie de Brauwer the timeout handling in the recvmmsg syscall had issues that boil down to it not properly passing the remaining time to each underlying
recvmsg()call.Fix it by adding a timeout pointer to the recvmsg implementations, so that it can use that using a variation of
sock_rcvtimeo, that overrides the value inSO_RCVTIMEOwith the timeout passed, and returns the remaining time in that pointer, this way each underlying recvmsg call receives the remaining time.It ends up in most cases being just a forward of this pointer from recvmmsg to
skb_recv_datagram().Reported-by Elie De Brauwer <[email protected]>Cc Caitlin Bestler <[email protected]>Cc Chris Friesen <[email protected]>Cc David Laight <[email protected]>Cc Elie De Brauwer <[email protected]>Cc Michael Kerrisk <[email protected]>Cc Neil Horman <[email protected]>Cc Ondřej Bílka <[email protected]>Cc Paul Moore <[email protected]>Cc Rémi Denis-Courmont <[email protected]>Cc Steven Whitehouse <[email protected]>Signed-off-by Arnaldo Carvalho de Melo <[email protected]>crypto/algif_hash.c +1
-1@@ -151,7 +151,7 @@ unlock: }static int hash_recvmsg (struct kiocb *unused,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct alg_sock *ask =alg_sk (sk);crypto/algif_skcipher.c +1
-1@@ -419,7 +419,7 @@ unlock: }static int skcipher_recvmsg (struct kiocb *unused,struct socket *sock, -struct msghdr *msg,size_t ignored,int flags) +struct msghdr *msg,size_t ignored,int flags,long *timeop) {struct sock *sk = sock->sk;struct alg_sock *ask =alg_sk (sk);drivers/isdn/mISDN/socket.c +2
-2@@ -113,7 +113,7 @@ mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)static int mISDN_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sk_buff *skb;struct sock *sk = sock->sk;@@ -130,7 +130,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (sk->sk_state ==MISDN_CLOSED )return 0 ; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);if (!skb)return err;drivers/net/macvtap.c +1
-1@@ -1111,7 +1111,7 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock,static int macvtap_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags) +int flags,long *timeop) { struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);int ret;drivers/net/ppp/pppoe.c +2
-2@@ -963,7 +963,7 @@ static const struct ppp_channel_ops pppoe_chan_ops = { };static int pppoe_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t total_len,int flags) +struct msghdr *m,size_t total_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -975,7 +975,7 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, } skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &error); + flags &MSG_DONTWAIT , &error, timeop);if (error <0 ) goto end;drivers/net/tun.c +2
-2@@ -1343,7 +1343,7 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,/* Read frames from queue */ skb =__skb_recv_datagram (tfile->socket.sk, noblock ?MSG_DONTWAIT :0 , - &peeked, &off, &err); + &peeked, &off, &err,NULL );if (skb) { ret =tun_put_user (tun, tfile, skb, iv, len);kfree_skb (skb);@@ -1452,7 +1452,7 @@ static int tun_sendmsg(struct kiocb *iocb, struct socket *sock,static int tun_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags) +int flags,long *timeop) { struct tun_file *tfile = container_of(sock, struct tun_file, socket);struct tun_struct *tun =__tun_get (tfile);drivers/vhost/net.c +2
-2@@ -602,7 +602,7 @@ static void handle_rx(struct vhost_net *net)if (unlikely (headcount >UIO_MAXIOV )) { msg.msg_iovlen =1 ; err = sock->ops->recvmsg (NULL , sock, &msg, -1 ,MSG_DONTWAIT |MSG_TRUNC ); +1 ,MSG_DONTWAIT |MSG_TRUNC ,NULL );pr_debug ("Discarded rx packet: len %zd\n" , sock_len);continue ; }@@ -628,7 +628,7 @@ static void handle_rx(struct vhost_net *net)copy_iovec_hdr (vq->iov, nvq->hdr, sock_hlen, in); msg.msg_iovlen = in; err = sock->ops->recvmsg (NULL , sock, &msg, - sock_len,MSG_DONTWAIT |MSG_TRUNC ); + sock_len,MSG_DONTWAIT |MSG_TRUNC ,NULL );/* Userspace might have consumed the packet meanwhile: * it's not supposed to do this usually, but might be hard * to prevent. Discard data we got (if any) and keep going. */ include/linux/net.h +5
-2@@ -171,10 +171,13 @@ struct proto_ops {* returning uninitialized memory to user space. The recvfrom * handlers can assume that msg.msg_name is either NULL or has * a minimum size of sizeof(struct sockaddr_storage). +* timeop contains a per call timeout (as opposed as per socket, +* used by recvmmsg, set it to NULL to disable it. It should return +* the remaining time, if not NULL. */ int (*recvmsg) (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags); +int flags,long *timeop);int (*mmap) (struct file *file,struct socket *sock,struct vm_area_struct * vma); ssize_t (*sendpage) (struct socket *sock, struct page *page,@@ -215,7 +218,7 @@ int sock_create_lite(int family, int type, int proto, struct socket **res);void sock_release (struct socket *sock);int sock_sendmsg (struct socket *sock,struct msghdr *msg,size_t len);int sock_recvmsg (struct socket *sock,struct msghdr *msg,size_t size, -int flags); +int flags,long *timeop);struct file *sock_alloc_file (struct socket *sock,int flags,const char *dname);struct socket *sockfd_lookup (int fd,int *err);struct socket *sock_from_file (struct file *file,int *err);include/linux/skbuff.h +2
-2@@ -2513,9 +2513,9 @@ static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag)for (iter =skb_shinfo (skb)->frag_list; iter; iter = iter->next) struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, -int *peeked,int *off,int *err); +int *peeked,int *off,int *err,long *timeop);struct sk_buff *skb_recv_datagram (struct sock *sk,unsigned flags,int noblock, -int *err); +int *err,long *timeop);unsigned int datagram_poll (struct file *file,struct socket *sock,struct poll_table_struct *wait); int skb_copy_datagram_iovec(const struct sk_buff *from, int offset,include/net/af_vsock.h +1
-1@@ -101,7 +101,7 @@ struct vsock_transport {/* DGRAM. */ int (*dgram_bind)(struct vsock_sock *,struct sockaddr_vm *);int (*dgram_dequeue)(struct kiocb *kiocb,struct vsock_sock *vsk, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);int (*dgram_enqueue)(struct vsock_sock *,struct sockaddr_vm *,struct iovec *,size_t len);bool (*dgram_allow)(u32 cid,u32 port);include/net/bluetooth/bluetooth.h +2
-2@@ -246,9 +246,9 @@ void bt_sock_unregister(int proto);void bt_sock_link (struct bt_sock_list *l,struct sock *s);void bt_sock_unlink (struct bt_sock_list *l,struct sock *s);int bt_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);int bt_sock_stream_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);uint bt_sock_poll (struct file *file,struct socket *sock,poll_table *wait);int bt_sock_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg);int bt_sock_wait_state (struct sock *sk,int state,unsigned long timeo);include/net/inet_common.h +1
-1@@ -26,7 +26,7 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,ssize_t inet_sendpage (struct socket *sock,struct page *page,int offset,size_t size,int flags);int inet_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags); +size_t size,int flags,long *timeop);int inet_shutdown (struct socket *sock,int how);int inet_listen (struct socket *sock,int backlog);void inet_sock_destruct (struct sock *sk);include/net/ping.h +1
-1@@ -76,7 +76,7 @@ int ping_getfrag(void *from, char *to, int offset, int fraglen, int odd, struct sk_buff *);int ping_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int ping_common_sendmsg (int family,struct msghdr *msg,size_t len,void *user_icmph,size_t icmph_len); int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,include/net/sock.h +8
-3@@ -961,7 +961,7 @@ struct proto {int (*recvmsg)(struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock,int flags, -int *addr_len); +int *addr_len,long *timeop);int (*sendpage)(struct sock *sk,struct page *page,int offset,size_t size,int flags); int (*bind)(struct sock *sk,@@ -1593,7 +1593,7 @@ int sock_no_getsockopt(struct socket *, int , int, char __user *, int __user *);int sock_no_setsockopt (struct socket *,int ,int ,char __user *,unsigned int );int sock_no_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );int sock_no_recvmsg (struct kiocb *,struct socket *,struct msghdr *,size_t , -int ); +int ,long *);int sock_no_mmap (struct file *file,struct socket *sock,struct vm_area_struct *vma); ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset,@@ -1606,7 +1606,7 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset,int sock_common_getsockopt (struct socket *sock,int level,int optname,char __user *optval,int __user *optlen);int sock_common_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags); +struct msghdr *msg,size_t size,int flags,long *timeop);int sock_common_setsockopt (struct socket *sock,int level,int optname,char __user *optval,unsigned int optlen); int compat_sock_common_getsockopt(struct socket *sock, int level,@@ -2104,6 +2104,11 @@ static inline long sock_rcvtimeo(const struct sock *sk, bool noblock)return noblock ?0 : sk->sk_rcvtimeo; } +static inline long sock_rcvtimeop (const struct sock *sk,long *timeop,bool noblock) +{ +return noblock ?0 : (timeop ? *timeop : sk->sk_rcvtimeo); +} +static inline long sock_sndtimeo (const struct sock *sk,bool noblock) {return noblock ?0 : sk->sk_sndtimeo;include/net/tcp.h +1
-1@@ -437,7 +437,7 @@ int compat_tcp_setsockopt(struct sock *sk, int level, int optname,void tcp_set_keepalive (struct sock *sk,int val);void tcp_syn_ack_timeout (struct sock *sk,struct request_sock *req);int tcp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len); +size_t len,int nonblock,int flags,int *addr_len,long *timeop);void tcp_parse_options (const struct sk_buff *skb,struct tcp_options_received *opt_rx,int estab,struct tcp_fastopen_cookie *foc);net/appletalk/ddp.c +2
-2@@ -1729,7 +1729,7 @@ out: }static int atalk_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct ddpehdr *ddp;@@ -1739,7 +1739,7 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdrstruct sk_buff *skb; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);lock_sock (sk);if (!skb)net/atm/common.c +2
-2@@ -524,7 +524,7 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci) }int vcc_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct atm_vcc *vcc;@@ -544,7 +544,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, !test_bit(ATM_VF_READY, &vcc->flags))return 0 ; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &error); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &error, timeop);if (!skb)return error;net/atm/common.h +1
-1@@ -14,7 +14,7 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family);int vcc_release (struct socket *sock);int vcc_connect (struct socket *sock,int itf,short vpi,int vci);int vcc_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags); +size_t size,int flags,long *timeop);int vcc_sendmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len);unsigned int vcc_poll (struct file *file,struct socket *sock,poll_table *wait);net/ax25/af_ax25.c +2
-2@@ -1600,7 +1600,7 @@ out: }static int ax25_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -1619,7 +1619,7 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,/* Now we can treat all alike */ skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (skb ==NULL ) goto out;net/bluetooth/af_bluetooth.c +6
-4@@ -209,7 +209,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)EXPORT_SYMBOL (bt_accept_dequeue);int bt_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -222,7 +222,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (flags & (MSG_OOB ))return -EOPNOTSUPP ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {if (sk->sk_shutdown &RCV_SHUTDOWN )return 0 ;@@ -282,7 +282,7 @@ static long bt_sock_data_wait(struct sock *sk, long timeo) }int bt_sock_stream_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int err =0 ;@@ -297,7 +297,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,lock_sock (sk); target =sock_rcvlowat (sk, flags &MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); do { struct sk_buff *skb;@@ -381,6 +381,8 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, }while (size); out: +if (timeop) + *timeop = timeo;release_sock (sk);return copied ? : err; }net/bluetooth/hci_sock.c +2
-2@@ -829,7 +829,7 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, }static int hci_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -844,7 +844,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (sk->sk_state ==BT_CLOSED )return 0 ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb)return err;net/bluetooth/l2cap_sock.c +3
-3@@ -971,7 +971,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int l2cap_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct l2cap_pinfo *pi =l2cap_pi (sk);@@ -998,9 +998,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (sk);if (sock->type ==SOCK_STREAM ) - err =bt_sock_stream_recvmsg (iocb, sock, msg, len, flags); + err =bt_sock_stream_recvmsg (iocb, sock, msg, len, flags, timeop);else - err =bt_sock_recvmsg (iocb, sock, msg, len, flags); + err =bt_sock_recvmsg (iocb, sock, msg, len, flags, timeop);if (pi->chan->mode !=L2CAP_MODE_ERTM )return err;net/bluetooth/rfcomm/sock.c +2
-2@@ -617,7 +617,7 @@ done: }static int rfcomm_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct rfcomm_dlc *d =rfcomm_pi (sk)->dlc;@@ -628,7 +628,7 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,return 0 ; } - len =bt_sock_stream_recvmsg (iocb, sock, msg, size, flags); + len =bt_sock_stream_recvmsg (iocb, sock, msg, size, flags, timeop);lock_sock (sk);if (!(flags &MSG_PEEK ) && len >0 )net/bluetooth/sco.c +2
-2@@ -700,7 +700,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting) }static int sco_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sco_pinfo *pi =sco_pi (sk);@@ -718,7 +718,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (sk); -return bt_sock_recvmsg (iocb, sock, msg, len, flags); +return bt_sock_recvmsg (iocb, sock, msg, len, flags, timeop); }static int sco_sock_setsockopt (struct socket *sock,int level,int optname,char __user *optval,unsigned int optlen)net/caif/caif_socket.c +6
-4@@ -272,7 +272,7 @@ static void caif_check_flow_release(struct sock *sk)* changed locking, address handling and added MSG_TRUNC. */ static int caif_seqpkt_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t len,int flags) +struct msghdr *m,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;@@ -284,7 +284,7 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,if (m->msg_flags&MSG_OOB ) goto read_error; - skb =skb_recv_datagram (sk, flags,0 , &ret); + skb =skb_recv_datagram (sk, flags,0 , &ret, timeop);if (!skb) goto read_error; copylen = skb->len;@@ -345,7 +345,7 @@ static long caif_stream_data_wait(struct sock *sk, long timeo)*/ static int caif_stream_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;int copied =0 ;@@ -367,7 +367,7 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,caif_read_lock (sk); target =sock_rcvlowat (sk, flags&MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, flags&MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags&MSG_DONTWAIT ); do { int chunk;@@ -450,6 +450,8 @@ unlock:caif_read_unlock (sk); out: +if (timeop) + *timeop = timeo;return copied ? : err; }net/can/bcm.c +2
-2@@ -1541,7 +1541,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, }static int bcm_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -1551,7 +1551,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock, noblock = flags &MSG_DONTWAIT ; flags &= ~MSG_DONTWAIT ; - skb =skb_recv_datagram (sk, flags, noblock, &error); + skb =skb_recv_datagram (sk, flags, noblock, &error, timeop);if (!skb)return error;net/can/raw.c +2
-2@@ -731,7 +731,7 @@ send_failed: }static int raw_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -741,7 +741,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, noblock = flags &MSG_DONTWAIT ; flags &= ~MSG_DONTWAIT ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb)return err;net/core/datagram.c +13
-6@@ -138,6 +138,9 @@ out_noerr:* @off: an offset in bytes to peek skb from. Returns an offset * within an skb where data actually starts * @err: error code returned +* @timeop: per call timeout (as opposed as per socket via SO_RCVTIMEO), +* will return the remaining time, used in recvmmsg, ignored +* if set to NULL. * * Get a datagram skbuff, understands the peeking, nonblocking wakeups * and possible races. This replaces identical code in packet, raw and @@ -162,7 +165,7 @@ out_noerr:* the standard around please. */ struct sk_buff *__skb_recv_datagram (struct sock *sk,unsigned int flags, -int *peeked,int *off,int *err) +int *peeked,int *off,int *err,long *timeop) {struct sk_buff *skb, *last;long timeo;@@ -174,7 +177,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,if (error) goto no_packet; - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); do { /* Again only user level code calls this function, so nothing@@ -205,6 +208,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,spin_unlock_irqrestore (&queue->lock, cpu_flags); *off = _off; +if (timeop) + *timeop = timeo;return skb; }spin_unlock_irqrestore (&queue->lock, cpu_flags);@@ -219,22 +224,24 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, goto no_packet; }while (!wait_for_more_packets (sk, err, &timeo, last)); - +out: +if (timeop) + *timeop = timeo;return NULL ; no_packet: *err = error; -return NULL ; + goto out; }EXPORT_SYMBOL (__skb_recv_datagram);struct sk_buff *skb_recv_datagram (struct sock *sk,unsigned int flags, -int noblock,int *err) +int noblock,int *err,long *timeop) {int peeked, off =0 ;return __skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, err); + &peeked, &off, err, timeop); }EXPORT_SYMBOL (skb_recv_datagram);net/core/sock.c +3
-3@@ -2191,7 +2191,7 @@ int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,EXPORT_SYMBOL (sock_no_sendmsg);int sock_no_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m, -size_t len,int flags) +size_t len,int flags,long *timeop) {return -EOPNOTSUPP ; }@@ -2577,14 +2577,14 @@ EXPORT_SYMBOL(compat_sock_common_getsockopt);#endif int sock_common_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int addr_len =0 ;int err; err = sk->sk_prot->recvmsg (iocb, sk, msg, size, flags &MSG_DONTWAIT , - flags & ~MSG_DONTWAIT , &addr_len); + flags & ~MSG_DONTWAIT , &addr_len, timeop);if (err >=0 ) msg->msg_namelen = addr_len;return err;net/dccp/dccp.h +1
-1@@ -314,7 +314,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size);int dccp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int nonblock,int flags, -int *addr_len); +int *addr_len,long *timeop);void dccp_shutdown (struct sock *sk,int how);int inet_dccp_listen (struct socket *sock,int backlog); unsigned int dccp_poll(struct file *file, struct socket *sock,net/dccp/proto.c +4
-2@@ -808,7 +808,7 @@ out_discard:EXPORT_SYMBOL_GPL (dccp_sendmsg);int dccp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len) +size_t len,int nonblock,int flags,int *addr_len,long *timeop) {const struct dccp_hdr *dh;long timeo;@@ -820,7 +820,7 @@ int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out; } - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock); do { struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);@@ -910,6 +910,8 @@ verify_sock_status: }while (1 ); out:release_sock (sk); +if (timeop) + *timeop = timeo;return len; }net/decnet/af_decnet.c +4
-3@@ -1669,7 +1669,7 @@ static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, intstatic int dn_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct dn_scp *scp =DN_SK (sk);@@ -1680,7 +1680,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,struct sk_buff *skb, *n;struct dn_skb_cb *cb =NULL ;unsigned char eor =0 ; -long timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); +long timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT );lock_sock (sk);@@ -1814,7 +1814,8 @@ out: }release_sock (sk); - +if (timeop) + *timeop = timeo;return rv; }net/ieee802154/dgram.c +2
-2@@ -305,14 +305,14 @@ out:static int dgram_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock,int flags, -int *addr_len) +int *addr_len,long *timeop) {size_t copied =0 ;int err = -EOPNOTSUPP ;struct sk_buff *skb; DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ieee802154/raw.c +2
-2@@ -179,13 +179,13 @@ out: }static int raw_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {size_t copied =0 ;int err = -EOPNOTSUPP ;struct sk_buff *skb; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ipv4/af_inet.c +2
-2@@ -757,7 +757,7 @@ ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,EXPORT_SYMBOL (inet_sendpage);int inet_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int addr_len =0 ;@@ -766,7 +766,7 @@ int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,sock_rps_record_flow (sk); err = sk->sk_prot->recvmsg (iocb, sk, msg, size, flags &MSG_DONTWAIT , - flags & ~MSG_DONTWAIT , &addr_len); + flags & ~MSG_DONTWAIT , &addr_len, timeop);if (err >=0 ) msg->msg_namelen = addr_len;return err;net/ipv4/ping.c +2
-2@@ -840,7 +840,7 @@ do_confirm: }int ping_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *isk =inet_sk (sk);int family = sk->sk_family;@@ -864,7 +864,7 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ipv4/raw.c +2
-2@@ -685,7 +685,7 @@ out: return ret;*/ static int raw_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk);size_t copied =0 ;@@ -701,7 +701,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out; } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ipv4/tcp.c +7
-9@@ -1602,7 +1602,7 @@ EXPORT_SYMBOL(tcp_read_sock);*/ int tcp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len) +size_t len,int nonblock,int flags,int *addr_len,long *timeop) {struct tcp_sock *tp =tcp_sk (sk);int copied =0 ;@@ -1627,7 +1627,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,if (sk->sk_state ==TCP_LISTEN ) goto out; - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock);/* Urgent data needs to be handled specially. */ if (flags &MSG_OOB )@@ -1994,20 +1994,18 @@ skip_copy:/* Clean up data we have read: This will do ACK frames. */ tcp_cleanup_rbuf (sk, copied); - -release_sock (sk); -return copied; - out:release_sock (sk); -return err; +if (timeop) + *timeop = timeo; +return copied; recv_urg: - err =tcp_recv_urg (sk, msg, len, flags); + copied =tcp_recv_urg (sk, msg, len, flags); goto out; recv_sndq: - err =tcp_peek_sndq (sk, msg, len); + copied =tcp_peek_sndq (sk, msg, len); goto out; }EXPORT_SYMBOL (tcp_recvmsg);net/ipv4/udp.c +2
-2@@ -1262,7 +1262,7 @@ EXPORT_SYMBOL(udp_ioctl);*/ int udp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk); DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);@@ -1278,7 +1278,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, try_again: skb =__skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, &err); + &peeked, &off, &err, timeop);if (!skb) goto out;net/ipv4/udp_impl.h +1
-1@@ -22,7 +22,7 @@ int compat_udp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);#endif int udp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int udp_sendpage (struct sock *sk,struct page *page,int offset,size_t size,int flags);int udp_queue_rcv_skb (struct sock *sk,struct sk_buff *skb);net/ipv6/raw.c +2
-2@@ -458,7 +458,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)static int rawv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len, -int noblock,int flags,int *addr_len) +int noblock,int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk); DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);@@ -475,7 +475,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,if (np->rxpmtu && np->rxopt.bits.rxpmtu)return ipv6_recv_rxpmtu (sk, msg, len, addr_len); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ipv6/udp.c +2
-2@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(udp6_lib_lookup);int udpv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len, -int noblock,int flags,int *addr_len) +int noblock,int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk);struct inet_sock *inet =inet_sk (sk);@@ -400,7 +400,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, try_again: skb =__skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, &err); + &peeked, &off, &err, timeop);if (!skb) goto out;net/ipv6/udp_impl.h +1
-1@@ -26,7 +26,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,int udpv6_sendmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len);int udpv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int udpv6_queue_rcv_skb (struct sock *sk,struct sk_buff *skb);void udpv6_destroy_sock (struct sock *sk);net/ipx/af_ipx.c +2
-2@@ -1756,7 +1756,7 @@ out:static int ipx_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct ipx_sock *ipxs =ipx_sk (sk);@@ -1791,7 +1791,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &rc); + flags &MSG_DONTWAIT , &rc, timeop);if (!skb) {if (rc == -EAGAIN && (sk->sk_shutdown &RCV_SHUTDOWN )) rc =0 ;net/irda/af_irda.c +10
-6@@ -1373,7 +1373,7 @@ out:* after being read, regardless of how much the user actually read */ static int irda_recvmsg_dgram (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct irda_sock *self =irda_sk (sk);@@ -1384,7 +1384,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,IRDA_DEBUG (4 ,"%s()\n" , __func__); skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (!skb)return err;@@ -1422,7 +1422,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,* Function irda_recvmsg_stream (iocb, sock, msg, size, flags) */ static int irda_recvmsg_stream (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct irda_sock *self =irda_sk (sk);@@ -1445,7 +1445,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, err =0 ; target =sock_rcvlowat (sk, flags &MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, noblock); + timeo =sock_rcvtimeop (sk, timeop, noblock); do { int chunk;@@ -1480,8 +1480,10 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,finish_wait (sk_sleep (sk), &wait); -if (err) -return err; +if (err) { + copied = err; +break ; + }if (sk->sk_shutdown &RCV_SHUTDOWN )break ;@@ -1534,6 +1536,8 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, } } +if (timeop) + *timeop = timeo;return copied; }net/iucv/af_iucv.c +2
-2@@ -1321,7 +1321,7 @@ static void iucv_process_message_q(struct sock *sk) }static int iucv_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -1342,7 +1342,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,/* receive/dequeue next skb: * the function understands MSG_PEEK and, thus, does not dequeue skb */ - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {if (sk->sk_shutdown &RCV_SHUTDOWN )return 0 ;net/key/af_key.c +2
-2@@ -3635,7 +3635,7 @@ out:static int pfkey_recvmsg (struct kiocb *kiocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;struct pfkey_sock *pfk =pfkey_sk (sk);@@ -3646,7 +3646,7 @@ static int pfkey_recvmsg(struct kiocb *kiocb,if (flags & ~(MSG_PEEK |MSG_DONTWAIT |MSG_TRUNC |MSG_CMSG_COMPAT )) goto out; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);if (skb ==NULL ) goto out;net/l2tp/l2tp_ip.c +2
-2@@ -507,7 +507,7 @@ no_route: }static int l2tp_ip_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk);size_t copied =0 ;@@ -518,7 +518,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *mif (flags &MSG_OOB ) goto out; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/l2tp/l2tp_ip6.c +2
-2@@ -645,7 +645,7 @@ do_confirm:static int l2tp_ip6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk); DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);@@ -662,7 +662,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,if (flags &MSG_ERRQUEUE )return ipv6_recv_error (sk, msg, len, addr_len); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/l2tp/l2tp_ppp.c +2
-2@@ -187,7 +187,7 @@ static int pppol2tp_recv_payload_hook(struct sk_buff *skb)*/ static int pppol2tp_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {int err;struct sk_buff *skb;@@ -199,7 +199,7 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, err =0 ; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (!skb) goto end;net/llc/af_llc.c +4
-2@@ -705,7 +705,7 @@ out:* Returns non-negative upon success, negative otherwise. */ static int llc_ui_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) { DECLARE_SOCKADDR(struct sockaddr_llc *, uaddr, msg->msg_name);const int nonblock = flags &MSG_DONTWAIT ;@@ -725,7 +725,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,if (unlikely (sk->sk_type ==SOCK_STREAM && sk->sk_state ==TCP_LISTEN )) goto out; - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock); seq = &llc->copied_seq;if (flags &MSG_PEEK ) {@@ -851,6 +851,8 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, out:release_sock (sk); +if (timeop) + *timeop = timeo;return copied; copy_uaddr:if (uaddr !=NULL && skb !=NULL ) {net/netlink/af_netlink.c +2
-2@@ -2404,7 +2404,7 @@ out:static int netlink_recvmsg (struct kiocb *kiocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (kiocb);struct scm_cookie scm;@@ -2420,7 +2420,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, copied =0 ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (skb ==NULL ) goto out;net/netrom/af_netrom.c +2
-2@@ -1134,7 +1134,7 @@ out: }static int nr_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk; DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);@@ -1154,7 +1154,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, }/* Now we can treat all alike */ -if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er)) ==NULL ) { +if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er, timeop)) ==NULL ) {release_sock (sk);return er; }net/nfc/llcp_sock.c +2
-2@@ -794,7 +794,7 @@ static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int llcp_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -817,7 +817,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (flags & (MSG_OOB ))return -EOPNOTSUPP ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {pr_err ("Recv datagram failed state %d %d %d" , sk->sk_state, err,sock_error (sk));net/nfc/rawsock.c +2
-2@@ -249,7 +249,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int rawsock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -259,7 +259,7 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,pr_debug ("sock=%p sk=%p len=%zu flags=%d\n" , sock, sk, len, flags); - skb =skb_recv_datagram (sk, flags, noblock, &rc); + skb =skb_recv_datagram (sk, flags, noblock, &rc, timeop);if (!skb)return rc;net/packet/af_packet.c +2
-2@@ -2852,7 +2852,7 @@ out:*/ static int packet_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -2884,7 +2884,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,* but then it will block. */ - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);/* * An error occurred so return it. Because skb_recv_datagram() net/phonet/datagram.c +2
-2@@ -127,7 +127,7 @@ static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,static int pn_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sk_buff *skb =NULL ;struct sockaddr_pn sa;@@ -138,7 +138,7 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, MSG_CMSG_COMPAT)) goto out_nofree; - skb =skb_recv_datagram (sk, flags, noblock, &rval); + skb =skb_recv_datagram (sk, flags, noblock, &rval, timeop);if (skb ==NULL ) goto out_nofree;net/phonet/pep.c +3
-3@@ -783,7 +783,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)u8 pipe_handle, enabled, n_sb;u8 aligned =0 ; - skb =skb_recv_datagram (sk,0 , flags &O_NONBLOCK , errp); + skb =skb_recv_datagram (sk,0 , flags &O_NONBLOCK , errp,NULL );if (!skb)return NULL ;@@ -1248,7 +1248,7 @@ struct sk_buff *pep_read(struct sock *sk)static int pep_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sk_buff *skb;int err;@@ -1277,7 +1277,7 @@ static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,return -EINVAL ; } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);lock_sock (sk);if (skb ==NULL ) {if (err == -ENOTCONN && sk->sk_state ==TCP_CLOSE_WAIT )net/rds/rds.h +1
-1@@ -706,7 +706,7 @@ void rds_inc_put(struct rds_incoming *inc);void rds_recv_incoming (struct rds_connection *conn,__be32 saddr,__be32 daddr,struct rds_incoming *inc,gfp_t gfp);int rds_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int msg_flags); +size_t size,int msg_flags,long *timeop);void rds_clear_recv_queue (struct rds_sock *rs);int rds_notify_queue_get (struct rds_sock *rs,struct msghdr *msg); void rds_inc_info_copy(struct rds_incoming *inc,net/rds/recv.c +4
-2@@ -396,7 +396,7 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg) }int rds_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int msg_flags) +size_t size,int msg_flags,long *timeop) {struct sock *sk = sock->sk;struct rds_sock *rs =rds_sk_to_rs (sk);@@ -406,7 +406,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,struct rds_incoming *inc =NULL ;/* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock);rdsdebug ("size %zu flags 0x%x timeo %ld\n" , size, msg_flags, timeo);@@ -493,6 +493,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,rds_inc_put (inc); out: +if (timeop) + *timeop = timeo;return ret; }net/rose/af_rose.c +2
-2@@ -1212,7 +1212,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,static int rose_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct rose_sock *rose =rose_sk (sk);@@ -1229,7 +1229,7 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,return -ENOTCONN ;/* Now we can treat all alike */ -if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er)) ==NULL ) +if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er, timeop)) ==NULL )return er; qbit = (skb->data[0 ] &ROSE_Q_BIT ) ==ROSE_Q_BIT ;net/rxrpc/ar-input.c +1
-1@@ -655,7 +655,7 @@ void rxrpc_data_ready(struct sock *sk)return ; } - skb =skb_recv_datagram (sk,0 ,1 , &ret); + skb =skb_recv_datagram (sk,0 ,1 , &ret,NULL );if (!skb) {rxrpc_put_local (local);if (ret == -EAGAIN )net/rxrpc/ar-internal.h +1
-1@@ -573,7 +573,7 @@ extern const struct file_operations rxrpc_connection_seq_fops;*/ void rxrpc_remove_user_ID (struct rxrpc_sock *,struct rxrpc_call *);int rxrpc_recvmsg (struct kiocb *,struct socket *,struct msghdr *,size_t , -int ); +int ,long *);/* * ar-security.c net/rxrpc/ar-recvmsg.c +13
-8@@ -44,7 +44,7 @@ void rxrpc_remove_user_ID(struct rxrpc_sock *rx, struct rxrpc_call *call)* simultaneously */ int rxrpc_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct rxrpc_skb_priv *sp;struct rxrpc_call *call =NULL , *continue_call =NULL ;@@ -63,7 +63,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, ullen = msg->msg_flags &MSG_CMSG_COMPAT ?4 :sizeof (unsigned long ); - timeo =sock_rcvtimeo (&rx->sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (&rx->sk, timeop, flags &MSG_DONTWAIT ); msg->msg_flags |=MSG_MORE ;lock_sock (&rx->sk);@@ -78,7 +78,8 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (&rx->sk);if (continue_call)rxrpc_put_call (continue_call); -return -ENODATA ; + copied = -ENODATA ; + goto out_copied; } }@@ -135,7 +136,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (&rx->sk);rxrpc_put_call (continue_call);_leave (" = %d [noncont]" , copied); -return copied; + goto out_copied; } }@@ -252,6 +253,9 @@ out:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d [data]" , copied); +out_copied: +if (timeop) + *timeop = timeo;return copied;/* handle non-DATA messages such as aborts, incoming connections and @@ -328,7 +332,8 @@ terminal_message:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d" , ret); -return ret; + copied = ret; + goto out_copied; copy_error:_debug ("copy error" );@@ -337,7 +342,8 @@ copy_error:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d" , ret); -return ret; + copied = ret; + goto out_copied; wait_interrupted: ret =sock_intr_errno (timeo);@@ -348,8 +354,7 @@ wait_error:if (copied) copied = ret;_leave (" = %d [waitfail %d]" , copied, ret); -return copied; - + goto out_copied; }/** net/sctp/socket.c +12
-8@@ -2042,11 +2042,11 @@ static int sctp_skb_pull(struct sk_buff *skb, int len)* flags - flags sent or received with the user message, see Section * 5 for complete description of the flags. */ -static struct sk_buff *sctp_skb_recv_datagram (struct sock *,int ,int ,int *); +static struct sk_buff *sctp_skb_recv_datagram (struct sock *,int ,int ,int *,long *);static int sctp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sctp_ulpevent *event =NULL ;struct sctp_sock *sp =sctp_sk (sk);@@ -2066,7 +2066,7 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, goto out; } - skb =sctp_skb_recv_datagram (sk, flags, noblock, &err); + skb =sctp_skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;@@ -6519,13 +6519,13 @@ out:* with a few changes to make lksctp work. */ static struct sk_buff *sctp_skb_recv_datagram (struct sock *sk,int flags, -int noblock,int *err) +int noblock,int *err,long *timeop) {int error;struct sk_buff *skb;long timeo; - timeo =sock_rcvtimeo (sk, noblock); + timeo =sock_rcvtimeop (sk, timeop, noblock);pr_debug ("%s: timeo:%ld, max:%ld\n" , __func__, timeo,MAX_SCHEDULE_TIMEOUT );@@ -6549,7 +6549,7 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, }if (skb) -return skb; +break ;/* Caller is allowed not to check sk->sk_err before calling. */ error =sock_error (sk);@@ -6569,11 +6569,15 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, goto no_packet; }while (sctp_wait_for_packet (sk, err, &timeo) ==0 ); -return NULL ; +out: +if (timeop) + *timeop = timeo; + +return skb; no_packet: *err = error; -return NULL ; + goto out; }/* If sndbuf has changed, wake up per association sndbuf waiters. */ net/socket.c +56
-31@@ -772,7 +772,7 @@ void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,EXPORT_SYMBOL_GPL (__sock_recv_ts_and_drops);static inline int __sock_recvmsg_nosec (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock_iocb *si =kiocb_to_siocb (iocb);@@ -782,19 +782,19 @@ static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, si->size = size; si->flags = flags; -return sock->ops->recvmsg (iocb, sock, msg, size, flags); +return sock->ops->recvmsg (iocb, sock, msg, size, flags, timeop); }static inline int __sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {int err =security_socket_recvmsg (sock, msg, size, flags); -return err ?:__sock_recvmsg_nosec (iocb, sock, msg, size, flags); +return err ?:__sock_recvmsg_nosec (iocb, sock, msg, size, flags, timeop); }int sock_recvmsg (struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct kiocb iocb;struct sock_iocb siocb;@@ -802,7 +802,7 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg,init_sync_kiocb (&iocb,NULL ); iocb.private = &siocb; - ret =__sock_recvmsg (&iocb, sock, msg, size, flags); + ret =__sock_recvmsg (&iocb, sock, msg, size, flags, timeop);if (-EIOCBQUEUED == ret) ret =wait_on_sync_kiocb (&iocb);return ret;@@ -810,7 +810,7 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg,EXPORT_SYMBOL (sock_recvmsg);static int sock_recvmsg_nosec (struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct kiocb iocb;struct sock_iocb siocb;@@ -818,7 +818,7 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,init_sync_kiocb (&iocb,NULL ); iocb.private = &siocb; - ret =__sock_recvmsg_nosec (&iocb, sock, msg, size, flags); + ret =__sock_recvmsg_nosec (&iocb, sock, msg, size, flags, timeop);if (-EIOCBQUEUED == ret) ret =wait_on_sync_kiocb (&iocb);return ret;@@ -851,7 +851,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg,* iovec are identical, yielding the same in-core layout and alignment */ msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num; - result =sock_recvmsg (sock, msg, size, flags); + result =sock_recvmsg (sock, msg, size, flags,NULL );set_fs (oldfs);return result; }@@ -914,7 +914,7 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, msg->msg_iovlen = nr_segs; msg->msg_flags = (file->f_flags &O_NONBLOCK ) ?MSG_DONTWAIT :0 ; -return __sock_recvmsg (iocb, sock, msg, size, msg->msg_flags); +return __sock_recvmsg (iocb, sock, msg, size, msg->msg_flags,NULL ); } static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,@@ -1862,7 +1862,7 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, msg.msg_namelen =0 ;if (sock->file->f_flags &O_NONBLOCK ) flags |=MSG_DONTWAIT ; - err =sock_recvmsg (sock, &msg, size, flags); + err =sock_recvmsg (sock, &msg, size, flags,NULL );if (err >=0 && addr !=NULL ) { err2 = move_addr_to_user(&address,@@ -2207,7 +2207,7 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, }static int ___sys_recvmsg (struct socket *sock,struct msghdr __user *msg, -struct msghdr *msg_sys,unsigned int flags,int nosec) +struct msghdr *msg_sys,unsigned int flags,int nosec,long *timeop) {struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg;@@ -2265,7 +2265,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,if (sock->file->f_flags &O_NONBLOCK ) flags |=MSG_DONTWAIT ; err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, - total_len, flags); + total_len, flags, timeop);if (err <0 ) goto out_freeiov; len = err;@@ -2312,7 +2312,7 @@ long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags)if (!sock) goto out; - err =___sys_recvmsg (sock, msg, &msg_sys, flags,0 ); + err =___sys_recvmsg (sock, msg, &msg_sys, flags,0 ,NULL );fput_light (sock->file, fput_needed); out:@@ -2327,6 +2327,30 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,return __sys_recvmsg (fd, msg, flags); } +static int sock_set_timeout_ts (long *timeo_p,struct timespec *ts) +{ +if (ts->tv_nsec <0 || ts->tv_nsec >=NSEC_PER_SEC ) +return -EDOM ; + +if (ts->tv_sec <0 ) { +static int warned__read_mostly ; + + *timeo_p =0 ; +if (warned <10 &&net_ratelimit ()) { + warned++; +pr_info ("%s: `%s' (pid %d) tries to set negative timeout\n" , + __func__, current->comm,task_pid_nr (current)); + } +return 0 ; + } + *timeo_p =MAX_SCHEDULE_TIMEOUT ; +if (ts->tv_sec ==0 && ts->tv_nsec ==0 ) +return 0 ; +if (ts->tv_sec < (MAX_SCHEDULE_TIMEOUT /HZ -1 )) + *timeo_p = ts->tv_sec *HZ + (ts->tv_nsec + (NSEC_PER_SEC /HZ -1 )) / (NSEC_PER_SEC /HZ ); +return 0 ; +} +/* * Linux recvmmsg interface */ @@ -2339,12 +2363,14 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,struct mmsghdr __user *entry;struct compat_mmsghdr __user *compat_entry;struct msghdr msg_sys; -struct timespec end_time; +long timeout_hz, *timeop =NULL ; -if (timeout && -poll_select_set_timeout (&end_time, timeout->tv_sec, - timeout->tv_nsec)) -return -EINVAL ; +if (timeout) { + err =sock_set_timeout_ts (&timeout_hz, timeout); +if (err) +return err; + timeop = &timeout_hz; + } datagrams =0 ;@@ -2366,7 +2392,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,if (MSG_CMSG_COMPAT & flags) { err =___sys_recvmsg (sock, (struct msghdr __user *)compat_entry, &msg_sys, flags & ~MSG_WAITFORONE , - datagrams); + datagrams, timeop);if (err <0 )break ; err =__put_user (err, &compat_entry->msg_len);@@ -2375,7 +2401,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, err =___sys_recvmsg (sock, (struct msghdr __user *)entry, &msg_sys, flags & ~MSG_WAITFORONE , - datagrams); + datagrams, timeop);if (err <0 )break ; err =put_user (err, &entry->msg_len);@@ -2390,17 +2416,11 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,if (flags &MSG_WAITFORONE ) flags |=MSG_DONTWAIT ; -if (timeout) { -ktime_get_ts (timeout); - *timeout =timespec_sub (end_time, *timeout); -if (timeout->tv_sec <0 ) { - timeout->tv_sec = timeout->tv_nsec =0 ; -break ; - } - +if (timeout && timeout_hz ==0 ) {/* Timeout, return less than vlen datagrams */ -if (timeout->tv_nsec ==0 && timeout->tv_sec ==0 ) -break ; + timeout->tv_sec = timeout->tv_nsec =0 ; + timeop =NULL ; +break ; }/* Out of band data, return right away */ @@ -2411,6 +2431,11 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, out_put:fput_light (sock->file, fput_needed); +if (timeop) { + timeout->tv_sec = timeout_hz /HZ ; + timeout->tv_nsec = (timeout_hz %HZ ) * (NSEC_PER_SEC /HZ ); + } +if (err ==0 )return datagrams;net/sunrpc/svcsock.c +1
-1@@ -551,7 +551,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) err =kernel_recvmsg (svsk->sk_sock, &msg,NULL ,0 ,0 ,MSG_PEEK |MSG_DONTWAIT );if (err >=0 ) - skb =skb_recv_datagram (svsk->sk_sk,0 ,1 , &err); + skb =skb_recv_datagram (svsk->sk_sk,0 ,1 , &err,NULL );if (skb ==NULL ) {if (err != -EAGAIN ) {net/sunrpc/xprtsock.c +2
-2@@ -965,7 +965,7 @@ static void xs_local_data_ready(struct sock *sk)if (xprt ==NULL ) goto out; - skb =skb_recv_datagram (sk,0 ,1 , &err); + skb =skb_recv_datagram (sk,0 ,1 , &err,NULL );if (skb ==NULL ) goto out;@@ -1027,7 +1027,7 @@ static void xs_udp_data_ready(struct sock *sk)if (!(xprt =xprt_from_sock (sk))) goto out; -if ((skb =skb_recv_datagram (sk,0 ,1 , &err)) ==NULL ) +if ((skb =skb_recv_datagram (sk,0 ,1 , &err,NULL )) ==NULL ) goto out; repsize = skb->len -sizeof (struct udphdr );net/tipc/socket.c +5
-3@@ -1031,7 +1031,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)* Returns size of returned message data, errno otherwise */ static int tipc_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t buf_len,int flags) +struct msghdr *m,size_t buf_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct tipc_sock *tsk =tipc_sk (sk);@@ -1054,7 +1054,7 @@ static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock, goto exit; } - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); restart:/* Look for a message in receive queue; wait if necessary */ @@ -1109,6 +1109,8 @@ restart:advance_rx_queue (sk); } exit: +if (timeop) + *timeop = timeo;release_sock (sk);return res; }@@ -1126,7 +1128,7 @@ exit:* Returns size of returned message data, errno otherwise */ static int tipc_recv_stream (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t buf_len,int flags) +struct msghdr *m,size_t buf_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct tipc_sock *tsk =tipc_sk (sk);net/unix/af_unix.c +12
-11@@ -519,17 +519,17 @@ static int unix_shutdown(struct socket *, int);static int unix_stream_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_stream_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_dgram_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_dgram_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_dgram_connect (struct socket *,struct sockaddr *,int ,int );static int unix_seqpacket_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_seqpacket_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_set_peek_off (struct sock *sk,int val) {@@ -1283,7 +1283,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)* so that no locks are necessary. */ - skb =skb_recv_datagram (sk,0 , flags&O_NONBLOCK , &err); + skb =skb_recv_datagram (sk,0 , flags&O_NONBLOCK , &err,NULL );if (!skb) {/* This means receive shutdown. */ if (err ==0 )@@ -1755,14 +1755,14 @@ static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock,static int unix_seqpacket_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;if (sk->sk_state !=TCP_ESTABLISHED )return -ENOTCONN ; -return unix_dgram_recvmsg (iocb, sock, msg, size, flags); +return unix_dgram_recvmsg (iocb, sock, msg, size, flags, timeop); }static void unix_copy_addr (struct msghdr *msg,struct sock *sk)@@ -1777,7 +1777,7 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)static int unix_dgram_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (iocb);struct scm_cookie tmp_scm;@@ -1803,7 +1803,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, skip =sk_peek_offset (sk, flags); - skb =__skb_recv_datagram (sk, flags, &peeked, &skip, &err); + skb =__skb_recv_datagram (sk, flags, &peeked, &skip, &err, timeop);if (!skb) {unix_state_lock (sk);/* Signal EOF on disconnected non-blocking SEQPACKET socket. */ @@ -1914,7 +1914,7 @@ static unsigned int unix_skb_len(const struct sk_buff *skb)static int unix_stream_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (iocb);struct scm_cookie tmp_scm;@@ -1926,7 +1926,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,int check_creds =0 ;int target;int err =0 ; -long timeo; +long timeo =sock_rcvtimeop (sk, timeop, noblock);int skip; err = -EINVAL ;@@ -1938,7 +1938,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; target =sock_rcvlowat (sk, flags&MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, noblock);/* Lock the socket to prevent queue disordering * while sleeps in memcpy_tomsg @@ -2071,6 +2070,8 @@ again:mutex_unlock (&u->readlock);scm_recv (sock, msg, siocb->scm, flags); out: +if (timeop) + *timeop = timeo;return copied ? : err; }net/vmw_vsock/af_vsock.c +6
-4@@ -1063,10 +1063,10 @@ out: }static int vsock_dgram_recvmsg (struct kiocb *kiocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {return transport->dgram_dequeue (kiocb,vsock_sk (sock->sk), msg, len, - flags); + flags, timeop); }static const struct proto_ops vsock_dgram_ops = {@@ -1646,7 +1646,7 @@ out:static int vsock_stream_recvmsg (struct kiocb *kiocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk;struct vsock_sock *vsk;@@ -1661,6 +1661,7 @@ vsock_stream_recvmsg(struct kiocb *kiocb, sk = sock->sk; vsk =vsock_sk (sk); err =0 ; + timeout =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT );lock_sock (sk);@@ -1711,7 +1712,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb, err = -ENOMEM ; goto out; } - timeout =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); copied =0 ; err = transport->notify_recv_init (vsk, target, &recv_data);@@ -1821,6 +1821,8 @@ vsock_stream_recvmsg(struct kiocb *kiocb, out_wait:finish_wait (sk_sleep (sk), &wait); out: +if (timeop) + *timeop = timeout;release_sock (sk);return err; }net/vmw_vsock/vmci_transport.c +2
-2@@ -1733,7 +1733,7 @@ static int vmci_transport_dgram_enqueue(static int vmci_transport_dgram_dequeue (struct kiocb *kiocb,struct vsock_sock *vsk,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {int err;int noblock;@@ -1748,7 +1748,7 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,/* Retrieve the head sk_buff from the socket's receive queue. */ err =0 ; - skb =skb_recv_datagram (&vsk->sk, flags, noblock, &err); + skb =skb_recv_datagram (&vsk->sk, flags, noblock, &err, timeop);if (err)return err;net/x25/af_x25.c +2
-2@@ -1254,7 +1254,7 @@ out_kfree_skb:static int x25_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;struct x25_sock *x25 =x25_sk (sk);@@ -1306,7 +1306,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,/* Now we can treat all alike */ release_sock (sk); skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &rc); + flags &MSG_DONTWAIT , &rc, timeop);lock_sock (sk);if (!skb) goto out;
Signature · 3 lines
Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/
Ping, Arnaldo!
Quoted 2,582 lines · Michael Kerrisk (man-pages)
Hello Arnaldo,
Quoted 11 lines · Arnaldo Carvalho de Melo
Em Mon, Jul 21, 2014 at 08:45:38PM -0700, David Miller escreveu:
Quoted 9 lines
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Mon, 21 Jul 2014 16:21:31 -0300Quoted 2 lines
Trying to get this merged, finally. I has whas has been
discussed so far and agreed wrt the timeout handling.This gets lots of rejects against the current 'net' tree.
Please respin and integrate Remi's Acked-by, thanks.
Quoted 8 lines
Here it is, I think we should wait a bit till Michael (and whoever else is up to test this today) can test it, Michael?
It was done on top of:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.gitfrom early today.
Okay, this applied cleanly against a recent pull of the 'net' tree.
However, the failure case that I pointed out (for the second time already) in http://thread.gmane.org/gmane.linux.kernel/1711197/focus=6435
is *still* failing. (Are you actually testing this case for your patches? It appears not.) However, this time the failure mode is slightly different:Suppose the following scenario:
1. We do a
recvmmsg()with 10 second timeout, asking for 5 messages.
2. 3 messages arrive
3. 6 seconds after the call, a signal handler interrupts the call.
4.recvmmsg()returns success, telling us it got 3 messages.So far, so good. But
5. We make a further
recvmmsg()call.
6. That call returns immediately, with the (unknown error) value 512 in errno. (In the previous patch version, we (wrongly) got EINTR at this point.)I also see now a second failure mode in this patch set (I'm not sure if it was present in your earlier patch sets). If the timespec structure pointed to by 'timeout' contains {0, 0} then the call blocks indefinitely, whereas it should return immediately (with, I think, an EAGAIN error) if there are no messages.
My test program (a modified version of the test program I posted earlier) is below. I've also added a test program that sends datagrams. To save some time, on the next iteration of your patch, could you please note which of the above failure modes you have tested for. Also, I think it would be good to include a detailed description of the expected semantics of the 'timeout' argument as part of the commit message. Then we all understand what the intended semantics are, and what needs to be tested. Something like this (may need fixing, if you think it is different):
[[
The 'timeout' argument implements three cases:1) 'timeout' is NULL: the call blocks until 'vlen' datagrams are received.
2) 'timeout' points to {0, 0}: the call (immediately) returns up to 'vlen' datagrams if they are available. If no datagrams are available, the call returns immediately, with the error EAGAIN.
3) 'timeout'points to a structure in which at least one of the fields is nonzero. The call blocks until either:a) the specified timeout expires
b) 'vlen' messages are receivedIn case (a), if one or more messages has been received, the call returns the number of messages received; otherwise, if no messages were received, the call fails with the error EAGAIN.
If, while blocking, the call is interrupted by a signal handler, then:
* if 1 or more datagrams have been received, then those datagrams are returned (and interruption by a signal handler is not (directly) reported by this or any subsequent call to
recvmmsg()).
* if no datagrams have so far been received, then the call fails with the error EINTR.
]](In the cases where I mention EAGAIN above, the call could instead return 0, but EAGAIN seems more consistent with other APIs.)
Of course, if we'd had such a spec to begin with, then probably the problems with the 'timeout' argument would have been detected much sooner. (But,
recvmmsg()is hardly the first, nor the last, of many, many examples of Linux API problems that occurred because of that omission.)Thanks,
Michael
/*
t_recvmmsg.c(C) 2014, Michael Kerrisk, Licensed under the GNU General Public License, version 2 or later.
*/
#define_GNU_SOURCE
#include <sys/time.h>
#include <signal.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ } while (0)static int /* Public interfaces:
inetBind()andinetListen()*/createBoundSocket(const char *service, int type, socklen_t *addrlen){ struct addrinfo hints; struct addrinfo *result, *rp; int sfd, s; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; hints.ai_socktype = type; hints.ai_family = AF_UNSPEC; /* Allows IPv4 or IPv6 */ hints.ai_flags = AI_PASSIVE; /* Use wildcard IP address */ s = getaddrinfo(NULL, service, &hints, &result); if (s != 0) return -1; /* Walk through returned list until we find an address structure that can be used to successfully create and bind a socket */ for (rp = result; rp != NULL; rp = rp->ai_next) { sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sfd == -1) continue; /* On error, try next address */ if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) break; /* Success */ /* bind() failed: close this socket and try next address */ close(sfd); } if (rp != NULL && addrlen != NULL) *addrlen = rp->ai_addrlen; /* Return address structure size */ freeaddrinfo(result); return (rp == NULL) ? -1 : sfd; }static void
handler(){ /* Just interrupt a syscall */ }int
main(int argc, char *argv[]){ int sfd, vlen, j, s; struct mmsghdr *msgvecp; struct timespec ts, ts_saved; struct timespec *tsp; struct sigaction sa; if (argc < 4) { fprintf(stderr, "Usage: %s port tmo-secs buf-len...\n", argv[0]); exit(EXIT_FAILURE); } sfd = createBoundSocket(argv[1], SOCK_DGRAM, NULL); if (sfd == -1) { fprintf(stderr, "Could not create server socket (%s)", strerror(errno)); exit(EXIT_FAILURE); } /* Handle a signal, so we can test behaviour when recvmmsg() is interrupted by a signal */ sa.sa_handler = handler; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); if (sigaction (SIGQUIT, &sa, NULL) == -1) errExit("sigaction"); /* argv[2] specifies recvmmsg() timeout in seconds, or is '-', meaning using NULL argument to get infinite timeout */ if (argv[2][0] == '-') { tsp = NULL; } else { ts.tv_sec = atoi(argv[2]); ts.tv_nsec = 0; ts_saved = ts; tsp = &ts; } /* Remaining command-line arguments specify the size of recvmmsg() buffers */ /* The second argument to recvmmsg() is a pointer to an array of mmsghdr structures. Each element of that array has a field, 'struct msghdr msg_hdr', that is used to store information from a single received datagram. Among the fields in the msghdr structure is a 'struct iovec *msg_iov'--that is, a pointer to a scatter/gather I/O vector. To keep things simple for this example, our scatter/gather vectors always consists of a single element. */ /* Allocate the mmssghdr vector, whose size corresponds to the number of remaining command-line arguments */ vlen = argc - 3; msgvecp = calloc(vlen, sizeof(struct mmsghdr)); if (msgvecp == NULL) errExit("calloc"); for (j = 0; j < vlen; j++) { msgvecp[j].msg_hdr.msg_name = NULL; msgvecp[j].msg_hdr.msg_namelen = 0; msgvecp[j].msg_hdr.msg_control = NULL; msgvecp[j].msg_hdr.msg_controllen = 0; /* Allocate an iovec for this mmsghdr element. The vector contains just a single item. */ msgvecp[j].msg_hdr.msg_iovlen = 1; msgvecp[j].msg_hdr.msg_iov = malloc(sizeof(struct iovec)); if (msgvecp[j].msg_hdr.msg_iov == NULL) errExit("malloc"); /* The single iovec element contains a pointer to a buffer that is sized according to the number given in the corresponding command-line argument */ s = atoi(argv[j + 3]); msgvecp[j].msg_hdr.msg_iov[0].iov_len = s; msgvecp[j].msg_hdr.msg_iov[0].iov_base = malloc(s); } if (tsp != NULL) printf("Timespec before call = %ld.%09ld\n", (long) tsp->tv_sec, (long) tsp->tv_nsec); /* Now we're ready to make the recvmmsg() call */ s = recvmmsg(sfd, msgvecp, vlen, 0, tsp); if (s == -1) { if (errno == EINTR) printf("EINTR! (interrupted system call)\n"); else errExit("recvmmsg"); } printf("recvmmsg() returned %d\n", s); if (tsp != NULL) printf("Timespec after call = %ld.%09ld\n", (long) tsp->tv_sec, (long) tsp->tv_nsec); /* Display datagrams retrieved by recvmmsg() */ for (j = 0; j < s; j++) { printf("%d: %u - %.*s\n", j, msgvecp[j].msg_len, msgvecp[j].msg_len, (char *) msgvecp[j].msg_hdr.msg_iov[0].iov_base); }#ifdef SECOND_CALL ts = ts_saved; printf("About to make second recvmmsg() call\n"); if (tsp != NULL) printf("Timespec before call = %ld.%09ld\n", (long) tsp->tv_sec, (long) tsp->tv_nsec); s = recvmmsg(sfd, msgvecp, vlen, 0, tsp); if (s == -1) { if (errno == EINTR) printf("Second recvmmsg(): EINTR! (interrupted system call)\n"); else errExit("recvmmsg"); } printf("Second recvmmsg(): returned %d\n", s);#endif
exit(EXIT_SUCCESS); }And this test program can be used to send datagrams:
/*
id_sendto.c(C) 2014, Michael Kerrisk, Licensed under the GNU General Public License, version 2 or later.
*/#include <
sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>/* Create socket and connect it to the address specified by
'host' + 'service'/'type'. Return socket descriptor on success, or -1 on error */static int
inetConnect(const char *host, const char *service, int type){ struct addrinfo hints; struct addrinfo *result, *rp; int sfd, s; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; hints.ai_family = AF_UNSPEC; /* Allows IPv4 or IPv6 */ hints.ai_socktype = type; s = getaddrinfo(host, service, &hints, &result); if (s != 0) { errno = ENOSYS; return -1; } /* Walk through returned list until we find an address structure that can be used to successfully connect a socket */ for (rp = result; rp != NULL; rp = rp->ai_next) { sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sfd == -1) continue; /* On error, try next address */ if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) break; /* Success */ /* Connect failed: close this socket and try next address */ close(sfd); } freeaddrinfo(result); return (rp == NULL) ? -1 : sfd; }int
main(int argc, char *argv[]){ int sfd, j; if (argc < 3 || strcmp(argv[1], "--help") == 0) { fprintf(stderr, "Usage: %s host port msg...\n", argv[0]); exit(EXIT_FAILURE); } sfd = inetConnect(argv[1], argv[2], SOCK_DGRAM); for (j = 3; j < argc; j++) { if (send(sfd, argv[j], strlen(argv[j]), 0) != strlen(argv[j])) perror("sendto"); } exit(EXIT_SUCCESS); }Quoted 2,180 lines
- Arnaldo
commit
93d40dc3a3266d6d4ed905b9333b6809b5fe24fcAuthor: Arnaldo Carvalho de Melo <[email protected]> Date: Fri Jul 18 15:23:44 2014 -0300net: Fix recvmmsg timeout handling
As reported by Elie de Brauwer the timeout handling in the recvmmsg syscall had issues that boil down to it not properly passing the remaining time to each underlying
recvmsg()call.Fix it by adding a timeout pointer to the recvmsg implementations, so that it can use that using a variation of
sock_rcvtimeo, that overrides the value inSO_RCVTIMEOwith the timeout passed, and returns the remaining time in that pointer, this way each underlying recvmsg call receives the remaining time.It ends up in most cases being just a forward of this pointer from recvmmsg to
skb_recv_datagram().Reported-by Elie De Brauwer <[email protected]>Cc Caitlin Bestler <[email protected]>Cc Chris Friesen <[email protected]>Cc David Laight <[email protected]>Cc Elie De Brauwer <[email protected]>Cc Michael Kerrisk <[email protected]>Cc Neil Horman <[email protected]>Cc Ondřej Bílka <[email protected]>Cc Paul Moore <[email protected]>Cc Rémi Denis-Courmont <[email protected]>Cc Steven Whitehouse <[email protected]>Signed-off-by Arnaldo Carvalho de Melo <[email protected]>crypto/algif_hash.c +1
-1@@ -151,7 +151,7 @@ unlock: }static int hash_recvmsg (struct kiocb *unused,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct alg_sock *ask =alg_sk (sk);crypto/algif_skcipher.c +1
-1@@ -419,7 +419,7 @@ unlock: }static int skcipher_recvmsg (struct kiocb *unused,struct socket *sock, -struct msghdr *msg,size_t ignored,int flags) +struct msghdr *msg,size_t ignored,int flags,long *timeop) {struct sock *sk = sock->sk;struct alg_sock *ask =alg_sk (sk);drivers/isdn/mISDN/socket.c +2
-2@@ -113,7 +113,7 @@ mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)static int mISDN_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sk_buff *skb;struct sock *sk = sock->sk;@@ -130,7 +130,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (sk->sk_state ==MISDN_CLOSED )return 0 ; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);if (!skb)return err;drivers/net/macvtap.c +1
-1@@ -1111,7 +1111,7 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock,static int macvtap_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags) +int flags,long *timeop) { struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);int ret;drivers/net/ppp/pppoe.c +2
-2@@ -963,7 +963,7 @@ static const struct ppp_channel_ops pppoe_chan_ops = { };static int pppoe_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t total_len,int flags) +struct msghdr *m,size_t total_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -975,7 +975,7 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, } skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &error); + flags &MSG_DONTWAIT , &error, timeop);if (error <0 ) goto end;drivers/net/tun.c +2
-2@@ -1343,7 +1343,7 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,/* Read frames from queue */ skb =__skb_recv_datagram (tfile->socket.sk, noblock ?MSG_DONTWAIT :0 , - &peeked, &off, &err); + &peeked, &off, &err,NULL );if (skb) { ret =tun_put_user (tun, tfile, skb, iv, len);kfree_skb (skb);@@ -1452,7 +1452,7 @@ static int tun_sendmsg(struct kiocb *iocb, struct socket *sock,static int tun_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags) +int flags,long *timeop) { struct tun_file *tfile = container_of(sock, struct tun_file, socket);struct tun_struct *tun =__tun_get (tfile);drivers/vhost/net.c +2
-2@@ -602,7 +602,7 @@ static void handle_rx(struct vhost_net *net)if (unlikely (headcount >UIO_MAXIOV )) { msg.msg_iovlen =1 ; err = sock->ops->recvmsg (NULL , sock, &msg, -1 ,MSG_DONTWAIT |MSG_TRUNC ); +1 ,MSG_DONTWAIT |MSG_TRUNC ,NULL );pr_debug ("Discarded rx packet: len %zd\n" , sock_len);continue ; }@@ -628,7 +628,7 @@ static void handle_rx(struct vhost_net *net)copy_iovec_hdr (vq->iov, nvq->hdr, sock_hlen, in); msg.msg_iovlen = in; err = sock->ops->recvmsg (NULL , sock, &msg, - sock_len,MSG_DONTWAIT |MSG_TRUNC ); + sock_len,MSG_DONTWAIT |MSG_TRUNC ,NULL );/* Userspace might have consumed the packet meanwhile: * it's not supposed to do this usually, but might be hard * to prevent. Discard data we got (if any) and keep going. */ include/linux/net.h +5
-2@@ -171,10 +171,13 @@ struct proto_ops {* returning uninitialized memory to user space. The recvfrom * handlers can assume that msg.msg_name is either NULL or has * a minimum size of sizeof(struct sockaddr_storage). +* timeop contains a per call timeout (as opposed as per socket, +* used by recvmmsg, set it to NULL to disable it. It should return +* the remaining time, if not NULL. */ int (*recvmsg) (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len, -int flags); +int flags,long *timeop);int (*mmap) (struct file *file,struct socket *sock,struct vm_area_struct * vma); ssize_t (*sendpage) (struct socket *sock, struct page *page,@@ -215,7 +218,7 @@ int sock_create_lite(int family, int type, int proto, struct socket **res);void sock_release (struct socket *sock);int sock_sendmsg (struct socket *sock,struct msghdr *msg,size_t len);int sock_recvmsg (struct socket *sock,struct msghdr *msg,size_t size, -int flags); +int flags,long *timeop);struct file *sock_alloc_file (struct socket *sock,int flags,const char *dname);struct socket *sockfd_lookup (int fd,int *err);struct socket *sock_from_file (struct file *file,int *err);include/linux/skbuff.h +2
-2@@ -2513,9 +2513,9 @@ static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag)for (iter =skb_shinfo (skb)->frag_list; iter; iter = iter->next) struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, -int *peeked,int *off,int *err); +int *peeked,int *off,int *err,long *timeop);struct sk_buff *skb_recv_datagram (struct sock *sk,unsigned flags,int noblock, -int *err); +int *err,long *timeop);unsigned int datagram_poll (struct file *file,struct socket *sock,struct poll_table_struct *wait); int skb_copy_datagram_iovec(const struct sk_buff *from, int offset,include/net/af_vsock.h +1
-1@@ -101,7 +101,7 @@ struct vsock_transport {/* DGRAM. */ int (*dgram_bind)(struct vsock_sock *,struct sockaddr_vm *);int (*dgram_dequeue)(struct kiocb *kiocb,struct vsock_sock *vsk, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);int (*dgram_enqueue)(struct vsock_sock *,struct sockaddr_vm *,struct iovec *,size_t len);bool (*dgram_allow)(u32 cid,u32 port);include/net/bluetooth/bluetooth.h +2
-2@@ -246,9 +246,9 @@ void bt_sock_unregister(int proto);void bt_sock_link (struct bt_sock_list *l,struct sock *s);void bt_sock_unlink (struct bt_sock_list *l,struct sock *s);int bt_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);int bt_sock_stream_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags); +struct msghdr *msg,size_t len,int flags,long *timeop);uint bt_sock_poll (struct file *file,struct socket *sock,poll_table *wait);int bt_sock_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg);int bt_sock_wait_state (struct sock *sk,int state,unsigned long timeo);include/net/inet_common.h +1
-1@@ -26,7 +26,7 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,ssize_t inet_sendpage (struct socket *sock,struct page *page,int offset,size_t size,int flags);int inet_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags); +size_t size,int flags,long *timeop);int inet_shutdown (struct socket *sock,int how);int inet_listen (struct socket *sock,int backlog);void inet_sock_destruct (struct sock *sk);include/net/ping.h +1
-1@@ -76,7 +76,7 @@ int ping_getfrag(void *from, char *to, int offset, int fraglen, int odd, struct sk_buff *);int ping_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int ping_common_sendmsg (int family,struct msghdr *msg,size_t len,void *user_icmph,size_t icmph_len); int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,include/net/sock.h +8
-3@@ -961,7 +961,7 @@ struct proto {int (*recvmsg)(struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock,int flags, -int *addr_len); +int *addr_len,long *timeop);int (*sendpage)(struct sock *sk,struct page *page,int offset,size_t size,int flags); int (*bind)(struct sock *sk,@@ -1593,7 +1593,7 @@ int sock_no_getsockopt(struct socket *, int , int, char __user *, int __user *);int sock_no_setsockopt (struct socket *,int ,int ,char __user *,unsigned int );int sock_no_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );int sock_no_recvmsg (struct kiocb *,struct socket *,struct msghdr *,size_t , -int ); +int ,long *);int sock_no_mmap (struct file *file,struct socket *sock,struct vm_area_struct *vma); ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset,@@ -1606,7 +1606,7 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset,int sock_common_getsockopt (struct socket *sock,int level,int optname,char __user *optval,int __user *optlen);int sock_common_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags); +struct msghdr *msg,size_t size,int flags,long *timeop);int sock_common_setsockopt (struct socket *sock,int level,int optname,char __user *optval,unsigned int optlen); int compat_sock_common_getsockopt(struct socket *sock, int level,@@ -2104,6 +2104,11 @@ static inline long sock_rcvtimeo(const struct sock *sk, bool noblock)return noblock ?0 : sk->sk_rcvtimeo; } +static inline long sock_rcvtimeop (const struct sock *sk,long *timeop,bool noblock) +{ +return noblock ?0 : (timeop ? *timeop : sk->sk_rcvtimeo); +} +static inline long sock_sndtimeo (const struct sock *sk,bool noblock) {return noblock ?0 : sk->sk_sndtimeo;include/net/tcp.h +1
-1@@ -437,7 +437,7 @@ int compat_tcp_setsockopt(struct sock *sk, int level, int optname,void tcp_set_keepalive (struct sock *sk,int val);void tcp_syn_ack_timeout (struct sock *sk,struct request_sock *req);int tcp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len); +size_t len,int nonblock,int flags,int *addr_len,long *timeop);void tcp_parse_options (const struct sk_buff *skb,struct tcp_options_received *opt_rx,int estab,struct tcp_fastopen_cookie *foc);net/appletalk/ddp.c +2
-2@@ -1729,7 +1729,7 @@ out: }static int atalk_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct ddpehdr *ddp;@@ -1739,7 +1739,7 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdrstruct sk_buff *skb; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);lock_sock (sk);if (!skb)net/atm/common.c +2
-2@@ -524,7 +524,7 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci) }int vcc_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct atm_vcc *vcc;@@ -544,7 +544,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, !test_bit(ATM_VF_READY, &vcc->flags))return 0 ; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &error); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &error, timeop);if (!skb)return error;net/atm/common.h +1
-1@@ -14,7 +14,7 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family);int vcc_release (struct socket *sock);int vcc_connect (struct socket *sock,int itf,short vpi,int vci);int vcc_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags); +size_t size,int flags,long *timeop);int vcc_sendmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m,size_t total_len);unsigned int vcc_poll (struct file *file,struct socket *sock,poll_table *wait);net/ax25/af_ax25.c +2
-2@@ -1600,7 +1600,7 @@ out: }static int ax25_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -1619,7 +1619,7 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,/* Now we can treat all alike */ skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (skb ==NULL ) goto out;net/bluetooth/af_bluetooth.c +6
-4@@ -209,7 +209,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)EXPORT_SYMBOL (bt_accept_dequeue);int bt_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -222,7 +222,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (flags & (MSG_OOB ))return -EOPNOTSUPP ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {if (sk->sk_shutdown &RCV_SHUTDOWN )return 0 ;@@ -282,7 +282,7 @@ static long bt_sock_data_wait(struct sock *sk, long timeo) }int bt_sock_stream_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int err =0 ;@@ -297,7 +297,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,lock_sock (sk); target =sock_rcvlowat (sk, flags &MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); do { struct sk_buff *skb;@@ -381,6 +381,8 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, }while (size); out: +if (timeop) + *timeop = timeo;release_sock (sk);return copied ? : err; }net/bluetooth/hci_sock.c +2
-2@@ -829,7 +829,7 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, }static int hci_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -844,7 +844,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (sk->sk_state ==BT_CLOSED )return 0 ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb)return err;net/bluetooth/l2cap_sock.c +3
-3@@ -971,7 +971,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int l2cap_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct l2cap_pinfo *pi =l2cap_pi (sk);@@ -998,9 +998,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (sk);if (sock->type ==SOCK_STREAM ) - err =bt_sock_stream_recvmsg (iocb, sock, msg, len, flags); + err =bt_sock_stream_recvmsg (iocb, sock, msg, len, flags, timeop);else - err =bt_sock_recvmsg (iocb, sock, msg, len, flags); + err =bt_sock_recvmsg (iocb, sock, msg, len, flags, timeop);if (pi->chan->mode !=L2CAP_MODE_ERTM )return err;net/bluetooth/rfcomm/sock.c +2
-2@@ -617,7 +617,7 @@ done: }static int rfcomm_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct rfcomm_dlc *d =rfcomm_pi (sk)->dlc;@@ -628,7 +628,7 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,return 0 ; } - len =bt_sock_stream_recvmsg (iocb, sock, msg, size, flags); + len =bt_sock_stream_recvmsg (iocb, sock, msg, size, flags, timeop);lock_sock (sk);if (!(flags &MSG_PEEK ) && len >0 )net/bluetooth/sco.c +2
-2@@ -700,7 +700,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting) }static int sco_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sco_pinfo *pi =sco_pi (sk);@@ -718,7 +718,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (sk); -return bt_sock_recvmsg (iocb, sock, msg, len, flags); +return bt_sock_recvmsg (iocb, sock, msg, len, flags, timeop); }static int sco_sock_setsockopt (struct socket *sock,int level,int optname,char __user *optval,unsigned int optlen)net/caif/caif_socket.c +6
-4@@ -272,7 +272,7 @@ static void caif_check_flow_release(struct sock *sk)* changed locking, address handling and added MSG_TRUNC. */ static int caif_seqpkt_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t len,int flags) +struct msghdr *m,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;@@ -284,7 +284,7 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,if (m->msg_flags&MSG_OOB ) goto read_error; - skb =skb_recv_datagram (sk, flags,0 , &ret); + skb =skb_recv_datagram (sk, flags,0 , &ret, timeop);if (!skb) goto read_error; copylen = skb->len;@@ -345,7 +345,7 @@ static long caif_stream_data_wait(struct sock *sk, long timeo)*/ static int caif_stream_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;int copied =0 ;@@ -367,7 +367,7 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,caif_read_lock (sk); target =sock_rcvlowat (sk, flags&MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, flags&MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags&MSG_DONTWAIT ); do { int chunk;@@ -450,6 +450,8 @@ unlock:caif_read_unlock (sk); out: +if (timeop) + *timeop = timeo;return copied ? : err; }net/can/bcm.c +2
-2@@ -1541,7 +1541,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, }static int bcm_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -1551,7 +1551,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock, noblock = flags &MSG_DONTWAIT ; flags &= ~MSG_DONTWAIT ; - skb =skb_recv_datagram (sk, flags, noblock, &error); + skb =skb_recv_datagram (sk, flags, noblock, &error, timeop);if (!skb)return error;net/can/raw.c +2
-2@@ -731,7 +731,7 @@ send_failed: }static int raw_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -741,7 +741,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, noblock = flags &MSG_DONTWAIT ; flags &= ~MSG_DONTWAIT ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb)return err;net/core/datagram.c +13
-6@@ -138,6 +138,9 @@ out_noerr:* @off: an offset in bytes to peek skb from. Returns an offset * within an skb where data actually starts * @err: error code returned +* @timeop: per call timeout (as opposed as per socket via SO_RCVTIMEO), +* will return the remaining time, used in recvmmsg, ignored +* if set to NULL. * * Get a datagram skbuff, understands the peeking, nonblocking wakeups * and possible races. This replaces identical code in packet, raw and @@ -162,7 +165,7 @@ out_noerr:* the standard around please. */ struct sk_buff *__skb_recv_datagram (struct sock *sk,unsigned int flags, -int *peeked,int *off,int *err) +int *peeked,int *off,int *err,long *timeop) {struct sk_buff *skb, *last;long timeo;@@ -174,7 +177,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,if (error) goto no_packet; - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); do { /* Again only user level code calls this function, so nothing@@ -205,6 +208,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,spin_unlock_irqrestore (&queue->lock, cpu_flags); *off = _off; +if (timeop) + *timeop = timeo;return skb; }spin_unlock_irqrestore (&queue->lock, cpu_flags);@@ -219,22 +224,24 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, goto no_packet; }while (!wait_for_more_packets (sk, err, &timeo, last)); - +out: +if (timeop) + *timeop = timeo;return NULL ; no_packet: *err = error; -return NULL ; + goto out; }EXPORT_SYMBOL (__skb_recv_datagram);struct sk_buff *skb_recv_datagram (struct sock *sk,unsigned int flags, -int noblock,int *err) +int noblock,int *err,long *timeop) {int peeked, off =0 ;return __skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, err); + &peeked, &off, err, timeop); }EXPORT_SYMBOL (skb_recv_datagram);net/core/sock.c +3
-3@@ -2191,7 +2191,7 @@ int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,EXPORT_SYMBOL (sock_no_sendmsg);int sock_no_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *m, -size_t len,int flags) +size_t len,int flags,long *timeop) {return -EOPNOTSUPP ; }@@ -2577,14 +2577,14 @@ EXPORT_SYMBOL(compat_sock_common_getsockopt);#endif int sock_common_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int addr_len =0 ;int err; err = sk->sk_prot->recvmsg (iocb, sk, msg, size, flags &MSG_DONTWAIT , - flags & ~MSG_DONTWAIT , &addr_len); + flags & ~MSG_DONTWAIT , &addr_len, timeop);if (err >=0 ) msg->msg_namelen = addr_len;return err;net/dccp/dccp.h +1
-1@@ -314,7 +314,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size);int dccp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int nonblock,int flags, -int *addr_len); +int *addr_len,long *timeop);void dccp_shutdown (struct sock *sk,int how);int inet_dccp_listen (struct socket *sock,int backlog); unsigned int dccp_poll(struct file *file, struct socket *sock,net/dccp/proto.c +4
-2@@ -808,7 +808,7 @@ out_discard:EXPORT_SYMBOL_GPL (dccp_sendmsg);int dccp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len) +size_t len,int nonblock,int flags,int *addr_len,long *timeop) {const struct dccp_hdr *dh;long timeo;@@ -820,7 +820,7 @@ int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out; } - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock); do { struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);@@ -910,6 +910,8 @@ verify_sock_status: }while (1 ); out:release_sock (sk); +if (timeop) + *timeop = timeo;return len; }net/decnet/af_decnet.c +4
-3@@ -1669,7 +1669,7 @@ static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, intstatic int dn_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct dn_scp *scp =DN_SK (sk);@@ -1680,7 +1680,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,struct sk_buff *skb, *n;struct dn_skb_cb *cb =NULL ;unsigned char eor =0 ; -long timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); +long timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT );lock_sock (sk);@@ -1814,7 +1814,8 @@ out: }release_sock (sk); - +if (timeop) + *timeop = timeo;return rv; }net/ieee802154/dgram.c +2
-2@@ -305,14 +305,14 @@ out:static int dgram_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock,int flags, -int *addr_len) +int *addr_len,long *timeop) {size_t copied =0 ;int err = -EOPNOTSUPP ;struct sk_buff *skb; DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ieee802154/raw.c +2
-2@@ -179,13 +179,13 @@ out: }static int raw_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {size_t copied =0 ;int err = -EOPNOTSUPP ;struct sk_buff *skb; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ipv4/af_inet.c +2
-2@@ -757,7 +757,7 @@ ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,EXPORT_SYMBOL (inet_sendpage);int inet_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;int addr_len =0 ;@@ -766,7 +766,7 @@ int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,sock_rps_record_flow (sk); err = sk->sk_prot->recvmsg (iocb, sk, msg, size, flags &MSG_DONTWAIT , - flags & ~MSG_DONTWAIT , &addr_len); + flags & ~MSG_DONTWAIT , &addr_len, timeop);if (err >=0 ) msg->msg_namelen = addr_len;return err;net/ipv4/ping.c +2
-2@@ -840,7 +840,7 @@ do_confirm: }int ping_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *isk =inet_sk (sk);int family = sk->sk_family;@@ -864,7 +864,7 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ipv4/raw.c +2
-2@@ -685,7 +685,7 @@ out: return ret;*/ static int raw_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk);size_t copied =0 ;@@ -701,7 +701,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out; } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ipv4/tcp.c +7
-9@@ -1602,7 +1602,7 @@ EXPORT_SYMBOL(tcp_read_sock);*/ int tcp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int nonblock,int flags,int *addr_len) +size_t len,int nonblock,int flags,int *addr_len,long *timeop) {struct tcp_sock *tp =tcp_sk (sk);int copied =0 ;@@ -1627,7 +1627,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,if (sk->sk_state ==TCP_LISTEN ) goto out; - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock);/* Urgent data needs to be handled specially. */ if (flags &MSG_OOB )@@ -1994,20 +1994,18 @@ skip_copy:/* Clean up data we have read: This will do ACK frames. */ tcp_cleanup_rbuf (sk, copied); - -release_sock (sk); -return copied; - out:release_sock (sk); -return err; +if (timeop) + *timeop = timeo; +return copied; recv_urg: - err =tcp_recv_urg (sk, msg, len, flags); + copied =tcp_recv_urg (sk, msg, len, flags); goto out; recv_sndq: - err =tcp_peek_sndq (sk, msg, len); + copied =tcp_peek_sndq (sk, msg, len); goto out; }EXPORT_SYMBOL (tcp_recvmsg);net/ipv4/udp.c +2
-2@@ -1262,7 +1262,7 @@ EXPORT_SYMBOL(udp_ioctl);*/ int udp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk); DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);@@ -1278,7 +1278,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, try_again: skb =__skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, &err); + &peeked, &off, &err, timeop);if (!skb) goto out;net/ipv4/udp_impl.h +1
-1@@ -22,7 +22,7 @@ int compat_udp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);#endif int udp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int udp_sendpage (struct sock *sk,struct page *page,int offset,size_t size,int flags);int udp_queue_rcv_skb (struct sock *sk,struct sk_buff *skb);net/ipv6/raw.c +2
-2@@ -458,7 +458,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)static int rawv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len, -int noblock,int flags,int *addr_len) +int noblock,int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk); DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);@@ -475,7 +475,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,if (np->rxpmtu && np->rxopt.bits.rxpmtu)return ipv6_recv_rxpmtu (sk, msg, len, addr_len); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/ipv6/udp.c +2
-2@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(udp6_lib_lookup);int udpv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len, -int noblock,int flags,int *addr_len) +int noblock,int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk);struct inet_sock *inet =inet_sk (sk);@@ -400,7 +400,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, try_again: skb =__skb_recv_datagram (sk, flags | (noblock ?MSG_DONTWAIT :0 ), - &peeked, &off, &err); + &peeked, &off, &err, timeop);if (!skb) goto out;net/ipv6/udp_impl.h +1
-1@@ -26,7 +26,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,int udpv6_sendmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len);int udpv6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len); +size_t len,int noblock,int flags,int *addr_len,long *timeop);int udpv6_queue_rcv_skb (struct sock *sk,struct sk_buff *skb);void udpv6_destroy_sock (struct sock *sk);net/ipx/af_ipx.c +2
-2@@ -1756,7 +1756,7 @@ out:static int ipx_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct ipx_sock *ipxs =ipx_sk (sk);@@ -1791,7 +1791,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &rc); + flags &MSG_DONTWAIT , &rc, timeop);if (!skb) {if (rc == -EAGAIN && (sk->sk_shutdown &RCV_SHUTDOWN )) rc =0 ;net/irda/af_irda.c +10
-6@@ -1373,7 +1373,7 @@ out:* after being read, regardless of how much the user actually read */ static int irda_recvmsg_dgram (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct irda_sock *self =irda_sk (sk);@@ -1384,7 +1384,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,IRDA_DEBUG (4 ,"%s()\n" , __func__); skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (!skb)return err;@@ -1422,7 +1422,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,* Function irda_recvmsg_stream (iocb, sock, msg, size, flags) */ static int irda_recvmsg_stream (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct irda_sock *self =irda_sk (sk);@@ -1445,7 +1445,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, err =0 ; target =sock_rcvlowat (sk, flags &MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, noblock); + timeo =sock_rcvtimeop (sk, timeop, noblock); do { int chunk;@@ -1480,8 +1480,10 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,finish_wait (sk_sleep (sk), &wait); -if (err) -return err; +if (err) { + copied = err; +break ; + }if (sk->sk_shutdown &RCV_SHUTDOWN )break ;@@ -1534,6 +1536,8 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, } } +if (timeop) + *timeop = timeo;return copied; }net/iucv/af_iucv.c +2
-2@@ -1321,7 +1321,7 @@ static void iucv_process_message_q(struct sock *sk) }static int iucv_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -1342,7 +1342,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,/* receive/dequeue next skb: * the function understands MSG_PEEK and, thus, does not dequeue skb */ - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {if (sk->sk_shutdown &RCV_SHUTDOWN )return 0 ;net/key/af_key.c +2
-2@@ -3635,7 +3635,7 @@ out:static int pfkey_recvmsg (struct kiocb *kiocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;struct pfkey_sock *pfk =pfkey_sk (sk);@@ -3646,7 +3646,7 @@ static int pfkey_recvmsg(struct kiocb *kiocb,if (flags & ~(MSG_PEEK |MSG_DONTWAIT |MSG_TRUNC |MSG_CMSG_COMPAT )) goto out; - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);if (skb ==NULL ) goto out;net/l2tp/l2tp_ip.c +2
-2@@ -507,7 +507,7 @@ no_route: }static int l2tp_ip_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg, -size_t len,int noblock,int flags,int *addr_len) +size_t len,int noblock,int flags,int *addr_len,long *timeop) {struct inet_sock *inet =inet_sk (sk);size_t copied =0 ;@@ -518,7 +518,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *mif (flags &MSG_OOB ) goto out; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/l2tp/l2tp_ip6.c +2
-2@@ -645,7 +645,7 @@ do_confirm:static int l2tp_ip6_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct ipv6_pinfo *np =inet6_sk (sk); DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);@@ -662,7 +662,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,if (flags &MSG_ERRQUEUE )return ipv6_recv_error (sk, msg, len, addr_len); - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;net/l2tp/l2tp_ppp.c +2
-2@@ -187,7 +187,7 @@ static int pppol2tp_recv_payload_hook(struct sk_buff *skb)*/ static int pppol2tp_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {int err;struct sk_buff *skb;@@ -199,7 +199,7 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, err =0 ; skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &err); + flags &MSG_DONTWAIT , &err, timeop);if (!skb) goto end;net/llc/af_llc.c +4
-2@@ -705,7 +705,7 @@ out:* Returns non-negative upon success, negative otherwise. */ static int llc_ui_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) { DECLARE_SOCKADDR(struct sockaddr_llc *, uaddr, msg->msg_name);const int nonblock = flags &MSG_DONTWAIT ;@@ -725,7 +725,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,if (unlikely (sk->sk_type ==SOCK_STREAM && sk->sk_state ==TCP_LISTEN )) goto out; - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock); seq = &llc->copied_seq;if (flags &MSG_PEEK ) {@@ -851,6 +851,8 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, out:release_sock (sk); +if (timeop) + *timeop = timeo;return copied; copy_uaddr:if (uaddr !=NULL && skb !=NULL ) {net/netlink/af_netlink.c +2
-2@@ -2404,7 +2404,7 @@ out:static int netlink_recvmsg (struct kiocb *kiocb,struct socket *sock,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (kiocb);struct scm_cookie scm;@@ -2420,7 +2420,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, copied =0 ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (skb ==NULL ) goto out;net/netrom/af_netrom.c +2
-2@@ -1134,7 +1134,7 @@ out: }static int nr_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk; DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);@@ -1154,7 +1154,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, }/* Now we can treat all alike */ -if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er)) ==NULL ) { +if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er, timeop)) ==NULL ) {release_sock (sk);return er; }net/nfc/llcp_sock.c +2
-2@@ -794,7 +794,7 @@ static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int llcp_sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -817,7 +817,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,if (flags & (MSG_OOB ))return -EOPNOTSUPP ; - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) {pr_err ("Recv datagram failed state %d %d %d" , sk->sk_state, err,sock_error (sk));net/nfc/rawsock.c +2
-2@@ -249,7 +249,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, }static int rawsock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {int noblock = flags &MSG_DONTWAIT ;struct sock *sk = sock->sk;@@ -259,7 +259,7 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,pr_debug ("sock=%p sk=%p len=%zu flags=%d\n" , sock, sk, len, flags); - skb =skb_recv_datagram (sk, flags, noblock, &rc); + skb =skb_recv_datagram (sk, flags, noblock, &rc, timeop);if (!skb)return rc;net/packet/af_packet.c +2
-2@@ -2852,7 +2852,7 @@ out:*/ static int packet_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk = sock->sk;struct sk_buff *skb;@@ -2884,7 +2884,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,* but then it will block. */ - skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err); + skb =skb_recv_datagram (sk, flags, flags &MSG_DONTWAIT , &err, timeop);/* * An error occurred so return it. Because skb_recv_datagram() net/phonet/datagram.c +2
-2@@ -127,7 +127,7 @@ static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,static int pn_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sk_buff *skb =NULL ;struct sockaddr_pn sa;@@ -138,7 +138,7 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, MSG_CMSG_COMPAT)) goto out_nofree; - skb =skb_recv_datagram (sk, flags, noblock, &rval); + skb =skb_recv_datagram (sk, flags, noblock, &rval, timeop);if (skb ==NULL ) goto out_nofree;net/phonet/pep.c +3
-3@@ -783,7 +783,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)u8 pipe_handle, enabled, n_sb;u8 aligned =0 ; - skb =skb_recv_datagram (sk,0 , flags &O_NONBLOCK , errp); + skb =skb_recv_datagram (sk,0 , flags &O_NONBLOCK , errp,NULL );if (!skb)return NULL ;@@ -1248,7 +1248,7 @@ struct sk_buff *pep_read(struct sock *sk)static int pep_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sk_buff *skb;int err;@@ -1277,7 +1277,7 @@ static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,return -EINVAL ; } - skb =skb_recv_datagram (sk, flags, noblock, &err); + skb =skb_recv_datagram (sk, flags, noblock, &err, timeop);lock_sock (sk);if (skb ==NULL ) {if (err == -ENOTCONN && sk->sk_state ==TCP_CLOSE_WAIT )net/rds/rds.h +1
-1@@ -706,7 +706,7 @@ void rds_inc_put(struct rds_incoming *inc);void rds_recv_incoming (struct rds_connection *conn,__be32 saddr,__be32 daddr,struct rds_incoming *inc,gfp_t gfp);int rds_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int msg_flags); +size_t size,int msg_flags,long *timeop);void rds_clear_recv_queue (struct rds_sock *rs);int rds_notify_queue_get (struct rds_sock *rs,struct msghdr *msg); void rds_inc_info_copy(struct rds_incoming *inc,net/rds/recv.c +4
-2@@ -396,7 +396,7 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg) }int rds_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg, -size_t size,int msg_flags) +size_t size,int msg_flags,long *timeop) {struct sock *sk = sock->sk;struct rds_sock *rs =rds_sk_to_rs (sk);@@ -406,7 +406,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,struct rds_incoming *inc =NULL ;/* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ - timeo =sock_rcvtimeo (sk, nonblock); + timeo =sock_rcvtimeop (sk, timeop, nonblock);rdsdebug ("size %zu flags 0x%x timeo %ld\n" , size, msg_flags, timeo);@@ -493,6 +493,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,rds_inc_put (inc); out: +if (timeop) + *timeop = timeo;return ret; }net/rose/af_rose.c +2
-2@@ -1212,7 +1212,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,static int rose_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock *sk = sock->sk;struct rose_sock *rose =rose_sk (sk);@@ -1229,7 +1229,7 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,return -ENOTCONN ;/* Now we can treat all alike */ -if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er)) ==NULL ) +if ((skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &er, timeop)) ==NULL )return er; qbit = (skb->data[0 ] &ROSE_Q_BIT ) ==ROSE_Q_BIT ;net/rxrpc/ar-input.c +1
-1@@ -655,7 +655,7 @@ void rxrpc_data_ready(struct sock *sk)return ; } - skb =skb_recv_datagram (sk,0 ,1 , &ret); + skb =skb_recv_datagram (sk,0 ,1 , &ret,NULL );if (!skb) {rxrpc_put_local (local);if (ret == -EAGAIN )net/rxrpc/ar-internal.h +1
-1@@ -573,7 +573,7 @@ extern const struct file_operations rxrpc_connection_seq_fops;*/ void rxrpc_remove_user_ID (struct rxrpc_sock *,struct rxrpc_call *);int rxrpc_recvmsg (struct kiocb *,struct socket *,struct msghdr *,size_t , -int ); +int ,long *);/* * ar-security.c net/rxrpc/ar-recvmsg.c +13
-8@@ -44,7 +44,7 @@ void rxrpc_remove_user_ID(struct rxrpc_sock *rx, struct rxrpc_call *call)* simultaneously */ int rxrpc_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct rxrpc_skb_priv *sp;struct rxrpc_call *call =NULL , *continue_call =NULL ;@@ -63,7 +63,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, ullen = msg->msg_flags &MSG_CMSG_COMPAT ?4 :sizeof (unsigned long ); - timeo =sock_rcvtimeo (&rx->sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (&rx->sk, timeop, flags &MSG_DONTWAIT ); msg->msg_flags |=MSG_MORE ;lock_sock (&rx->sk);@@ -78,7 +78,8 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (&rx->sk);if (continue_call)rxrpc_put_call (continue_call); -return -ENODATA ; + copied = -ENODATA ; + goto out_copied; } }@@ -135,7 +136,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,release_sock (&rx->sk);rxrpc_put_call (continue_call);_leave (" = %d [noncont]" , copied); -return copied; + goto out_copied; } }@@ -252,6 +253,9 @@ out:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d [data]" , copied); +out_copied: +if (timeop) + *timeop = timeo;return copied;/* handle non-DATA messages such as aborts, incoming connections and @@ -328,7 +332,8 @@ terminal_message:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d" , ret); -return ret; + copied = ret; + goto out_copied; copy_error:_debug ("copy error" );@@ -337,7 +342,8 @@ copy_error:if (continue_call)rxrpc_put_call (continue_call);_leave (" = %d" , ret); -return ret; + copied = ret; + goto out_copied; wait_interrupted: ret =sock_intr_errno (timeo);@@ -348,8 +354,7 @@ wait_error:if (copied) copied = ret;_leave (" = %d [waitfail %d]" , copied, ret); -return copied; - + goto out_copied; }/** net/sctp/socket.c +12
-8@@ -2042,11 +2042,11 @@ static int sctp_skb_pull(struct sk_buff *skb, int len)* flags - flags sent or received with the user message, see Section * 5 for complete description of the flags. */ -static struct sk_buff *sctp_skb_recv_datagram (struct sock *,int ,int ,int *); +static struct sk_buff *sctp_skb_recv_datagram (struct sock *,int ,int ,int *,long *);static int sctp_recvmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len,int noblock, -int flags,int *addr_len) +int flags,int *addr_len,long *timeop) {struct sctp_ulpevent *event =NULL ;struct sctp_sock *sp =sctp_sk (sk);@@ -2066,7 +2066,7 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, goto out; } - skb =sctp_skb_recv_datagram (sk, flags, noblock, &err); + skb =sctp_skb_recv_datagram (sk, flags, noblock, &err, timeop);if (!skb) goto out;@@ -6519,13 +6519,13 @@ out:* with a few changes to make lksctp work. */ static struct sk_buff *sctp_skb_recv_datagram (struct sock *sk,int flags, -int noblock,int *err) +int noblock,int *err,long *timeop) {int error;struct sk_buff *skb;long timeo; - timeo =sock_rcvtimeo (sk, noblock); + timeo =sock_rcvtimeop (sk, timeop, noblock);pr_debug ("%s: timeo:%ld, max:%ld\n" , __func__, timeo,MAX_SCHEDULE_TIMEOUT );@@ -6549,7 +6549,7 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, }if (skb) -return skb; +break ;/* Caller is allowed not to check sk->sk_err before calling. */ error =sock_error (sk);@@ -6569,11 +6569,15 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, goto no_packet; }while (sctp_wait_for_packet (sk, err, &timeo) ==0 ); -return NULL ; +out: +if (timeop) + *timeop = timeo; + +return skb; no_packet: *err = error; -return NULL ; + goto out; }/* If sndbuf has changed, wake up per association sndbuf waiters. */ net/socket.c +56
-31@@ -772,7 +772,7 @@ void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,EXPORT_SYMBOL_GPL (__sock_recv_ts_and_drops);static inline int __sock_recvmsg_nosec (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {struct sock_iocb *si =kiocb_to_siocb (iocb);@@ -782,19 +782,19 @@ static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, si->size = size; si->flags = flags; -return sock->ops->recvmsg (iocb, sock, msg, size, flags); +return sock->ops->recvmsg (iocb, sock, msg, size, flags, timeop); }static inline int __sock_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *msg,size_t size,int flags) +struct msghdr *msg,size_t size,int flags,long *timeop) {int err =security_socket_recvmsg (sock, msg, size, flags); -return err ?:__sock_recvmsg_nosec (iocb, sock, msg, size, flags); +return err ?:__sock_recvmsg_nosec (iocb, sock, msg, size, flags, timeop); }int sock_recvmsg (struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct kiocb iocb;struct sock_iocb siocb;@@ -802,7 +802,7 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg,init_sync_kiocb (&iocb,NULL ); iocb.private = &siocb; - ret =__sock_recvmsg (&iocb, sock, msg, size, flags); + ret =__sock_recvmsg (&iocb, sock, msg, size, flags, timeop);if (-EIOCBQUEUED == ret) ret =wait_on_sync_kiocb (&iocb);return ret;@@ -810,7 +810,7 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg,EXPORT_SYMBOL (sock_recvmsg);static int sock_recvmsg_nosec (struct socket *sock,struct msghdr *msg, -size_t size,int flags) +size_t size,int flags,long *timeop) {struct kiocb iocb;struct sock_iocb siocb;@@ -818,7 +818,7 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,init_sync_kiocb (&iocb,NULL ); iocb.private = &siocb; - ret =__sock_recvmsg_nosec (&iocb, sock, msg, size, flags); + ret =__sock_recvmsg_nosec (&iocb, sock, msg, size, flags, timeop);if (-EIOCBQUEUED == ret) ret =wait_on_sync_kiocb (&iocb);return ret;@@ -851,7 +851,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg,* iovec are identical, yielding the same in-core layout and alignment */ msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num; - result =sock_recvmsg (sock, msg, size, flags); + result =sock_recvmsg (sock, msg, size, flags,NULL );set_fs (oldfs);return result; }@@ -914,7 +914,7 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, msg->msg_iovlen = nr_segs; msg->msg_flags = (file->f_flags &O_NONBLOCK ) ?MSG_DONTWAIT :0 ; -return __sock_recvmsg (iocb, sock, msg, size, msg->msg_flags); +return __sock_recvmsg (iocb, sock, msg, size, msg->msg_flags,NULL ); } static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,@@ -1862,7 +1862,7 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, msg.msg_namelen =0 ;if (sock->file->f_flags &O_NONBLOCK ) flags |=MSG_DONTWAIT ; - err =sock_recvmsg (sock, &msg, size, flags); + err =sock_recvmsg (sock, &msg, size, flags,NULL );if (err >=0 && addr !=NULL ) { err2 = move_addr_to_user(&address,@@ -2207,7 +2207,7 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, }static int ___sys_recvmsg (struct socket *sock,struct msghdr __user *msg, -struct msghdr *msg_sys,unsigned int flags,int nosec) +struct msghdr *msg_sys,unsigned int flags,int nosec,long *timeop) {struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg;@@ -2265,7 +2265,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,if (sock->file->f_flags &O_NONBLOCK ) flags |=MSG_DONTWAIT ; err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, - total_len, flags); + total_len, flags, timeop);if (err <0 ) goto out_freeiov; len = err;@@ -2312,7 +2312,7 @@ long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags)if (!sock) goto out; - err =___sys_recvmsg (sock, msg, &msg_sys, flags,0 ); + err =___sys_recvmsg (sock, msg, &msg_sys, flags,0 ,NULL );fput_light (sock->file, fput_needed); out:@@ -2327,6 +2327,30 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,return __sys_recvmsg (fd, msg, flags); } +static int sock_set_timeout_ts (long *timeo_p,struct timespec *ts) +{ +if (ts->tv_nsec <0 || ts->tv_nsec >=NSEC_PER_SEC ) +return -EDOM ; + +if (ts->tv_sec <0 ) { +static int warned__read_mostly ; + + *timeo_p =0 ; +if (warned <10 &&net_ratelimit ()) { + warned++; +pr_info ("%s: `%s' (pid %d) tries to set negative timeout\n" , + __func__, current->comm,task_pid_nr (current)); + } +return 0 ; + } + *timeo_p =MAX_SCHEDULE_TIMEOUT ; +if (ts->tv_sec ==0 && ts->tv_nsec ==0 ) +return 0 ; +if (ts->tv_sec < (MAX_SCHEDULE_TIMEOUT /HZ -1 )) + *timeo_p = ts->tv_sec *HZ + (ts->tv_nsec + (NSEC_PER_SEC /HZ -1 )) / (NSEC_PER_SEC /HZ ); +return 0 ; +} +/* * Linux recvmmsg interface */ @@ -2339,12 +2363,14 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,struct mmsghdr __user *entry;struct compat_mmsghdr __user *compat_entry;struct msghdr msg_sys; -struct timespec end_time; +long timeout_hz, *timeop =NULL ; -if (timeout && -poll_select_set_timeout (&end_time, timeout->tv_sec, - timeout->tv_nsec)) -return -EINVAL ; +if (timeout) { + err =sock_set_timeout_ts (&timeout_hz, timeout); +if (err) +return err; + timeop = &timeout_hz; + } datagrams =0 ;@@ -2366,7 +2392,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,if (MSG_CMSG_COMPAT & flags) { err =___sys_recvmsg (sock, (struct msghdr __user *)compat_entry, &msg_sys, flags & ~MSG_WAITFORONE , - datagrams); + datagrams, timeop);if (err <0 )break ; err =__put_user (err, &compat_entry->msg_len);@@ -2375,7 +2401,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, err =___sys_recvmsg (sock, (struct msghdr __user *)entry, &msg_sys, flags & ~MSG_WAITFORONE , - datagrams); + datagrams, timeop);if (err <0 )break ; err =put_user (err, &entry->msg_len);@@ -2390,17 +2416,11 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,if (flags &MSG_WAITFORONE ) flags |=MSG_DONTWAIT ; -if (timeout) { -ktime_get_ts (timeout); - *timeout =timespec_sub (end_time, *timeout); -if (timeout->tv_sec <0 ) { - timeout->tv_sec = timeout->tv_nsec =0 ; -break ; - } - +if (timeout && timeout_hz ==0 ) {/* Timeout, return less than vlen datagrams */ -if (timeout->tv_nsec ==0 && timeout->tv_sec ==0 ) -break ; + timeout->tv_sec = timeout->tv_nsec =0 ; + timeop =NULL ; +break ; }/* Out of band data, return right away */ @@ -2411,6 +2431,11 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, out_put:fput_light (sock->file, fput_needed); +if (timeop) { + timeout->tv_sec = timeout_hz /HZ ; + timeout->tv_nsec = (timeout_hz %HZ ) * (NSEC_PER_SEC /HZ ); + } +if (err ==0 )return datagrams;net/sunrpc/svcsock.c +1
-1@@ -551,7 +551,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) err =kernel_recvmsg (svsk->sk_sock, &msg,NULL ,0 ,0 ,MSG_PEEK |MSG_DONTWAIT );if (err >=0 ) - skb =skb_recv_datagram (svsk->sk_sk,0 ,1 , &err); + skb =skb_recv_datagram (svsk->sk_sk,0 ,1 , &err,NULL );if (skb ==NULL ) {if (err != -EAGAIN ) {net/sunrpc/xprtsock.c +2
-2@@ -965,7 +965,7 @@ static void xs_local_data_ready(struct sock *sk)if (xprt ==NULL ) goto out; - skb =skb_recv_datagram (sk,0 ,1 , &err); + skb =skb_recv_datagram (sk,0 ,1 , &err,NULL );if (skb ==NULL ) goto out;@@ -1027,7 +1027,7 @@ static void xs_udp_data_ready(struct sock *sk)if (!(xprt =xprt_from_sock (sk))) goto out; -if ((skb =skb_recv_datagram (sk,0 ,1 , &err)) ==NULL ) +if ((skb =skb_recv_datagram (sk,0 ,1 , &err,NULL )) ==NULL ) goto out; repsize = skb->len -sizeof (struct udphdr );net/tipc/socket.c +5
-3@@ -1031,7 +1031,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)* Returns size of returned message data, errno otherwise */ static int tipc_recvmsg (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t buf_len,int flags) +struct msghdr *m,size_t buf_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct tipc_sock *tsk =tipc_sk (sk);@@ -1054,7 +1054,7 @@ static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock, goto exit; } - timeo =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); + timeo =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT ); restart:/* Look for a message in receive queue; wait if necessary */ @@ -1109,6 +1109,8 @@ restart:advance_rx_queue (sk); } exit: +if (timeop) + *timeop = timeo;release_sock (sk);return res; }@@ -1126,7 +1128,7 @@ exit:* Returns size of returned message data, errno otherwise */ static int tipc_recv_stream (struct kiocb *iocb,struct socket *sock, -struct msghdr *m,size_t buf_len,int flags) +struct msghdr *m,size_t buf_len,int flags,long *timeop) {struct sock *sk = sock->sk;struct tipc_sock *tsk =tipc_sk (sk);net/unix/af_unix.c +12
-11@@ -519,17 +519,17 @@ static int unix_shutdown(struct socket *, int);static int unix_stream_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_stream_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_dgram_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_dgram_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_dgram_connect (struct socket *,struct sockaddr *,int ,int );static int unix_seqpacket_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t );static int unix_seqpacket_recvmsg (struct kiocb *,struct socket *, -struct msghdr *,size_t ,int ); +struct msghdr *,size_t ,int ,long *);static int unix_set_peek_off (struct sock *sk,int val) {@@ -1283,7 +1283,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)* so that no locks are necessary. */ - skb =skb_recv_datagram (sk,0 , flags&O_NONBLOCK , &err); + skb =skb_recv_datagram (sk,0 , flags&O_NONBLOCK , &err,NULL );if (!skb) {/* This means receive shutdown. */ if (err ==0 )@@ -1755,14 +1755,14 @@ static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock,static int unix_seqpacket_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;if (sk->sk_state !=TCP_ESTABLISHED )return -ENOTCONN ; -return unix_dgram_recvmsg (iocb, sock, msg, size, flags); +return unix_dgram_recvmsg (iocb, sock, msg, size, flags, timeop); }static void unix_copy_addr (struct msghdr *msg,struct sock *sk)@@ -1777,7 +1777,7 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)static int unix_dgram_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (iocb);struct scm_cookie tmp_scm;@@ -1803,7 +1803,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, skip =sk_peek_offset (sk, flags); - skb =__skb_recv_datagram (sk, flags, &peeked, &skip, &err); + skb =__skb_recv_datagram (sk, flags, &peeked, &skip, &err, timeop);if (!skb) {unix_state_lock (sk);/* Signal EOF on disconnected non-blocking SEQPACKET socket. */ @@ -1914,7 +1914,7 @@ static unsigned int unix_skb_len(const struct sk_buff *skb)static int unix_stream_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock_iocb *siocb =kiocb_to_siocb (iocb);struct scm_cookie tmp_scm;@@ -1926,7 +1926,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,int check_creds =0 ;int target;int err =0 ; -long timeo; +long timeo =sock_rcvtimeop (sk, timeop, noblock);int skip; err = -EINVAL ;@@ -1938,7 +1938,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; target =sock_rcvlowat (sk, flags&MSG_WAITALL , size); - timeo =sock_rcvtimeo (sk, noblock);/* Lock the socket to prevent queue disordering * while sleeps in memcpy_tomsg @@ -2071,6 +2070,8 @@ again:mutex_unlock (&u->readlock);scm_recv (sock, msg, siocb->scm, flags); out: +if (timeop) + *timeop = timeo;return copied ? : err; }net/vmw_vsock/af_vsock.c +6
-4@@ -1063,10 +1063,10 @@ out: }static int vsock_dgram_recvmsg (struct kiocb *kiocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {return transport->dgram_dequeue (kiocb,vsock_sk (sock->sk), msg, len, - flags); + flags, timeop); }static const struct proto_ops vsock_dgram_ops = {@@ -1646,7 +1646,7 @@ out:static int vsock_stream_recvmsg (struct kiocb *kiocb,struct socket *sock, -struct msghdr *msg,size_t len,int flags) +struct msghdr *msg,size_t len,int flags,long *timeop) {struct sock *sk;struct vsock_sock *vsk;@@ -1661,6 +1661,7 @@ vsock_stream_recvmsg(struct kiocb *kiocb, sk = sock->sk; vsk =vsock_sk (sk); err =0 ; + timeout =sock_rcvtimeop (sk, timeop, flags &MSG_DONTWAIT );lock_sock (sk);@@ -1711,7 +1712,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb, err = -ENOMEM ; goto out; } - timeout =sock_rcvtimeo (sk, flags &MSG_DONTWAIT ); copied =0 ; err = transport->notify_recv_init (vsk, target, &recv_data);@@ -1821,6 +1821,8 @@ vsock_stream_recvmsg(struct kiocb *kiocb, out_wait:finish_wait (sk_sleep (sk), &wait); out: +if (timeop) + *timeop = timeout;release_sock (sk);return err; }net/vmw_vsock/vmci_transport.c +2
-2@@ -1733,7 +1733,7 @@ static int vmci_transport_dgram_enqueue(static int vmci_transport_dgram_dequeue (struct kiocb *kiocb,struct vsock_sock *vsk,struct msghdr *msg,size_t len, -int flags) +int flags,long *timeop) {int err;int noblock;@@ -1748,7 +1748,7 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,/* Retrieve the head sk_buff from the socket's receive queue. */ err =0 ; - skb =skb_recv_datagram (&vsk->sk, flags, noblock, &err); + skb =skb_recv_datagram (&vsk->sk, flags, noblock, &err, timeop);if (err)return err;net/x25/af_x25.c +2
-2@@ -1254,7 +1254,7 @@ out_kfree_skb:static int x25_recvmsg (struct kiocb *iocb,struct socket *sock,struct msghdr *msg,size_t size, -int flags) +int flags,long *timeop) {struct sock *sk = sock->sk;struct x25_sock *x25 =x25_sk (sk);@@ -1306,7 +1306,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,/* Now we can treat all alike */ release_sock (sk); skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , - flags &MSG_DONTWAIT , &rc); + flags &MSG_DONTWAIT , &rc, timeop);lock_sock (sk);if (!skb) goto out;
Signature · 3 lines
Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/