public inbox for netdev@vger.kernel.org 
 help / color / mirror / Atom feed
From: Pavel Emelyanov <xemul@parallels•com>
To: David Miller <davem@davemloft•net>,
	Eric Dumazet <eric.dumazet@gmail•com>,
	Linux Netdev List <netdev@vger•kernel.org>
Subject: [PATCH 6/6] unix: Support peeking offset for stream sockets
Date: Tue, 21 Feb 2012 21:32:06 +0400	[thread overview]
Message-ID: <4F43D516.9060102@parallels.com> (raw)
In-Reply-To: <4F43D49E.3010401@parallels.com>

The same here -- we can protect the sk_peek_off manipulations with
the unix_sk->readlock mutex.

The peeking of data from a stream socket is done in the datagram style,
i.e. even if there's enough room for more data in the user buffer, only
the head skb's data is copied in there. This feature is preserved when
peeking data from a given offset -- the data is read till the nearest
skb's boundary.

Signed-off-by: Pavel Emelyanov <xemul@parallels•com>

---
 net/unix/af_unix.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 3d9481d..0be4d24 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -559,6 +559,7 @@ static const struct proto_ops unix_stream_ops = {
 	.recvmsg =	unix_stream_recvmsg,
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
+	.set_peek_off =	unix_set_peek_off,
 };
 
 static const struct proto_ops unix_dgram_ops = {
@@ -1904,6 +1905,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 	int target;
 	int err = 0;
 	long timeo;
+	int skip;
 
 	err = -EINVAL;
 	if (sk->sk_state != TCP_ESTABLISHED)
@@ -1933,12 +1935,15 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 		goto out;
 	}
 
+	skip = sk_peek_offset(sk, flags);
+
 	do {
 		int chunk;
 		struct sk_buff *skb;
 
 		unix_state_lock(sk);
 		skb = skb_peek(&sk->sk_receive_queue);
+again:
 		if (skb == NULL) {
 			unix_sk(sk)->recursion_level = 0;
 			if (copied >= target)
@@ -1973,6 +1978,13 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			unix_state_unlock(sk);
 			break;
 		}
+
+		if (skip >= skb->len) {
+			skip -= skb->len;
+			skb = skb_peek_next(skb, &sk->sk_receive_queue);
+			goto again;
+		}
+
 		unix_state_unlock(sk);
 
 		if (check_creds) {
@@ -1992,8 +2004,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			sunaddr = NULL;
 		}
 
-		chunk = min_t(unsigned int, skb->len, size);
-		if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+		chunk = min_t(unsigned int, skb->len - skip, size);
+		if (memcpy_toiovec(msg->msg_iov, skb->data + skip, chunk)) {
 			if (copied == 0)
 				copied = -EFAULT;
 			break;
@@ -2005,6 +2017,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 		if (!(flags & MSG_PEEK)) {
 			skb_pull(skb, chunk);
 
+			sk_peek_offset_bwd(sk, chunk);
+
 			if (UNIXCB(skb).fp)
 				unix_detach_fds(siocb->scm, skb);
 
@@ -2022,6 +2036,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			if (UNIXCB(skb).fp)
 				siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
 
+			sk_peek_offset_fwd(sk, chunk);
+
 			break;
 		}
 	} while (size);
-- 
1.5.5.6

  parent reply	other threads:[~2012-02-21 17:32 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-21 17:30 [PATCH net-next 0/6] Ability to peek full socket queue Pavel Emelyanov
2012-02-21 17:30 ` [PATCH 1/6] datagram: Factor out sk queue referencing Pavel Emelyanov
2012-02-21 17:39   ` Eric Dumazet
2012-02-21 20:04     ` David Miller
2012-02-21 17:30 ` [PATCH 2/6] datagram: Add offset argument to __skb_recv_datagram Pavel Emelyanov
2012-02-21 17:40   ` Eric Dumazet
2012-02-21 20:04     ` David Miller
2012-02-21 17:31 ` [PATCH 3/6] skb: Add skb_peek_next helper Pavel Emelyanov
2012-02-21 17:43   ` Eric Dumazet
2012-02-21 20:04     ` David Miller
2012-02-21 17:31 ` [PATCH 4/6] sock: Introduce the SO_PEEK_OFF sock option Pavel Emelyanov
2012-02-21 17:45   ` Eric Dumazet
2012-02-21 20:05     ` David Miller
2012-02-21 17:31 ` [PATCH 5/6] unix: Support peeking offset for datagram and seqpacket sockets Pavel Emelyanov
2012-02-21 17:49   ` Eric Dumazet
2012-02-21 20:05     ` David Miller
2012-02-21 17:32 ` Pavel Emelyanov [this message]
2012-02-21 17:51   ` [PATCH 6/6] unix: Support peeking offset for stream sockets Eric Dumazet
2012-02-21 20:05     ` David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F43D516.9060102@parallels.com \
    --to=xemul@parallels$(echo .)com \
    --cc=davem@davemloft$(echo .)net \
    --cc=eric.dumazet@gmail$(echo .)com \
    --cc=netdev@vger$(echo .)kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox