diff options
author | Wei Yongjun <yjwei@cn.fujitsu.com> | 2009-07-05 15:45:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-06 15:47:08 -0400 |
commit | 1bc4ee4088c9a502db0e9c87f675e61e57fa1734 (patch) | |
tree | a166f4b7e7aa78fa31431ae6cb060bf4e5d088be /net | |
parent | 3c8a9c63d5fd738c261bd0ceece04d9c8357ca13 (diff) |
sctp: fix warning at inet_sock_destruct() while release sctp socket
Commit 'net: Move rx skb_orphan call to where needed' broken sctp protocol
with warning at inet_sock_destruct(). Actually, sctp can do this right with
sctp_sock_rfree_frag() and sctp_skb_set_owner_r_frag() pair.
sctp_sock_rfree_frag(skb);
sctp_skb_set_owner_r_frag(skb, newsk);
This patch not revert the commit d55d87fdff8252d0e2f7c28c2d443aee17e9d70f,
instead remove the sctp_sock_rfree_frag() function.
------------[ cut here ]------------
WARNING: at net/ipv4/af_inet.c:151 inet_sock_destruct+0xe0/0x142()
Modules linked in: sctp ipv6 dm_mirror dm_region_hash dm_log dm_multipath
scsi_mod ext3 jbd uhci_hcd ohci_hcd ehci_hcd [last unloaded: scsi_wait_scan]
Pid: 1808, comm: sctp_test Not tainted 2.6.31-rc2 #40
Call Trace:
[<c042dd06>] warn_slowpath_common+0x6a/0x81
[<c064a39a>] ? inet_sock_destruct+0xe0/0x142
[<c042dd2f>] warn_slowpath_null+0x12/0x15
[<c064a39a>] inet_sock_destruct+0xe0/0x142
[<c05fde44>] __sk_free+0x19/0xcc
[<c05fdf50>] sk_free+0x18/0x1a
[<ca0d14ad>] sctp_close+0x192/0x1a1 [sctp]
[<c0649f7f>] inet_release+0x47/0x4d
[<c05fba4d>] sock_release+0x19/0x5e
[<c05fbab3>] sock_close+0x21/0x25
[<c049c31b>] __fput+0xde/0x189
[<c049c3de>] fput+0x18/0x1a
[<c049988f>] filp_close+0x56/0x60
[<c042f422>] put_files_struct+0x5d/0xa1
[<c042f49f>] exit_files+0x39/0x3d
[<c043086a>] do_exit+0x1a5/0x5dd
[<c04a86c2>] ? d_kill+0x35/0x3b
[<c0438fa4>] ? dequeue_signal+0xa6/0x115
[<c0430d05>] do_group_exit+0x63/0x8a
[<c0439504>] get_signal_to_deliver+0x2e1/0x2f9
[<c0401d9e>] do_notify_resume+0x7c/0x6b5
[<c043f601>] ? autoremove_wake_function+0x0/0x34
[<c04a864e>] ? __d_free+0x3d/0x40
[<c04a867b>] ? d_free+0x2a/0x3c
[<c049ba7e>] ? vfs_write+0x103/0x117
[<c05fc8fa>] ? sys_socketcall+0x178/0x182
[<c0402a56>] work_notifysig+0x13/0x19
---[ end trace 9db92c463e789fba ]---
Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sctp/socket.c | 25 |
1 files changed, 2 insertions, 23 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 35ba035970a2..971890dbfea0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -6652,21 +6652,6 @@ static void sctp_wait_for_close(struct sock *sk, long timeout) | |||
6652 | finish_wait(sk->sk_sleep, &wait); | 6652 | finish_wait(sk->sk_sleep, &wait); |
6653 | } | 6653 | } |
6654 | 6654 | ||
6655 | static void sctp_sock_rfree_frag(struct sk_buff *skb) | ||
6656 | { | ||
6657 | struct sk_buff *frag; | ||
6658 | |||
6659 | if (!skb->data_len) | ||
6660 | goto done; | ||
6661 | |||
6662 | /* Don't forget the fragments. */ | ||
6663 | skb_walk_frags(skb, frag) | ||
6664 | sctp_sock_rfree_frag(frag); | ||
6665 | |||
6666 | done: | ||
6667 | sctp_sock_rfree(skb); | ||
6668 | } | ||
6669 | |||
6670 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) | 6655 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) |
6671 | { | 6656 | { |
6672 | struct sk_buff *frag; | 6657 | struct sk_buff *frag; |
@@ -6776,7 +6761,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
6776 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { | 6761 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { |
6777 | event = sctp_skb2event(skb); | 6762 | event = sctp_skb2event(skb); |
6778 | if (event->asoc == assoc) { | 6763 | if (event->asoc == assoc) { |
6779 | sctp_sock_rfree_frag(skb); | ||
6780 | __skb_unlink(skb, &oldsk->sk_receive_queue); | 6764 | __skb_unlink(skb, &oldsk->sk_receive_queue); |
6781 | __skb_queue_tail(&newsk->sk_receive_queue, skb); | 6765 | __skb_queue_tail(&newsk->sk_receive_queue, skb); |
6782 | sctp_skb_set_owner_r_frag(skb, newsk); | 6766 | sctp_skb_set_owner_r_frag(skb, newsk); |
@@ -6807,7 +6791,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
6807 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { | 6791 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { |
6808 | event = sctp_skb2event(skb); | 6792 | event = sctp_skb2event(skb); |
6809 | if (event->asoc == assoc) { | 6793 | if (event->asoc == assoc) { |
6810 | sctp_sock_rfree_frag(skb); | ||
6811 | __skb_unlink(skb, &oldsp->pd_lobby); | 6794 | __skb_unlink(skb, &oldsp->pd_lobby); |
6812 | __skb_queue_tail(queue, skb); | 6795 | __skb_queue_tail(queue, skb); |
6813 | sctp_skb_set_owner_r_frag(skb, newsk); | 6796 | sctp_skb_set_owner_r_frag(skb, newsk); |
@@ -6822,15 +6805,11 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
6822 | 6805 | ||
6823 | } | 6806 | } |
6824 | 6807 | ||
6825 | sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp) { | 6808 | sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp) |
6826 | sctp_sock_rfree_frag(skb); | ||
6827 | sctp_skb_set_owner_r_frag(skb, newsk); | 6809 | sctp_skb_set_owner_r_frag(skb, newsk); |
6828 | } | ||
6829 | 6810 | ||
6830 | sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp) { | 6811 | sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp) |
6831 | sctp_sock_rfree_frag(skb); | ||
6832 | sctp_skb_set_owner_r_frag(skb, newsk); | 6812 | sctp_skb_set_owner_r_frag(skb, newsk); |
6833 | } | ||
6834 | 6813 | ||
6835 | /* Set the type of socket to indicate that it is peeled off from the | 6814 | /* Set the type of socket to indicate that it is peeled off from the |
6836 | * original UDP-style socket or created with the accept() call on a | 6815 | * original UDP-style socket or created with the accept() call on a |