/*
* Fill out an ACK packet.
*/
-static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn,
- struct rxrpc_call *call,
- struct rxrpc_txbuf *txb,
- u16 *_rwind)
+static void rxrpc_fill_out_ack(struct rxrpc_connection *conn,
+ struct rxrpc_call *call,
+ struct rxrpc_txbuf *txb,
+ u16 *_rwind)
{
struct rxrpc_acktrailer trailer;
unsigned int qsize, sack, wrap, to;
*ackp++ = 0;
*ackp++ = 0;
memcpy(ackp, &trailer, sizeof(trailer));
- return txb->ack.nAcks + 3 + sizeof(trailer);
+ txb->kvec[0].iov_len = sizeof(txb->wire) +
+ sizeof(txb->ack) + txb->ack.nAcks + 3 + sizeof(trailer);
+ txb->len = txb->kvec[0].iov_len;
}
/*
{
struct rxrpc_connection *conn;
struct msghdr msg;
- struct kvec iov[1];
- size_t len, n;
int ret, rtt_slot = -1;
u16 rwind;
txb->flags |= RXRPC_REQUEST_ACK;
txb->wire.flags = txb->flags & RXRPC_TXBUF_WIRE_FLAGS;
- n = rxrpc_fill_out_ack(conn, call, txb, &rwind);
- if (n == 0)
- return 0;
-
- iov[0].iov_base = &txb->wire;
- iov[0].iov_len = sizeof(txb->wire) + sizeof(txb->ack) + n;
- len = iov[0].iov_len;
+ rxrpc_fill_out_ack(conn, call, txb, &rwind);
txb->serial = rxrpc_get_next_serial(conn);
txb->wire.serial = htonl(txb->serial);
/* Grab the highest received seq as late as possible */
txb->ack.previousPacket = htonl(call->rx_highest_seq);
- iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, len);
+ iov_iter_kvec(&msg.msg_iter, WRITE, txb->kvec, txb->nr_kvec, txb->len);
rxrpc_local_dont_fragment(conn->local, false);
- ret = do_udp_sendmsg(conn->local->socket, &msg, len);
+ ret = do_udp_sendmsg(conn->local->socket, &msg, txb->len);
call->peer->last_tx_at = ktime_get_seconds();
if (ret < 0) {
trace_rxrpc_tx_fail(call->debug_id, txb->serial, ret,
enum rxrpc_req_ack_trace why;
enum rxrpc_tx_point frag;
struct msghdr msg;
- struct kvec iov[1];
size_t len;
int ret, rtt_slot = -1;
txb->seq == 1)
txb->wire.userStatus = RXRPC_USERSTATUS_SERVICE_UPGRADE;
- iov[0].iov_base = &txb->wire;
- iov[0].iov_len = sizeof(txb->wire) + txb->len;
- len = iov[0].iov_len;
- iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, len);
+ len = txb->kvec[0].iov_len;
+ iov_iter_kvec(&msg.msg_iter, WRITE, txb->kvec, txb->nr_kvec, len);
msg.msg_name = &call->peer->srx.transport;
msg.msg_namelen = call->peer->srx.transport_len;
if (!txb)
goto maybe_error;
- txb->offset = offset;
+ txb->offset = offset + sizeof(struct rxrpc_wire_header);
txb->space -= offset;
txb->space = min_t(size_t, chunk, txb->space);
}
size_t copy = min_t(size_t, txb->space, msg_data_left(msg));
_debug("add %zu", copy);
- if (!copy_from_iter_full(txb->data + txb->offset, copy,
- &msg->msg_iter))
+ if (!copy_from_iter_full(txb->kvec[0].iov_base + txb->offset,
+ copy, &msg->msg_iter))
goto efault;
_debug("added");
txb->space -= copy;
if (ret < 0)
goto out;
+ txb->kvec[0].iov_len += txb->len;
+ txb->len = txb->kvec[0].iov_len;
rxrpc_queue_packet(rx, call, txb, notify_end_tx);
txb = NULL;
}