12 #include <linux/net.h>
16 #include <linux/export.h>
23 static int rxrpc_send_data(
struct kiocb *
iocb,
32 unsigned long *user_call_ID,
59 if (len !=
sizeof(
u32))
63 if (len !=
sizeof(
unsigned long))
65 *user_call_ID = *(
unsigned long *)
68 _debug(
"User Call ID %lx", *user_call_ID);
75 if (len !=
sizeof(*abort_code))
77 *abort_code = *(
unsigned int *)
CMSG_DATA(cmsg);
78 _debug(
"Abort %x", *abort_code);
105 static void rxrpc_send_abort(
struct rxrpc_call *call,
u32 abort_code)
109 if (call->
state <= RXRPC_CALL_COMPLETE) {
110 call->
state = RXRPC_CALL_LOCALLY_ABORTED;
136 unsigned long user_call_ID = 0;
146 ret = rxrpc_sendmsg_cmsg(rx, msg, &user_call_ID, &cmd, &abort_code,
160 if (key && !rx->
key->payload.data)
165 return PTR_ERR(bundle);
173 _leave(
" = %ld", PTR_ERR(call));
174 return PTR_ERR(call);
177 _debug(
"CALL %d USR %lx ST %d on CONN %p",
180 if (call->
state >= RXRPC_CALL_COMPLETE) {
184 rxrpc_send_abort(call, abort_code);
187 }
else if (call->
state != RXRPC_CALL_CLIENT_SEND_REQUEST) {
191 ret = rxrpc_send_data(iocb, rx, call, msg, len);
220 lock_sock(&call->
socket->sk);
222 _debug(
"CALL %d USR %lx ST %d on CONN %p",
225 if (call->
state >= RXRPC_CALL_COMPLETE) {
227 }
else if (call->
state != RXRPC_CALL_CLIENT_SEND_REQUEST &&
228 call->
state != RXRPC_CALL_SERVER_ACK_REQUEST &&
229 call->
state != RXRPC_CALL_SERVER_SEND_REPLY) {
234 ret = rxrpc_send_data(
NULL, call->
socket, call, msg, len);
256 lock_sock(&call->
socket->sk);
258 _debug(
"CALL %d USR %lx ST %d on CONN %p",
261 if (call->
state < RXRPC_CALL_COMPLETE)
262 rxrpc_send_abort(call, abort_code);
275 struct msghdr *msg,
size_t len)
279 unsigned long user_call_ID = 0;
285 ret = rxrpc_sendmsg_cmsg(rx, msg, &user_call_ID, &cmd, &abort_code,
293 return PTR_ERR(call);
316 ret = rxrpc_send_data(iocb, rx, call, msg, len);
320 rxrpc_send_abort(call, abort_code);
367 goto send_fragmentable;
369 _leave(
" = %d [%u]", ret, trans->
peer->maxdata);
380 (
char *) &opt,
sizeof(opt));
391 _leave(
" = %d [frag %u]", ret, trans->
peer->maxdata);
399 static int rxrpc_wait_for_tx_window(
struct rxrpc_sock *rx,
419 ret = sock_intr_errno(*timeo);
437 static inline void rxrpc_instant_resend(
struct rxrpc_call *call)
442 if (call->
state < RXRPC_CALL_COMPLETE &&
466 if (last || call->
state == RXRPC_CALL_SERVER_ACK_REQUEST) {
467 _debug(
"________awaiting reply/ACK__________");
469 switch (call->
state) {
470 case RXRPC_CALL_CLIENT_SEND_REQUEST:
471 call->
state = RXRPC_CALL_CLIENT_AWAIT_REPLY;
473 case RXRPC_CALL_SERVER_ACK_REQUEST:
474 call->
state = RXRPC_CALL_SERVER_SEND_REPLY;
477 case RXRPC_CALL_SERVER_SEND_REPLY:
478 call->
state = RXRPC_CALL_SERVER_AWAIT_ACK;
486 _proto(
"Tx DATA %%%u { #%u }",
504 _net(
"sent skb %p", skb);
506 _debug(
"failed to delete ACK timer");
510 _debug(
"need instant resend %d", ret);
512 rxrpc_instant_resend(call);
523 static int rxrpc_send_data(
struct kiocb *
iocb,
526 struct msghdr *msg,
size_t len)
564 _debug(
"SEGMENT %d @%p", segment, from);
576 ret = rxrpc_wait_for_tx_window(rx, call,
582 max = call->
conn->trans->peer->maxdata;
583 max -= call->
conn->security_size;
584 max &= ~(call->
conn->size_align - 1
UL);
587 if (chunk > len && !more)
590 space = chunk + call->
conn->size_align;
591 space &= ~(call->
conn->size_align - 1
UL);
593 size = space + call->
conn->header_size;
595 _debug(
"SIZE: %zu/%zu/%zu", chunk, space, size);
605 _debug(
"ALLOC SEND %p", skb);
610 skb_reserve(skb, call->
conn->header_size);
611 skb->
len += call->
conn->header_size;
615 if (sp->
remain > skb_tailroom(skb))
616 sp->
remain = skb_tailroom(skb);
618 _net(
"skb: hr %d, tr %d, hl %d, rm %d",
631 copy = skb_tailroom(skb);
639 ret = skb_add_data(skb, from, copy);
650 while (segment == 0 && ioc > 0) {
663 if (call->
state > RXRPC_CALL_COMPLETE)
667 if (sp->
remain <= 0 || (segment == 0 && !more)) {
689 sp->
hdr.userStatus = 0;
695 if (len == 0 && !more)
702 call, skb, skb->
mark,
709 rxrpc_queue_packet(call, skb, segment == 0 && !more);
713 }
while (segment > 0);
724 if (call->
state == RXRPC_CALL_NETWORK_ERROR)
725 ret = call->
conn->trans->peer->net_error;