diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 3fe906d65069..9deec4391187 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -5362,6 +5362,20 @@ static void sctp_wfree(struct sk_buff *skb) | |||
5362 | sctp_association_put(asoc); | 5362 | sctp_association_put(asoc); |
5363 | } | 5363 | } |
5364 | 5364 | ||
5365 | /* Do accounting for the receive space on the socket. | ||
5366 | * Accounting for the association is done in ulpevent.c | ||
5367 | * We set this as a destructor for the cloned data skbs so that | ||
5368 | * accounting is done at the correct time. | ||
5369 | */ | ||
5370 | void sctp_sock_rfree(struct sk_buff *skb) | ||
5371 | { | ||
5372 | struct sock *sk = skb->sk; | ||
5373 | struct sctp_ulpevent *event = sctp_skb2event(skb); | ||
5374 | |||
5375 | atomic_sub(event->rmem_len, &sk->sk_rmem_alloc); | ||
5376 | } | ||
5377 | |||
5378 | |||
5365 | /* Helper function to wait for space in the sndbuf. */ | 5379 | /* Helper function to wait for space in the sndbuf. */ |
5366 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, | 5380 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, |
5367 | size_t msg_len) | 5381 | size_t msg_len) |
@@ -5634,10 +5648,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5634 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { | 5648 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { |
5635 | event = sctp_skb2event(skb); | 5649 | event = sctp_skb2event(skb); |
5636 | if (event->asoc == assoc) { | 5650 | if (event->asoc == assoc) { |
5637 | sock_rfree(skb); | 5651 | sctp_sock_rfree(skb); |
5638 | __skb_unlink(skb, &oldsk->sk_receive_queue); | 5652 | __skb_unlink(skb, &oldsk->sk_receive_queue); |
5639 | __skb_queue_tail(&newsk->sk_receive_queue, skb); | 5653 | __skb_queue_tail(&newsk->sk_receive_queue, skb); |
5640 | skb_set_owner_r(skb, newsk); | 5654 | sctp_skb_set_owner_r(skb, newsk); |
5641 | } | 5655 | } |
5642 | } | 5656 | } |
5643 | 5657 | ||
@@ -5665,10 +5679,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5665 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { | 5679 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { |
5666 | event = sctp_skb2event(skb); | 5680 | event = sctp_skb2event(skb); |
5667 | if (event->asoc == assoc) { | 5681 | if (event->asoc == assoc) { |
5668 | sock_rfree(skb); | 5682 | sctp_sock_rfree(skb); |
5669 | __skb_unlink(skb, &oldsp->pd_lobby); | 5683 | __skb_unlink(skb, &oldsp->pd_lobby); |
5670 | __skb_queue_tail(queue, skb); | 5684 | __skb_queue_tail(queue, skb); |
5671 | skb_set_owner_r(skb, newsk); | 5685 | sctp_skb_set_owner_r(skb, newsk); |
5672 | } | 5686 | } |
5673 | } | 5687 | } |
5674 | 5688 | ||