aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-10-06 03:11:49 -0400
committerDavid Howells <dhowells@redhat.com>2016-10-06 03:11:49 -0400
commit26cb02aa6d3efeb543805ed9ad599dae24f7c6d4 (patch)
tree58265f21e206c1249ed4fbbf6e58bd49258879ef
parenta9f312d98affab387557e2795d4e11ad82a4e4e8 (diff)
rxrpc: Fix warning by splitting rxrpc_send_call_packet()
Split rxrpc_send_data_packet() to separate ACK generation (which is more complicated) from ABORT generation. This simplifies the code a bit and fixes the following warning: In file included from ../net/rxrpc/output.c:20:0: net/rxrpc/output.c: In function 'rxrpc_send_call_packet': net/rxrpc/ar-internal.h:1187:27: error: 'top' may be used uninitialized in this function [-Werror=maybe-uninitialized] net/rxrpc/output.c:103:24: note: 'top' was declared here net/rxrpc/output.c:225:25: error: 'hard_ack' may be used uninitialized in this function [-Werror=maybe-uninitialized] Reported-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--net/rxrpc/ar-internal.h3
-rw-r--r--net/rxrpc/call_accept.c2
-rw-r--r--net/rxrpc/call_event.c6
-rw-r--r--net/rxrpc/call_object.c2
-rw-r--r--net/rxrpc/output.c156
-rw-r--r--net/rxrpc/recvmsg.c4
-rw-r--r--net/rxrpc/rxkad.c6
-rw-r--r--net/rxrpc/sendmsg.c7
8 files changed, 102 insertions, 84 deletions
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 4954e6e25819..ef849a12a0f0 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -1068,7 +1068,8 @@ extern const s8 rxrpc_ack_priority[];
1068/* 1068/*
1069 * output.c 1069 * output.c
1070 */ 1070 */
1071int rxrpc_send_call_packet(struct rxrpc_call *, u8); 1071int rxrpc_send_ack_packet(struct rxrpc_call *);
1072int rxrpc_send_abort_packet(struct rxrpc_call *);
1072int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *, bool); 1073int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *, bool);
1073void rxrpc_reject_packets(struct rxrpc_local *); 1074void rxrpc_reject_packets(struct rxrpc_local *);
1074 1075
diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c
index 22cd8a18c481..832d854c2d5c 100644
--- a/net/rxrpc/call_accept.c
+++ b/net/rxrpc/call_accept.c
@@ -565,7 +565,7 @@ out_discard:
565 write_unlock_bh(&call->state_lock); 565 write_unlock_bh(&call->state_lock);
566 write_unlock(&rx->call_lock); 566 write_unlock(&rx->call_lock);
567 if (abort) { 567 if (abort) {
568 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT); 568 rxrpc_send_abort_packet(call);
569 rxrpc_release_call(rx, call); 569 rxrpc_release_call(rx, call);
570 rxrpc_put_call(call, rxrpc_call_put); 570 rxrpc_put_call(call, rxrpc_call_put);
571 } 571 }
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c
index 4f00476630b9..e313099860d5 100644
--- a/net/rxrpc/call_event.c
+++ b/net/rxrpc/call_event.c
@@ -253,7 +253,7 @@ static void rxrpc_resend(struct rxrpc_call *call, ktime_t now)
253 goto out; 253 goto out;
254 rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false, 254 rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false,
255 rxrpc_propose_ack_ping_for_lost_ack); 255 rxrpc_propose_ack_ping_for_lost_ack);
256 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK); 256 rxrpc_send_ack_packet(call);
257 goto out; 257 goto out;
258 } 258 }
259 259
@@ -328,7 +328,7 @@ void rxrpc_process_call(struct work_struct *work)
328 328
329recheck_state: 329recheck_state:
330 if (test_and_clear_bit(RXRPC_CALL_EV_ABORT, &call->events)) { 330 if (test_and_clear_bit(RXRPC_CALL_EV_ABORT, &call->events)) {
331 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT); 331 rxrpc_send_abort_packet(call);
332 goto recheck_state; 332 goto recheck_state;
333 } 333 }
334 334
@@ -347,7 +347,7 @@ recheck_state:
347 if (test_and_clear_bit(RXRPC_CALL_EV_ACK, &call->events)) { 347 if (test_and_clear_bit(RXRPC_CALL_EV_ACK, &call->events)) {
348 call->ack_at = call->expire_at; 348 call->ack_at = call->expire_at;
349 if (call->ackr_reason) { 349 if (call->ackr_reason) {
350 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK); 350 rxrpc_send_ack_packet(call);
351 goto recheck_state; 351 goto recheck_state;
352 } 352 }
353 } 353 }
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
index 364b42dc3dce..07094012ac15 100644
--- a/net/rxrpc/call_object.c
+++ b/net/rxrpc/call_object.c
@@ -498,7 +498,7 @@ void rxrpc_release_calls_on_socket(struct rxrpc_sock *rx)
498 struct rxrpc_call, sock_link); 498 struct rxrpc_call, sock_link);
499 rxrpc_get_call(call, rxrpc_call_got); 499 rxrpc_get_call(call, rxrpc_call_got);
500 rxrpc_abort_call("SKT", call, 0, RX_CALL_DEAD, ECONNRESET); 500 rxrpc_abort_call("SKT", call, 0, RX_CALL_DEAD, ECONNRESET);
501 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT); 501 rxrpc_send_abort_packet(call);
502 rxrpc_release_call(rx, call); 502 rxrpc_release_call(rx, call);
503 rxrpc_put_call(call, rxrpc_call_put); 503 rxrpc_put_call(call, rxrpc_call_put);
504 } 504 }
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 0d47db886f6e..2dae877c0876 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -19,24 +19,24 @@
19#include <net/af_rxrpc.h> 19#include <net/af_rxrpc.h>
20#include "ar-internal.h" 20#include "ar-internal.h"
21 21
22struct rxrpc_pkt_buffer { 22struct rxrpc_ack_buffer {
23 struct rxrpc_wire_header whdr; 23 struct rxrpc_wire_header whdr;
24 union { 24 struct rxrpc_ackpacket ack;
25 struct { 25 u8 acks[255];
26 struct rxrpc_ackpacket ack; 26 u8 pad[3];
27 u8 acks[255];
28 u8 pad[3];
29 };
30 __be32 abort_code;
31 };
32 struct rxrpc_ackinfo ackinfo; 27 struct rxrpc_ackinfo ackinfo;
33}; 28};
34 29
30struct rxrpc_abort_buffer {
31 struct rxrpc_wire_header whdr;
32 __be32 abort_code;
33};
34
35/* 35/*
36 * Fill out an ACK packet. 36 * Fill out an ACK packet.
37 */ 37 */
38static size_t rxrpc_fill_out_ack(struct rxrpc_call *call, 38static size_t rxrpc_fill_out_ack(struct rxrpc_call *call,
39 struct rxrpc_pkt_buffer *pkt, 39 struct rxrpc_ack_buffer *pkt,
40 rxrpc_seq_t *_hard_ack, 40 rxrpc_seq_t *_hard_ack,
41 rxrpc_seq_t *_top) 41 rxrpc_seq_t *_top)
42{ 42{
@@ -91,22 +91,19 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_call *call,
91} 91}
92 92
93/* 93/*
94 * Send an ACK or ABORT call packet. 94 * Send an ACK call packet.
95 */ 95 */
96int rxrpc_send_call_packet(struct rxrpc_call *call, u8 type) 96int rxrpc_send_ack_packet(struct rxrpc_call *call)
97{ 97{
98 struct rxrpc_connection *conn = NULL; 98 struct rxrpc_connection *conn = NULL;
99 struct rxrpc_pkt_buffer *pkt; 99 struct rxrpc_ack_buffer *pkt;
100 struct msghdr msg; 100 struct msghdr msg;
101 struct kvec iov[2]; 101 struct kvec iov[2];
102 rxrpc_serial_t serial; 102 rxrpc_serial_t serial;
103 rxrpc_seq_t hard_ack, top; 103 rxrpc_seq_t hard_ack, top;
104 size_t len, n; 104 size_t len, n;
105 bool ping = false; 105 bool ping = false;
106 int ioc, ret; 106 int ret;
107 u32 abort_code;
108
109 _enter("%u,%s", call->debug_id, rxrpc_pkts[type]);
110 107
111 spin_lock_bh(&call->lock); 108 spin_lock_bh(&call->lock);
112 if (call->conn) 109 if (call->conn)
@@ -131,65 +128,37 @@ int rxrpc_send_call_packet(struct rxrpc_call *call, u8 type)
131 pkt->whdr.cid = htonl(call->cid); 128 pkt->whdr.cid = htonl(call->cid);
132 pkt->whdr.callNumber = htonl(call->call_id); 129 pkt->whdr.callNumber = htonl(call->call_id);
133 pkt->whdr.seq = 0; 130 pkt->whdr.seq = 0;
134 pkt->whdr.type = type; 131 pkt->whdr.type = RXRPC_PACKET_TYPE_ACK;
135 pkt->whdr.flags = conn->out_clientflag; 132 pkt->whdr.flags = RXRPC_SLOW_START_OK | conn->out_clientflag;
136 pkt->whdr.userStatus = 0; 133 pkt->whdr.userStatus = 0;
137 pkt->whdr.securityIndex = call->security_ix; 134 pkt->whdr.securityIndex = call->security_ix;
138 pkt->whdr._rsvd = 0; 135 pkt->whdr._rsvd = 0;
139 pkt->whdr.serviceId = htons(call->service_id); 136 pkt->whdr.serviceId = htons(call->service_id);
140 137
141 iov[0].iov_base = pkt; 138 spin_lock_bh(&call->lock);
142 iov[0].iov_len = sizeof(pkt->whdr); 139 if (!call->ackr_reason) {
143 len = sizeof(pkt->whdr);
144
145 switch (type) {
146 case RXRPC_PACKET_TYPE_ACK:
147 spin_lock_bh(&call->lock);
148 if (!call->ackr_reason) {
149 spin_unlock_bh(&call->lock);
150 ret = 0;
151 goto out;
152 }
153 ping = (call->ackr_reason == RXRPC_ACK_PING);
154 n = rxrpc_fill_out_ack(call, pkt, &hard_ack, &top);
155 call->ackr_reason = 0;
156
157 spin_unlock_bh(&call->lock); 140 spin_unlock_bh(&call->lock);
158 141 ret = 0;
159
160 pkt->whdr.flags |= RXRPC_SLOW_START_OK;
161
162 iov[0].iov_len += sizeof(pkt->ack) + n;
163 iov[1].iov_base = &pkt->ackinfo;
164 iov[1].iov_len = sizeof(pkt->ackinfo);
165 len += sizeof(pkt->ack) + n + sizeof(pkt->ackinfo);
166 ioc = 2;
167 break;
168
169 case RXRPC_PACKET_TYPE_ABORT:
170 abort_code = call->abort_code;
171 pkt->abort_code = htonl(abort_code);
172 iov[0].iov_len += sizeof(pkt->abort_code);
173 len += sizeof(pkt->abort_code);
174 ioc = 1;
175 break;
176
177 default:
178 BUG();
179 ret = -ENOANO;
180 goto out; 142 goto out;
181 } 143 }
144 ping = (call->ackr_reason == RXRPC_ACK_PING);
145 n = rxrpc_fill_out_ack(call, pkt, &hard_ack, &top);
146 call->ackr_reason = 0;
147
148 spin_unlock_bh(&call->lock);
149
150 iov[0].iov_base = pkt;
151 iov[0].iov_len = sizeof(pkt->whdr) + sizeof(pkt->ack) + n;
152 iov[1].iov_base = &pkt->ackinfo;
153 iov[1].iov_len = sizeof(pkt->ackinfo);
154 len = iov[0].iov_len + iov[1].iov_len;
182 155
183 serial = atomic_inc_return(&conn->serial); 156 serial = atomic_inc_return(&conn->serial);
184 pkt->whdr.serial = htonl(serial); 157 pkt->whdr.serial = htonl(serial);
185 switch (type) { 158 trace_rxrpc_tx_ack(call, serial,
186 case RXRPC_PACKET_TYPE_ACK: 159 ntohl(pkt->ack.firstPacket),
187 trace_rxrpc_tx_ack(call, serial, 160 ntohl(pkt->ack.serial),
188 ntohl(pkt->ack.firstPacket), 161 pkt->ack.reason, pkt->ack.nAcks);
189 ntohl(pkt->ack.serial),
190 pkt->ack.reason, pkt->ack.nAcks);
191 break;
192 }
193 162
194 if (ping) { 163 if (ping) {
195 call->ackr_ping = serial; 164 call->ackr_ping = serial;
@@ -205,13 +174,12 @@ int rxrpc_send_call_packet(struct rxrpc_call *call, u8 type)
205 set_bit(RXRPC_CALL_PINGING, &call->flags); 174 set_bit(RXRPC_CALL_PINGING, &call->flags);
206 trace_rxrpc_rtt_tx(call, rxrpc_rtt_tx_ping, serial); 175 trace_rxrpc_rtt_tx(call, rxrpc_rtt_tx_ping, serial);
207 } 176 }
208 ret = kernel_sendmsg(conn->params.local->socket, 177
209 &msg, iov, ioc, len); 178 ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
210 if (ping) 179 if (ping)
211 call->ackr_ping_time = ktime_get_real(); 180 call->ackr_ping_time = ktime_get_real();
212 181
213 if (type == RXRPC_PACKET_TYPE_ACK && 182 if (call->state < RXRPC_CALL_COMPLETE) {
214 call->state < RXRPC_CALL_COMPLETE) {
215 if (ret < 0) { 183 if (ret < 0) {
216 clear_bit(RXRPC_CALL_PINGING, &call->flags); 184 clear_bit(RXRPC_CALL_PINGING, &call->flags);
217 rxrpc_propose_ACK(call, pkt->ack.reason, 185 rxrpc_propose_ACK(call, pkt->ack.reason,
@@ -236,6 +204,56 @@ out:
236} 204}
237 205
238/* 206/*
207 * Send an ABORT call packet.
208 */
209int rxrpc_send_abort_packet(struct rxrpc_call *call)
210{
211 struct rxrpc_connection *conn = NULL;
212 struct rxrpc_abort_buffer pkt;
213 struct msghdr msg;
214 struct kvec iov[1];
215 rxrpc_serial_t serial;
216 int ret;
217
218 spin_lock_bh(&call->lock);
219 if (call->conn)
220 conn = rxrpc_get_connection_maybe(call->conn);
221 spin_unlock_bh(&call->lock);
222 if (!conn)
223 return -ECONNRESET;
224
225 msg.msg_name = &call->peer->srx.transport;
226 msg.msg_namelen = call->peer->srx.transport_len;
227 msg.msg_control = NULL;
228 msg.msg_controllen = 0;
229 msg.msg_flags = 0;
230
231 pkt.whdr.epoch = htonl(conn->proto.epoch);
232 pkt.whdr.cid = htonl(call->cid);
233 pkt.whdr.callNumber = htonl(call->call_id);
234 pkt.whdr.seq = 0;
235 pkt.whdr.type = RXRPC_PACKET_TYPE_ABORT;
236 pkt.whdr.flags = conn->out_clientflag;
237 pkt.whdr.userStatus = 0;
238 pkt.whdr.securityIndex = call->security_ix;
239 pkt.whdr._rsvd = 0;
240 pkt.whdr.serviceId = htons(call->service_id);
241 pkt.abort_code = htonl(call->abort_code);
242
243 iov[0].iov_base = &pkt;
244 iov[0].iov_len = sizeof(pkt);
245
246 serial = atomic_inc_return(&conn->serial);
247 pkt.whdr.serial = htonl(serial);
248
249 ret = kernel_sendmsg(conn->params.local->socket,
250 &msg, iov, 1, sizeof(pkt));
251
252 rxrpc_put_connection(conn);
253 return ret;
254}
255
256/*
239 * send a packet through the transport endpoint 257 * send a packet through the transport endpoint
240 */ 258 */
241int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb, 259int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
index f05ea0a88076..11723bc1c783 100644
--- a/net/rxrpc/recvmsg.c
+++ b/net/rxrpc/recvmsg.c
@@ -143,7 +143,7 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial)
143 if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) { 143 if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) {
144 rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, serial, true, false, 144 rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, serial, true, false,
145 rxrpc_propose_ack_terminal_ack); 145 rxrpc_propose_ack_terminal_ack);
146 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK); 146 rxrpc_send_ack_packet(call);
147 } 147 }
148 148
149 write_lock_bh(&call->state_lock); 149 write_lock_bh(&call->state_lock);
@@ -212,7 +212,7 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call)
212 true, false, 212 true, false,
213 rxrpc_propose_ack_rotate_rx); 213 rxrpc_propose_ack_rotate_rx);
214 if (call->ackr_reason) 214 if (call->ackr_reason)
215 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK); 215 rxrpc_send_ack_packet(call);
216 } 216 }
217} 217}
218 218
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index 627abed5f999..4374e7b9c7bf 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -381,7 +381,7 @@ static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,
381 return 0; 381 return 0;
382 382
383protocol_error: 383protocol_error:
384 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT); 384 rxrpc_send_abort_packet(call);
385 _leave(" = -EPROTO"); 385 _leave(" = -EPROTO");
386 return -EPROTO; 386 return -EPROTO;
387 387
@@ -471,7 +471,7 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb,
471 return 0; 471 return 0;
472 472
473protocol_error: 473protocol_error:
474 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT); 474 rxrpc_send_abort_packet(call);
475 _leave(" = -EPROTO"); 475 _leave(" = -EPROTO");
476 return -EPROTO; 476 return -EPROTO;
477 477
@@ -523,7 +523,7 @@ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,
523 523
524 if (cksum != expected_cksum) { 524 if (cksum != expected_cksum) {
525 rxrpc_abort_call("VCK", call, seq, RXKADSEALEDINCON, EPROTO); 525 rxrpc_abort_call("VCK", call, seq, RXKADSEALEDINCON, EPROTO);
526 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT); 526 rxrpc_send_abort_packet(call);
527 _leave(" = -EPROTO [csum failed]"); 527 _leave(" = -EPROTO [csum failed]");
528 return -EPROTO; 528 return -EPROTO;
529 } 529 }
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index 3322543d460a..901b28ceeff4 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -197,7 +197,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
197 do { 197 do {
198 /* Check to see if there's a ping ACK to reply to. */ 198 /* Check to see if there's a ping ACK to reply to. */
199 if (call->ackr_reason == RXRPC_ACK_PING_RESPONSE) 199 if (call->ackr_reason == RXRPC_ACK_PING_RESPONSE)
200 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK); 200 rxrpc_send_ack_packet(call);
201 201
202 if (!skb) { 202 if (!skb) {
203 size_t size, chunk, max, space; 203 size_t size, chunk, max, space;
@@ -514,8 +514,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
514 } else if (cmd == RXRPC_CMD_SEND_ABORT) { 514 } else if (cmd == RXRPC_CMD_SEND_ABORT) {
515 ret = 0; 515 ret = 0;
516 if (rxrpc_abort_call("CMD", call, 0, abort_code, ECONNABORTED)) 516 if (rxrpc_abort_call("CMD", call, 0, abort_code, ECONNABORTED))
517 ret = rxrpc_send_call_packet(call, 517 ret = rxrpc_send_abort_packet(call);
518 RXRPC_PACKET_TYPE_ABORT);
519 } else if (cmd != RXRPC_CMD_SEND_DATA) { 518 } else if (cmd != RXRPC_CMD_SEND_DATA) {
520 ret = -EINVAL; 519 ret = -EINVAL;
521 } else if (rxrpc_is_client_call(call) && 520 } else if (rxrpc_is_client_call(call) &&
@@ -597,7 +596,7 @@ void rxrpc_kernel_abort_call(struct socket *sock, struct rxrpc_call *call,
597 lock_sock(sock->sk); 596 lock_sock(sock->sk);
598 597
599 if (rxrpc_abort_call(why, call, 0, abort_code, error)) 598 if (rxrpc_abort_call(why, call, 0, abort_code, error))
600 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT); 599 rxrpc_send_abort_packet(call);
601 600
602 release_sock(sock->sk); 601 release_sock(sock->sk);
603 _leave(""); 602 _leave("");