diff options
author | Len Brown <len.brown@intel.com> | 2009-01-09 03:39:43 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-01-09 03:39:43 -0500 |
commit | b2576e1d4408e134e2188c967b1f28af39cd79d4 (patch) | |
tree | 004f3c82faab760f304ce031d6d2f572e7746a50 /net/can/raw.c | |
parent | 3cc8a5f4ba91f67bbdb81a43a99281a26aab8d77 (diff) | |
parent | 2150edc6c5cf00f7adb54538b9ea2a3e9cedca3f (diff) |
Merge branch 'linus' into release
Diffstat (limited to 'net/can/raw.c')
-rw-r--r-- | net/can/raw.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/net/can/raw.c b/net/can/raw.c index 6e0663faaf9..0703cba4bf9 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -99,13 +99,14 @@ static void raw_rcv(struct sk_buff *skb, void *data) struct raw_sock *ro = raw_sk(sk); struct sockaddr_can *addr; - if (!ro->recv_own_msgs) { - /* check the received tx sock reference */ - if (skb->sk == sk) { - kfree_skb(skb); - return; - } - } + /* check the received tx sock reference */ + if (!ro->recv_own_msgs && skb->sk == sk) + return; + + /* clone the given skb to be able to enqueue it into the rcv queue */ + skb = skb_clone(skb, GFP_ATOMIC); + if (!skb) + return; /* * Put the datagram to the queue so that raw_recvmsg() can @@ -641,17 +642,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err); - if (!skb) { - dev_put(dev); - return err; - } + if (!skb) + goto put_dev; err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); - if (err < 0) { - kfree_skb(skb); - dev_put(dev); - return err; - } + if (err < 0) + goto free_skb; skb->dev = dev; skb->sk = sk; @@ -660,9 +656,16 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, dev_put(dev); if (err) - return err; + goto send_failed; return size; + +free_skb: + kfree_skb(skb); +put_dev: + dev_put(dev); +send_failed: + return err; } static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, |