Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 78340
b: refs/heads/master
c: a59322b
h: refs/heads/master
v: v3
  • Loading branch information
Herbert Xu authored and David S. Miller committed Jan 28, 2008
1 parent 8743bdf commit 89c2558
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1781f7f5804e52ee2d35328b129602146a8d8254
refs/heads/master: a59322be07c964e916d15be3df473fb7ba20c41e
3 changes: 3 additions & 0 deletions trunk/include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ struct sk_buff {
__u8 pkt_type:3,
fclone:2,
ipvs_property:1,
peeked:1,
nf_trace:1;
__be16 protocol;

Expand Down Expand Up @@ -1538,6 +1539,8 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
skb = skb->prev)


extern struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
int *peeked, int *err);
extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
int noblock, int *err);
extern unsigned int datagram_poll(struct file *file, struct socket *sock,
Expand Down
43 changes: 27 additions & 16 deletions trunk/net/core/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ static int wait_for_packet(struct sock *sk, int *err, long *timeo_p)
}

/**
* skb_recv_datagram - Receive a datagram skbuff
* __skb_recv_datagram - Receive a datagram skbuff
* @sk: socket
* @flags: MSG_ flags
* @noblock: blocking operation?
* @peeked: returns non-zero if this packet has been seen before
* @err: error code returned
*
* Get a datagram skbuff, understands the peeking, nonblocking wakeups
Expand All @@ -143,8 +143,8 @@ static int wait_for_packet(struct sock *sk, int *err, long *timeo_p)
* quite explicitly by POSIX 1003.1g, don't change them without having
* the standard around please.
*/
struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
int noblock, int *err)
struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
int *peeked, int *err)
{
struct sk_buff *skb;
long timeo;
Expand All @@ -156,7 +156,7 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
if (error)
goto no_packet;

timeo = sock_rcvtimeo(sk, noblock);
timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);

do {
/* Again only user level code calls this function, so nothing
Expand All @@ -165,18 +165,19 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
* Look at current nfs client by the way...
* However, this function was corrent in any case. 8)
*/
if (flags & MSG_PEEK) {
unsigned long cpu_flags;

spin_lock_irqsave(&sk->sk_receive_queue.lock,
cpu_flags);
skb = skb_peek(&sk->sk_receive_queue);
if (skb)
unsigned long cpu_flags;

spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
skb = skb_peek(&sk->sk_receive_queue);
if (skb) {
*peeked = skb->peeked;
if (flags & MSG_PEEK) {
skb->peeked = 1;
atomic_inc(&skb->users);
spin_unlock_irqrestore(&sk->sk_receive_queue.lock,
cpu_flags);
} else
skb = skb_dequeue(&sk->sk_receive_queue);
} else
__skb_unlink(skb, &sk->sk_receive_queue);
}
spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);

if (skb)
return skb;
Expand All @@ -194,6 +195,16 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
*err = error;
return NULL;
}
EXPORT_SYMBOL(__skb_recv_datagram);

struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
int noblock, int *err)
{
int peeked;

return __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
&peeked, err);
}

void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
{
Expand Down
7 changes: 5 additions & 2 deletions trunk/net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
struct sk_buff *skb;
unsigned int ulen, copied;
int peeked;
int err;
int is_udplite = IS_UDPLITE(sk);

Expand All @@ -840,7 +841,8 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
return ip_recv_error(sk, msg, len);

try_again:
skb = skb_recv_datagram(sk, flags, noblock, &err);
skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
&peeked, &err);
if (!skb)
goto out;

Expand Down Expand Up @@ -875,7 +877,8 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (err)
goto out_free;

UDP_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite);
if (!peeked)
UDP_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite);

sock_recv_timestamp(msg, sk, skb);

Expand Down
7 changes: 5 additions & 2 deletions trunk/net/ipv6/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
struct inet_sock *inet = inet_sk(sk);
struct sk_buff *skb;
unsigned int ulen, copied;
int peeked;
int err;
int is_udplite = IS_UDPLITE(sk);

Expand All @@ -133,7 +134,8 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
return ipv6_recv_error(sk, msg, len);

try_again:
skb = skb_recv_datagram(sk, flags, noblock, &err);
skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
&peeked, &err);
if (!skb)
goto out;

Expand Down Expand Up @@ -166,7 +168,8 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
if (err)
goto out_free;

UDP6_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite);
if (!peeked)
UDP6_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite);

sock_recv_timestamp(msg, sk, skb);

Expand Down

0 comments on commit 89c2558

Please sign in to comment.