diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2019-11-04 05:32:04 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2019-11-04 05:32:04 -0500 |
commit | ca8888d7ae6fa18454c9e4f192c56bc6c8ca9b33 (patch) | |
tree | c2b86b162f8fc2adf8a98f7e074500bee155d603 /net/rxrpc/recvmsg.c | |
parent | db616173d787395787ecc93eef075fa975227b10 (diff) | |
parent | a99d8080aaf358d5d23581244e5da23b35e340b9 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
to pick up the KVM fix which is required for the NX series.
Diffstat (limited to 'net/rxrpc/recvmsg.c')
-rw-r--r-- | net/rxrpc/recvmsg.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index a4090797c9b2..8578c39ec839 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c | |||
@@ -267,11 +267,13 @@ static int rxrpc_verify_packet(struct rxrpc_call *call, struct sk_buff *skb, | |||
267 | */ | 267 | */ |
268 | static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, | 268 | static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, |
269 | u8 *_annotation, | 269 | u8 *_annotation, |
270 | unsigned int *_offset, unsigned int *_len) | 270 | unsigned int *_offset, unsigned int *_len, |
271 | bool *_last) | ||
271 | { | 272 | { |
272 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | 273 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
273 | unsigned int offset = sizeof(struct rxrpc_wire_header); | 274 | unsigned int offset = sizeof(struct rxrpc_wire_header); |
274 | unsigned int len; | 275 | unsigned int len; |
276 | bool last = false; | ||
275 | int ret; | 277 | int ret; |
276 | u8 annotation = *_annotation; | 278 | u8 annotation = *_annotation; |
277 | u8 subpacket = annotation & RXRPC_RX_ANNO_SUBPACKET; | 279 | u8 subpacket = annotation & RXRPC_RX_ANNO_SUBPACKET; |
@@ -281,6 +283,8 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, | |||
281 | len = skb->len - offset; | 283 | len = skb->len - offset; |
282 | if (subpacket < sp->nr_subpackets - 1) | 284 | if (subpacket < sp->nr_subpackets - 1) |
283 | len = RXRPC_JUMBO_DATALEN; | 285 | len = RXRPC_JUMBO_DATALEN; |
286 | else if (sp->rx_flags & RXRPC_SKB_INCL_LAST) | ||
287 | last = true; | ||
284 | 288 | ||
285 | if (!(annotation & RXRPC_RX_ANNO_VERIFIED)) { | 289 | if (!(annotation & RXRPC_RX_ANNO_VERIFIED)) { |
286 | ret = rxrpc_verify_packet(call, skb, annotation, offset, len); | 290 | ret = rxrpc_verify_packet(call, skb, annotation, offset, len); |
@@ -291,6 +295,7 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, | |||
291 | 295 | ||
292 | *_offset = offset; | 296 | *_offset = offset; |
293 | *_len = len; | 297 | *_len = len; |
298 | *_last = last; | ||
294 | call->security->locate_data(call, skb, _offset, _len); | 299 | call->security->locate_data(call, skb, _offset, _len); |
295 | return 0; | 300 | return 0; |
296 | } | 301 | } |
@@ -309,7 +314,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
309 | rxrpc_serial_t serial; | 314 | rxrpc_serial_t serial; |
310 | rxrpc_seq_t hard_ack, top, seq; | 315 | rxrpc_seq_t hard_ack, top, seq; |
311 | size_t remain; | 316 | size_t remain; |
312 | bool last; | 317 | bool rx_pkt_last; |
313 | unsigned int rx_pkt_offset, rx_pkt_len; | 318 | unsigned int rx_pkt_offset, rx_pkt_len; |
314 | int ix, copy, ret = -EAGAIN, ret2; | 319 | int ix, copy, ret = -EAGAIN, ret2; |
315 | 320 | ||
@@ -319,6 +324,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
319 | 324 | ||
320 | rx_pkt_offset = call->rx_pkt_offset; | 325 | rx_pkt_offset = call->rx_pkt_offset; |
321 | rx_pkt_len = call->rx_pkt_len; | 326 | rx_pkt_len = call->rx_pkt_len; |
327 | rx_pkt_last = call->rx_pkt_last; | ||
322 | 328 | ||
323 | if (call->state >= RXRPC_CALL_SERVER_ACK_REQUEST) { | 329 | if (call->state >= RXRPC_CALL_SERVER_ACK_REQUEST) { |
324 | seq = call->rx_hard_ack; | 330 | seq = call->rx_hard_ack; |
@@ -329,6 +335,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
329 | /* Barriers against rxrpc_input_data(). */ | 335 | /* Barriers against rxrpc_input_data(). */ |
330 | hard_ack = call->rx_hard_ack; | 336 | hard_ack = call->rx_hard_ack; |
331 | seq = hard_ack + 1; | 337 | seq = hard_ack + 1; |
338 | |||
332 | while (top = smp_load_acquire(&call->rx_top), | 339 | while (top = smp_load_acquire(&call->rx_top), |
333 | before_eq(seq, top) | 340 | before_eq(seq, top) |
334 | ) { | 341 | ) { |
@@ -356,7 +363,8 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
356 | if (rx_pkt_offset == 0) { | 363 | if (rx_pkt_offset == 0) { |
357 | ret2 = rxrpc_locate_data(call, skb, | 364 | ret2 = rxrpc_locate_data(call, skb, |
358 | &call->rxtx_annotations[ix], | 365 | &call->rxtx_annotations[ix], |
359 | &rx_pkt_offset, &rx_pkt_len); | 366 | &rx_pkt_offset, &rx_pkt_len, |
367 | &rx_pkt_last); | ||
360 | trace_rxrpc_recvmsg(call, rxrpc_recvmsg_next, seq, | 368 | trace_rxrpc_recvmsg(call, rxrpc_recvmsg_next, seq, |
361 | rx_pkt_offset, rx_pkt_len, ret2); | 369 | rx_pkt_offset, rx_pkt_len, ret2); |
362 | if (ret2 < 0) { | 370 | if (ret2 < 0) { |
@@ -396,13 +404,12 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
396 | } | 404 | } |
397 | 405 | ||
398 | /* The whole packet has been transferred. */ | 406 | /* The whole packet has been transferred. */ |
399 | last = sp->hdr.flags & RXRPC_LAST_PACKET; | ||
400 | if (!(flags & MSG_PEEK)) | 407 | if (!(flags & MSG_PEEK)) |
401 | rxrpc_rotate_rx_window(call); | 408 | rxrpc_rotate_rx_window(call); |
402 | rx_pkt_offset = 0; | 409 | rx_pkt_offset = 0; |
403 | rx_pkt_len = 0; | 410 | rx_pkt_len = 0; |
404 | 411 | ||
405 | if (last) { | 412 | if (rx_pkt_last) { |
406 | ASSERTCMP(seq, ==, READ_ONCE(call->rx_top)); | 413 | ASSERTCMP(seq, ==, READ_ONCE(call->rx_top)); |
407 | ret = 1; | 414 | ret = 1; |
408 | goto out; | 415 | goto out; |
@@ -415,6 +422,7 @@ out: | |||
415 | if (!(flags & MSG_PEEK)) { | 422 | if (!(flags & MSG_PEEK)) { |
416 | call->rx_pkt_offset = rx_pkt_offset; | 423 | call->rx_pkt_offset = rx_pkt_offset; |
417 | call->rx_pkt_len = rx_pkt_len; | 424 | call->rx_pkt_len = rx_pkt_len; |
425 | call->rx_pkt_last = rx_pkt_last; | ||
418 | } | 426 | } |
419 | done: | 427 | done: |
420 | trace_rxrpc_recvmsg(call, rxrpc_recvmsg_data_return, seq, | 428 | trace_rxrpc_recvmsg(call, rxrpc_recvmsg_data_return, seq, |