* Special handling of recvmsg with multishot */
| 1225 | * Special handling of recvmsg with multishot |
| 1226 | */ |
| 1227 | static int recv_mshot_msg(struct conn *c, struct conn_dir *cd, int *bid, |
| 1228 | int in_bytes) |
| 1229 | { |
| 1230 | struct conn_buf_ring *cbr = &c->out_br; |
| 1231 | struct conn_buf_ring *in_cbr = &c->in_br; |
| 1232 | struct io_uring_buf *buf; |
| 1233 | int nr_packets = 0; |
| 1234 | |
| 1235 | while (in_bytes) { |
| 1236 | struct io_uring_recvmsg_out *pdu; |
| 1237 | int this_bytes; |
| 1238 | void *data; |
| 1239 | |
| 1240 | buf = &in_cbr->br->bufs[*bid]; |
| 1241 | |
| 1242 | /* |
| 1243 | * multishot recvmsg puts a header in front of the data - we |
| 1244 | * have to take that into account for the send setup, and |
| 1245 | * adjust the actual data read to not take this metadata into |
| 1246 | * account. For this use case, namelen and controllen will not |
| 1247 | * be set. If they were, they would need to be factored in too. |
| 1248 | */ |
| 1249 | buf->len -= sizeof(struct io_uring_recvmsg_out); |
| 1250 | in_bytes -= sizeof(struct io_uring_recvmsg_out); |
| 1251 | |
| 1252 | pdu = (void *) (unsigned long) buf->addr; |
| 1253 | vlog("pdu namelen %d, controllen %d, payload %d flags %x\n", |
| 1254 | pdu->namelen, pdu->controllen, pdu->payloadlen, |
| 1255 | pdu->flags); |
| 1256 | data = (void *) (pdu + 1); |
| 1257 | |
| 1258 | this_bytes = pdu->payloadlen; |
| 1259 | if (this_bytes > in_bytes) |
| 1260 | this_bytes = in_bytes; |
| 1261 | |
| 1262 | in_bytes -= this_bytes; |
| 1263 | |
| 1264 | if (send_ring) |
| 1265 | io_uring_buf_ring_add(cbr->br, data, this_bytes, *bid, |
| 1266 | br_mask, nr_packets); |
| 1267 | else |
| 1268 | send_append(c, cd, data, *bid, this_bytes); |
| 1269 | |
| 1270 | *bid = (*bid + 1) & (nr_bufs - 1); |
| 1271 | nr_packets++; |
| 1272 | } |
| 1273 | |
| 1274 | if (send_ring) |
| 1275 | io_uring_buf_ring_advance(cbr->br, nr_packets); |
| 1276 | |
| 1277 | return nr_packets; |
| 1278 | } |
| 1279 | |
| 1280 | static int __handle_recv(struct io_uring *ring, struct conn *c, |
| 1281 | struct conn_dir *cd, struct io_uring_cqe *cqe) |
no test coverage detected