Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
rxrpc
ar-skbuff.c
Go to the documentation of this file.
1
/* ar-skbuff.c: socket buffer destruction handling
2
*
3
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells (
[email protected]
)
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version
9
* 2 of the License, or (at your option) any later version.
10
*/
11
12
#include <linux/module.h>
13
#include <linux/net.h>
14
#include <
linux/skbuff.h
>
15
#include <
net/sock.h
>
16
#include <
net/af_rxrpc.h
>
17
#include "
ar-internal.h
"
18
19
/*
20
* set up for the ACK at the end of the receive phase when we discard the final
21
* receive phase data packet
22
* - called with softirqs disabled
23
*/
24
static
void
rxrpc_request_final_ACK(
struct
rxrpc_call
*call)
25
{
26
/* the call may be aborted before we have a chance to ACK it */
27
write_lock
(&call->
state_lock
);
28
29
switch
(call->
state
) {
30
case
RXRPC_CALL_CLIENT_RECV_REPLY:
31
call->
state
= RXRPC_CALL_CLIENT_FINAL_ACK;
32
_debug
(
"request final ACK"
);
33
34
/* get an extra ref on the call for the final-ACK generator to
35
* release */
36
rxrpc_get_call
(call);
37
set_bit
(
RXRPC_CALL_ACK_FINAL
, &call->
events
);
38
if
(
try_to_del_timer_sync
(&call->
ack_timer
) >= 0)
39
rxrpc_queue_call
(call);
40
break
;
41
42
case
RXRPC_CALL_SERVER_RECV_REQUEST:
43
call->
state
= RXRPC_CALL_SERVER_ACK_REQUEST;
44
default
:
45
break
;
46
}
47
48
write_unlock
(&call->
state_lock
);
49
}
50
51
/*
52
* drop the bottom ACK off of the call ACK window and advance the window
53
*/
54
static
void
rxrpc_hard_ACK_data(
struct
rxrpc_call
*call,
55
struct
rxrpc_skb_priv
*
sp
)
56
{
57
int
loop;
58
u32
seq
;
59
60
spin_lock_bh(&call->
lock
);
61
62
_debug
(
"hard ACK #%u"
,
ntohl
(sp->
hdr
.seq));
63
64
for
(loop = 0; loop <
RXRPC_ACKR_WINDOW_ASZ
; loop++) {
65
call->
ackr_window
[loop] >>= 1;
66
call->
ackr_window
[loop] |=
67
call->
ackr_window
[loop + 1] << (
BITS_PER_LONG
- 1);
68
}
69
70
seq =
ntohl
(sp->
hdr
.seq);
71
ASSERTCMP
(seq, ==, call->
rx_data_eaten
+ 1);
72
call->
rx_data_eaten
= seq;
73
74
if
(call->
ackr_win_top
<
UINT_MAX
)
75
call->
ackr_win_top
++;
76
77
ASSERTIFCMP
(call->
state
<= RXRPC_CALL_COMPLETE,
78
call->
rx_data_post
, >=, call->
rx_data_recv
);
79
ASSERTIFCMP
(call->
state
<= RXRPC_CALL_COMPLETE,
80
call->
rx_data_recv
, >=, call->
rx_data_eaten
);
81
82
if
(sp->
hdr
.flags &
RXRPC_LAST_PACKET
) {
83
rxrpc_request_final_ACK(call);
84
}
else
if
(
atomic_dec_and_test
(&call->
ackr_not_idle
) &&
85
test_and_clear_bit
(
RXRPC_CALL_TX_SOFT_ACK
, &call->
flags
)) {
86
_debug
(
"send Rx idle ACK"
);
87
__rxrpc_propose_ACK
(call,
RXRPC_ACK_IDLE
, sp->
hdr
.serial,
88
true
);
89
}
90
91
spin_unlock_bh(&call->
lock
);
92
}
93
94
/*
95
* destroy a packet that has an RxRPC control buffer
96
* - advance the hard-ACK state of the parent call (done here in case something
97
* in the kernel bypasses recvmsg() and steals the packet directly off of the
98
* socket receive queue)
99
*/
100
void
rxrpc_packet_destructor
(
struct
sk_buff
*
skb
)
101
{
102
struct
rxrpc_skb_priv
*sp =
rxrpc_skb
(skb);
103
struct
rxrpc_call
*call = sp->
call
;
104
105
_enter
(
"%p{%p}"
, skb, call);
106
107
if
(call) {
108
/* send the final ACK on a client call */
109
if
(sp->
hdr
.type ==
RXRPC_PACKET_TYPE_DATA
)
110
rxrpc_hard_ACK_data(call, sp);
111
rxrpc_put_call
(call);
112
sp->
call
=
NULL
;
113
}
114
115
if
(skb->
sk
)
116
sock_rfree
(skb);
117
_leave
(
""
);
118
}
119
127
void
rxrpc_kernel_free_skb
(
struct
sk_buff
*
skb
)
128
{
129
rxrpc_free_skb
(skb);
130
}
131
132
EXPORT_SYMBOL
(
rxrpc_kernel_free_skb
);
Generated on Thu Jan 10 2013 15:01:41 for Linux Kernel by
1.8.2