Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 290231
b: refs/heads/master
c: 8de65c2
h: refs/heads/master
i:
  290229: 7940f8f
  290227: ec0cd8f
  290223: d6d2614
v: v3
  • Loading branch information
David S. Miller committed Feb 21, 2012
1 parent 8fa652c commit 0227d55
Show file tree
Hide file tree
Showing 26 changed files with 139 additions and 23 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: 475be4d85a274d0961593db41cf85689db1d583c
refs/heads/master: 8de65c2aaa1faf8e57e1b29b4265b6a57fae4136
1 change: 1 addition & 0 deletions trunk/arch/alpha/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here.
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/arm/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/arch/avr32/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* __ASM_AVR32_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/arch/cris/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_SOCKET_H */

Expand Down
1 change: 1 addition & 0 deletions trunk/arch/frv/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_SOCKET_H */

1 change: 1 addition & 0 deletions trunk/arch/h8300/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/arch/ia64/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_IA64_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/arch/m32r/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_M32R_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/arch/m68k/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/arch/mips/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#ifdef __KERNEL__

Expand Down
1 change: 1 addition & 0 deletions trunk/arch/mn10300/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/arch/parisc/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@

#define SO_WIFI_STATUS 0x4022
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 0x4023

/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here.
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_POWERPC_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/arch/s390/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _ASM_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/arch/sparc/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@

#define SO_WIFI_STATUS 0x0025
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 0x0026

/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/xtensa/include/asm/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,6 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42

#endif /* _XTENSA_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/include/asm-generic/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,5 @@

#define SO_WIFI_STATUS 41
#define SCM_WIFI_STATUS SO_WIFI_STATUS
#define SO_PEEK_OFF 42
#endif /* __ASM_GENERIC_SOCKET_H */
1 change: 1 addition & 0 deletions trunk/include/linux/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ struct proto_ops {
int offset, size_t size, int flags);
ssize_t (*splice_read)(struct socket *sock, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len, unsigned int flags);
void (*set_peek_off)(struct sock *sk, int val);
};

#define DECLARE_SOCKADDR(type, dst, src) \
Expand Down
20 changes: 19 additions & 1 deletion trunk/include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,24 @@ static inline struct sk_buff *skb_peek(const struct sk_buff_head *list_)
return list;
}

/**
* skb_peek_next - peek skb following the given one from a queue
* @skb: skb to start from
* @list_: list to peek at
*
* Returns %NULL when the end of the list is met or a pointer to the
* next element. The reference count is not incremented and the
* reference is therefore volatile. Use with caution.
*/
static inline struct sk_buff *skb_peek_next(struct sk_buff *skb,
const struct sk_buff_head *list_)
{
struct sk_buff *next = skb->next;
if (next == (struct sk_buff *)list_)
next = NULL;
return next;
}

/**
* skb_peek_tail - peek at the tail of an &sk_buff_head
* @list_: list to peek at
Expand Down Expand Up @@ -2046,7 +2064,7 @@ 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)

extern struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
int *peeked, int *err);
int *peeked, int *off, 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
25 changes: 25 additions & 0 deletions trunk/include/net/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ struct sock {
struct page *sk_sndmsg_page;
struct sk_buff *sk_send_head;
__u32 sk_sndmsg_off;
__s32 sk_peek_off;
int sk_write_pending;
#ifdef CONFIG_SECURITY
void *sk_security;
Expand All @@ -373,6 +374,30 @@ struct sock {
void (*sk_destruct)(struct sock *sk);
};

static inline int sk_peek_offset(struct sock *sk, int flags)
{
if ((flags & MSG_PEEK) && (sk->sk_peek_off >= 0))
return sk->sk_peek_off;
else
return 0;
}

static inline void sk_peek_offset_bwd(struct sock *sk, int val)
{
if (sk->sk_peek_off >= 0) {
if (sk->sk_peek_off >= val)
sk->sk_peek_off -= val;
else
sk->sk_peek_off = 0;
}
}

static inline void sk_peek_offset_fwd(struct sock *sk, int val)
{
if (sk->sk_peek_off >= 0)
sk->sk_peek_off += val;
}

/*
* Hashed lists helper routines
*/
Expand Down
26 changes: 16 additions & 10 deletions trunk/net/core/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ static int wait_for_packet(struct sock *sk, int *err, long *timeo_p)
* __skb_recv_datagram - Receive a datagram skbuff
* @sk: socket
* @flags: MSG_ flags
* @off: an offset in bytes to peek skb from. Returns an offset
* within an skb where data actually starts
* @peeked: returns non-zero if this packet has been seen before
* @err: error code returned
*
Expand All @@ -158,7 +160,7 @@ static int wait_for_packet(struct sock *sk, int *err, long *timeo_p)
* the standard around please.
*/
struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
int *peeked, int *err)
int *peeked, int *off, int *err)
{
struct sk_buff *skb;
long timeo;
Expand All @@ -180,21 +182,25 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
* However, this function was correct in any case. 8)
*/
unsigned long cpu_flags;
struct sk_buff_head *queue = &sk->sk_receive_queue;

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

if (skb)
spin_unlock_irqrestore(&queue->lock, cpu_flags);
return skb;
}
spin_unlock_irqrestore(&queue->lock, cpu_flags);

/* User doesn't want to wait */
error = -EAGAIN;
Expand All @@ -214,10 +220,10 @@ EXPORT_SYMBOL(__skb_recv_datagram);
struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
int noblock, int *err)
{
int peeked;
int peeked, off = 0;

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

Expand Down
13 changes: 13 additions & 0 deletions trunk/net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,12 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
break;

case SO_PEEK_OFF:
if (sock->ops->set_peek_off)
sock->ops->set_peek_off(sk, val);
else
ret = -EOPNOTSUPP;
break;
default:
ret = -ENOPROTOOPT;
break;
Expand Down Expand Up @@ -1018,6 +1024,12 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
v.val = !!sock_flag(sk, SOCK_WIFI_STATUS);
break;

case SO_PEEK_OFF:
if (!sock->ops->set_peek_off)
return -EOPNOTSUPP;

v.val = sk->sk_peek_off;
break;
default:
return -ENOPROTOOPT;
}
Expand Down Expand Up @@ -2092,6 +2104,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)

sk->sk_sndmsg_page = NULL;
sk->sk_sndmsg_off = 0;
sk->sk_peek_off = -1;

sk->sk_peer_pid = NULL;
sk->sk_peer_cred = NULL;
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,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 peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
bool slow;
Expand All @@ -1183,7 +1183,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, &err);
&peeked, &off, &err);
if (!skb)
goto out;

Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv6/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,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 peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
int is_udp4;
Expand All @@ -359,7 +359,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,

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

Expand Down
Loading

0 comments on commit 0227d55

Please sign in to comment.